diff options
| author | <jgarzik@pretzel.yyz.us> | 2005-06-02 18:43:09 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-02 18:43:09 -0400 |
| commit | d7aaf48128ec7fcefcee92ea22833afc1a80e268 (patch) | |
| tree | 16ff78f6be6a5519944bb7bfc6034dfbd71ae97f | |
| parent | decc6d0b68f27bbb8a0357fccf41936a3c196b03 (diff) | |
| parent | 1e86d1c648508fd50e6c9960576b87906a7906ad (diff) | |
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
194 files changed, 4593 insertions, 1698 deletions
diff --git a/Documentation/cpu-freq/cpufreq-stats.txt b/Documentation/cpu-freq/cpufreq-stats.txt new file mode 100644 index 000000000000..e2d1e760b4ba --- /dev/null +++ b/Documentation/cpu-freq/cpufreq-stats.txt | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | |||
| 2 | CPU frequency and voltage scaling statictics in the Linux(TM) kernel | ||
| 3 | |||
| 4 | |||
| 5 | L i n u x c p u f r e q - s t a t s d r i v e r | ||
| 6 | |||
| 7 | - information for users - | ||
| 8 | |||
| 9 | |||
| 10 | Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> | ||
| 11 | |||
| 12 | Contents | ||
| 13 | 1. Introduction | ||
| 14 | 2. Statistics Provided (with example) | ||
| 15 | 3. Configuring cpufreq-stats | ||
| 16 | |||
| 17 | |||
| 18 | 1. Introduction | ||
| 19 | |||
| 20 | cpufreq-stats is a driver that provices CPU frequency statistics for each CPU. | ||
| 21 | This statistics is provided in /sysfs as a bunch of read_only interfaces. This | ||
| 22 | interface (when configured) will appear in a seperate directory under cpufreq | ||
| 23 | in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU. | ||
| 24 | Various statistics will form read_only files under this directory. | ||
| 25 | |||
| 26 | This driver is designed to be independent of any particular cpufreq_driver | ||
| 27 | that may be running on your CPU. So, it will work with any cpufreq_driver. | ||
| 28 | |||
| 29 | |||
| 30 | 2. Statistics Provided (with example) | ||
| 31 | |||
| 32 | cpufreq stats provides following statistics (explained in detail below). | ||
| 33 | - time_in_state | ||
| 34 | - total_trans | ||
| 35 | - trans_table | ||
| 36 | |||
| 37 | All the statistics will be from the time the stats driver has been inserted | ||
| 38 | to the time when a read of a particular statistic is done. Obviously, stats | ||
| 39 | driver will not have any information about the the frequcny transitions before | ||
| 40 | the stats driver insertion. | ||
| 41 | |||
| 42 | -------------------------------------------------------------------------------- | ||
| 43 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l | ||
| 44 | total 0 | ||
| 45 | drwxr-xr-x 2 root root 0 May 14 16:06 . | ||
| 46 | drwxr-xr-x 3 root root 0 May 14 15:58 .. | ||
| 47 | -r--r--r-- 1 root root 4096 May 14 16:06 time_in_state | ||
| 48 | -r--r--r-- 1 root root 4096 May 14 16:06 total_trans | ||
| 49 | -r--r--r-- 1 root root 4096 May 14 16:06 trans_table | ||
| 50 | -------------------------------------------------------------------------------- | ||
| 51 | |||
| 52 | - time_in_state | ||
| 53 | This gives the amount of time spent in each of the frequencies supported by | ||
| 54 | this CPU. The cat output will have "<frequency> <time>" pair in each line, which | ||
| 55 | will mean this CPU spent <time> usertime units of time at <frequency>. Output | ||
| 56 | will have one line for each of the supported freuencies. usertime units here | ||
| 57 | is 10mS (similar to other time exported in /proc). | ||
| 58 | |||
| 59 | -------------------------------------------------------------------------------- | ||
| 60 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat time_in_state | ||
| 61 | 3600000 2089 | ||
| 62 | 3400000 136 | ||
| 63 | 3200000 34 | ||
| 64 | 3000000 67 | ||
| 65 | 2800000 172488 | ||
| 66 | -------------------------------------------------------------------------------- | ||
| 67 | |||
| 68 | |||
| 69 | - total_trans | ||
| 70 | This gives the total number of frequency transitions on this CPU. The cat | ||
| 71 | output will have a single count which is the total number of frequency | ||
| 72 | transitions. | ||
| 73 | |||
| 74 | -------------------------------------------------------------------------------- | ||
| 75 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat total_trans | ||
| 76 | 20 | ||
| 77 | -------------------------------------------------------------------------------- | ||
| 78 | |||
| 79 | - trans_table | ||
| 80 | This will give a fine grained information about all the CPU frequency | ||
| 81 | transitions. The cat output here is a two dimensional matrix, where an entry | ||
| 82 | <i,j> (row i, column j) represents the count of number of transitions from | ||
| 83 | Freq_i to Freq_j. Freq_i is in descending order with increasing rows and | ||
| 84 | Freq_j is in descending order with increasing columns. The output here also | ||
| 85 | contains the actual freq values for each row and column for better readability. | ||
| 86 | |||
| 87 | -------------------------------------------------------------------------------- | ||
| 88 | <mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat trans_table | ||
| 89 | From : To | ||
| 90 | : 3600000 3400000 3200000 3000000 2800000 | ||
| 91 | 3600000: 0 5 0 0 0 | ||
| 92 | 3400000: 4 0 2 0 0 | ||
| 93 | 3200000: 0 1 0 2 0 | ||
| 94 | 3000000: 0 0 1 0 3 | ||
| 95 | 2800000: 0 0 0 2 0 | ||
| 96 | -------------------------------------------------------------------------------- | ||
| 97 | |||
| 98 | |||
| 99 | 3. Configuring cpufreq-stats | ||
| 100 | |||
| 101 | To configure cpufreq-stats in your kernel | ||
| 102 | Config Main Menu | ||
| 103 | Power management options (ACPI, APM) ---> | ||
| 104 | CPU Frequency scaling ---> | ||
| 105 | [*] CPU Frequency scaling | ||
| 106 | <*> CPU frequency translation statistics | ||
| 107 | [*] CPU frequency translation statistics details | ||
| 108 | |||
| 109 | |||
| 110 | "CPU Frequency scaling" (CONFIG_CPU_FREQ) should be enabled to configure | ||
| 111 | cpufreq-stats. | ||
| 112 | |||
| 113 | "CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT) provides the | ||
| 114 | basic statistics which includes time_in_state and total_trans. | ||
| 115 | |||
| 116 | "CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS) | ||
| 117 | provides fine grained cpufreq stats by trans_table. The reason for having a | ||
| 118 | seperate config option for trans_table is: | ||
| 119 | - trans_table goes against the traditional /sysfs rule of one value per | ||
| 120 | interface. It provides a whole bunch of value in a 2 dimensional matrix | ||
| 121 | form. | ||
| 122 | |||
| 123 | Once these two options are enabled and your CPU supports cpufrequency, you | ||
| 124 | will be able to see the CPU frequency statistics in /sysfs. | ||
| 125 | |||
| 126 | |||
| 127 | |||
| 128 | |||
diff --git a/MAINTAINERS b/MAINTAINERS index 5b8483334de1..65ad8251e4bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -239,6 +239,12 @@ L: linux-usb-devel@lists.sourceforge.net | |||
| 239 | W: http://www.linux-usb.org/SpeedTouch/ | 239 | W: http://www.linux-usb.org/SpeedTouch/ |
| 240 | S: Maintained | 240 | S: Maintained |
| 241 | 241 | ||
| 242 | ALI1563 I2C DRIVER | ||
| 243 | P: Rudolf Marek | ||
| 244 | M: r.marek@sh.cvut.cz | ||
| 245 | L: sensors@stimpy.netroedge.com | ||
| 246 | S: Maintained | ||
| 247 | |||
| 242 | ALPHA PORT | 248 | ALPHA PORT |
| 243 | P: Richard Henderson | 249 | P: Richard Henderson |
| 244 | M: rth@twiddle.net | 250 | M: rth@twiddle.net |
| @@ -1023,8 +1029,8 @@ W: http://www.ia64-linux.org/ | |||
| 1023 | S: Maintained | 1029 | S: Maintained |
| 1024 | 1030 | ||
| 1025 | SN-IA64 (Itanium) SUB-PLATFORM | 1031 | SN-IA64 (Itanium) SUB-PLATFORM |
| 1026 | P: Jesse Barnes | 1032 | P: Greg Edwards |
| 1027 | M: jbarnes@sgi.com | 1033 | M: edwardsg@sgi.com |
| 1028 | L: linux-altix@sgi.com | 1034 | L: linux-altix@sgi.com |
| 1029 | L: linux-ia64@vger.kernel.org | 1035 | L: linux-ia64@vger.kernel.org |
| 1030 | W: http://www.sgi.com/altix | 1036 | W: http://www.sgi.com/altix |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index 134aec1c6d19..b5f83e9f04db 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
| @@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void); | |||
| 54 | void default_idle(void) | 54 | void default_idle(void) |
| 55 | { | 55 | { |
| 56 | while(1) { | 56 | while(1) { |
| 57 | if (need_resched()) { | 57 | if (!need_resched()) { |
| 58 | local_irq_enable(); | 58 | local_irq_enable(); |
| 59 | __asm__("sleep"); | 59 | __asm__("sleep"); |
| 60 | local_irq_disable(); | 60 | local_irq_disable(); |
diff --git a/arch/i386/kernel/cpu/cpufreq/Kconfig b/arch/i386/kernel/cpu/cpufreq/Kconfig index f25ffd74235c..0f1eb507233b 100644 --- a/arch/i386/kernel/cpu/cpufreq/Kconfig +++ b/arch/i386/kernel/cpu/cpufreq/Kconfig | |||
| @@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ | |||
| 23 | If in doubt, say N. | 23 | If in doubt, say N. |
| 24 | 24 | ||
| 25 | config ELAN_CPUFREQ | 25 | config ELAN_CPUFREQ |
| 26 | tristate "AMD Elan" | 26 | tristate "AMD Elan SC400 and SC410" |
| 27 | select CPU_FREQ_TABLE | 27 | select CPU_FREQ_TABLE |
| 28 | depends on X86_ELAN | 28 | depends on X86_ELAN |
| 29 | ---help--- | 29 | ---help--- |
| @@ -38,6 +38,18 @@ config ELAN_CPUFREQ | |||
| 38 | 38 | ||
| 39 | If in doubt, say N. | 39 | If in doubt, say N. |
| 40 | 40 | ||
| 41 | config SC520_CPUFREQ | ||
| 42 | tristate "AMD Elan SC520" | ||
| 43 | select CPU_FREQ_TABLE | ||
| 44 | depends on X86_ELAN | ||
| 45 | ---help--- | ||
| 46 | This adds the CPUFreq driver for AMD Elan SC520 processor. | ||
| 47 | |||
| 48 | For details, take a look at <file:Documentation/cpu-freq/>. | ||
| 49 | |||
| 50 | If in doubt, say N. | ||
| 51 | |||
| 52 | |||
| 41 | config X86_POWERNOW_K6 | 53 | config X86_POWERNOW_K6 |
| 42 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" | 54 | tristate "AMD Mobile K6-2/K6-3 PowerNow!" |
| 43 | select CPU_FREQ_TABLE | 55 | select CPU_FREQ_TABLE |
diff --git a/arch/i386/kernel/cpu/cpufreq/Makefile b/arch/i386/kernel/cpu/cpufreq/Makefile index a922e97aeedd..2e894f1c8910 100644 --- a/arch/i386/kernel/cpu/cpufreq/Makefile +++ b/arch/i386/kernel/cpu/cpufreq/Makefile | |||
| @@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o | |||
| 3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o | 3 | obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o |
| 4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o | 4 | obj-$(CONFIG_X86_LONGHAUL) += longhaul.o |
| 5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o | 5 | obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o |
| 6 | obj-$(CONFIG_SC520_CPUFREQ) += sc520_freq.o | ||
| 6 | obj-$(CONFIG_X86_LONGRUN) += longrun.o | 7 | obj-$(CONFIG_X86_LONGRUN) += longrun.o |
| 7 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o | 8 | obj-$(CONFIG_X86_GX_SUSPMOD) += gx-suspmod.o |
| 8 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o | 9 | obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o |
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index ab0f9f5aac11..04e3563da4fe 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/cpufreq.h> | 29 | #include <linux/cpufreq.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
| 32 | #include <linux/pci.h> | ||
| 32 | 33 | ||
| 33 | #include <asm/msr.h> | 34 | #include <asm/msr.h> |
| 34 | #include <asm/timex.h> | 35 | #include <asm/timex.h> |
| @@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void) | |||
| 119 | static void do_powersaver(union msr_longhaul *longhaul, | 120 | static void do_powersaver(union msr_longhaul *longhaul, |
| 120 | unsigned int clock_ratio_index) | 121 | unsigned int clock_ratio_index) |
| 121 | { | 122 | { |
| 123 | struct pci_dev *dev; | ||
| 124 | unsigned long flags; | ||
| 125 | unsigned int tmp_mask; | ||
| 122 | int version; | 126 | int version; |
| 127 | int i; | ||
| 128 | u16 pci_cmd; | ||
| 129 | u16 cmd_state[64]; | ||
| 123 | 130 | ||
| 124 | switch (cpu_model) { | 131 | switch (cpu_model) { |
| 125 | case CPU_EZRA_T: | 132 | case CPU_EZRA_T: |
| @@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul, | |||
| 137 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; | 144 | longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4; |
| 138 | longhaul->bits.EnableSoftBusRatio = 1; | 145 | longhaul->bits.EnableSoftBusRatio = 1; |
| 139 | longhaul->bits.RevisionKey = 0; | 146 | longhaul->bits.RevisionKey = 0; |
| 140 | local_irq_disable(); | 147 | |
| 141 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 148 | preempt_disable(); |
| 149 | local_irq_save(flags); | ||
| 150 | |||
| 151 | /* | ||
| 152 | * get current pci bus master state for all devices | ||
| 153 | * and clear bus master bit | ||
| 154 | */ | ||
| 155 | dev = NULL; | ||
| 156 | i = 0; | ||
| 157 | do { | ||
| 158 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
| 159 | if (dev != NULL) { | ||
| 160 | pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); | ||
| 161 | cmd_state[i++] = pci_cmd; | ||
| 162 | pci_cmd &= ~PCI_COMMAND_MASTER; | ||
| 163 | pci_write_config_word(dev, PCI_COMMAND, pci_cmd); | ||
| 164 | } | ||
| 165 | } while (dev != NULL); | ||
| 166 | |||
| 167 | tmp_mask=inb(0x21); /* works on C3. save mask. */ | ||
| 168 | outb(0xFE,0x21); /* TMR0 only */ | ||
| 169 | outb(0xFF,0x80); /* delay */ | ||
| 170 | |||
| 142 | local_irq_enable(); | 171 | local_irq_enable(); |
| 172 | |||
| 173 | __hlt(); | ||
| 174 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | ||
| 143 | __hlt(); | 175 | __hlt(); |
| 144 | 176 | ||
| 177 | local_irq_disable(); | ||
| 178 | |||
| 179 | outb(tmp_mask,0x21); /* restore mask */ | ||
| 180 | |||
| 181 | /* restore pci bus master state for all devices */ | ||
| 182 | dev = NULL; | ||
| 183 | i = 0; | ||
| 184 | do { | ||
| 185 | dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev); | ||
| 186 | if (dev != NULL) { | ||
| 187 | pci_cmd = cmd_state[i++]; | ||
| 188 | pci_write_config_byte(dev, PCI_COMMAND, pci_cmd); | ||
| 189 | } | ||
| 190 | } while (dev != NULL); | ||
| 191 | local_irq_restore(flags); | ||
| 192 | preempt_enable(); | ||
| 193 | |||
| 194 | /* disable bus ratio bit */ | ||
| 145 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 195 | rdmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
| 146 | longhaul->bits.EnableSoftBusRatio = 0; | 196 | longhaul->bits.EnableSoftBusRatio = 0; |
| 147 | longhaul->bits.RevisionKey = version; | 197 | longhaul->bits.RevisionKey = version; |
| 148 | local_irq_disable(); | ||
| 149 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); | 198 | wrmsrl(MSR_VIA_LONGHAUL, longhaul->val); |
| 150 | local_irq_enable(); | ||
| 151 | } | 199 | } |
| 152 | 200 | ||
| 153 | /** | 201 | /** |
| @@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
| 578 | longhaul_setup_voltagescaling(); | 626 | longhaul_setup_voltagescaling(); |
| 579 | 627 | ||
| 580 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | 628 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; |
| 581 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 629 | policy->cpuinfo.transition_latency = 200000; /* nsec */ |
| 582 | policy->cur = calc_speed(longhaul_get_cpu_mult()); | 630 | policy->cur = calc_speed(longhaul_get_cpu_mult()); |
| 583 | 631 | ||
| 584 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); | 632 | ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 913f652623d9..5c530064eb74 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/dmi.h> | 23 | #include <linux/dmi.h> |
| 24 | 24 | ||
| 25 | #include <asm/msr.h> | 25 | #include <asm/msr.h> |
| 26 | #include <asm/timer.h> | ||
| 26 | #include <asm/timex.h> | 27 | #include <asm/timex.h> |
| 27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
| 28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
| @@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy) | |||
| 586 | 587 | ||
| 587 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); | 588 | rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); |
| 588 | 589 | ||
| 589 | /* A K7 with powernow technology is set to max frequency by BIOS */ | 590 | /* recalibrate cpu_khz */ |
| 590 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID]; | 591 | result = recalibrate_cpu_khz(); |
| 592 | if (result) | ||
| 593 | return result; | ||
| 594 | |||
| 595 | fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; | ||
| 591 | if (!fsb) { | 596 | if (!fsb) { |
| 592 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); | 597 | printk(KERN_WARNING PFX "can not determine bus frequency\n"); |
| 593 | return -EINVAL; | 598 | return -EINVAL; |
| 594 | } | 599 | } |
| 595 | dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000); | 600 | dprintk("FSB: %3dMHz\n", fsb/1000); |
| 596 | 601 | ||
| 597 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { | 602 | if (dmi_check_system(powernow_dmi_table) || acpi_force) { |
| 598 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); | 603 | printk (KERN_INFO PFX "PSB/PST known to be broken. Trying ACPI instead\n"); |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index a65ff7e32e5d..10cc096c0ade 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * GNU general public license version 2. See "COPYING" or | 4 | * GNU general public license version 2. See "COPYING" or |
| 5 | * http://www.gnu.org/licenses/gpl.html | 5 | * http://www.gnu.org/licenses/gpl.html |
| 6 | * | 6 | * |
| 7 | * Support : paul.devriendt@amd.com | 7 | * Support : mark.langsdorf@amd.com |
| 8 | * | 8 | * |
| 9 | * Based on the powernow-k7.c module written by Dave Jones. | 9 | * Based on the powernow-k7.c module written by Dave Jones. |
| 10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs | 10 | * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs |
| @@ -15,12 +15,13 @@ | |||
| 15 | * | 15 | * |
| 16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, | 16 | * Valuable input gratefully received from Dave Jones, Pavel Machek, |
| 17 | * Dominik Brodowski, and others. | 17 | * Dominik Brodowski, and others. |
| 18 | * Originally developed by Paul Devriendt. | ||
| 18 | * Processor information obtained from Chapter 9 (Power and Thermal Management) | 19 | * Processor information obtained from Chapter 9 (Power and Thermal Management) |
| 19 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD | 20 | * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD |
| 20 | * Opteron Processors" available for download from www.amd.com | 21 | * Opteron Processors" available for download from www.amd.com |
| 21 | * | 22 | * |
| 22 | * Tables for specific CPUs can be infrerred from | 23 | * Tables for specific CPUs can be infrerred from |
| 23 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf | 24 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf |
| 24 | */ | 25 | */ |
| 25 | 26 | ||
| 26 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| @@ -30,6 +31,7 @@ | |||
| 30 | #include <linux/cpufreq.h> | 31 | #include <linux/cpufreq.h> |
| 31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 32 | #include <linux/string.h> | 33 | #include <linux/string.h> |
| 34 | #include <linux/cpumask.h> | ||
| 33 | 35 | ||
| 34 | #include <asm/msr.h> | 36 | #include <asm/msr.h> |
| 35 | #include <asm/io.h> | 37 | #include <asm/io.h> |
| @@ -42,7 +44,7 @@ | |||
| 42 | 44 | ||
| 43 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
| 44 | #define BFX PFX "BIOS error: " | 46 | #define BFX PFX "BIOS error: " |
| 45 | #define VERSION "version 1.00.09e" | 47 | #define VERSION "version 1.40.2" |
| 46 | #include "powernow-k8.h" | 48 | #include "powernow-k8.h" |
| 47 | 49 | ||
| 48 | /* serialize freq changes */ | 50 | /* serialize freq changes */ |
| @@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem); | |||
| 50 | 52 | ||
| 51 | static struct powernow_k8_data *powernow_data[NR_CPUS]; | 53 | static struct powernow_k8_data *powernow_data[NR_CPUS]; |
| 52 | 54 | ||
| 55 | #ifndef CONFIG_SMP | ||
| 56 | static cpumask_t cpu_core_map[1]; | ||
| 57 | #endif | ||
| 58 | |||
| 53 | /* Return a frequency in MHz, given an input fid */ | 59 | /* Return a frequency in MHz, given an input fid */ |
| 54 | static u32 find_freq_from_fid(u32 fid) | 60 | static u32 find_freq_from_fid(u32 fid) |
| 55 | { | 61 | { |
| @@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
| 274 | { | 280 | { |
| 275 | u32 rvosteps = data->rvo; | 281 | u32 rvosteps = data->rvo; |
| 276 | u32 savefid = data->currfid; | 282 | u32 savefid = data->currfid; |
| 283 | u32 maxvid, lo; | ||
| 277 | 284 | ||
| 278 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", | 285 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", |
| 279 | smp_processor_id(), | 286 | smp_processor_id(), |
| 280 | data->currfid, data->currvid, reqvid, data->rvo); | 287 | data->currfid, data->currvid, reqvid, data->rvo); |
| 281 | 288 | ||
| 289 | rdmsr(MSR_FIDVID_STATUS, lo, maxvid); | ||
| 290 | maxvid = 0x1f & (maxvid >> 16); | ||
| 291 | dprintk("ph1 maxvid=0x%x\n", maxvid); | ||
| 292 | if (reqvid < maxvid) /* lower numbers are higher voltages */ | ||
| 293 | reqvid = maxvid; | ||
| 294 | |||
| 282 | while (data->currvid > reqvid) { | 295 | while (data->currvid > reqvid) { |
| 283 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", | 296 | dprintk("ph1: curr 0x%x, req vid 0x%x\n", |
| 284 | data->currvid, reqvid); | 297 | data->currvid, reqvid); |
| @@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
| 286 | return 1; | 299 | return 1; |
| 287 | } | 300 | } |
| 288 | 301 | ||
| 289 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { | 302 | while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) { |
| 290 | if (data->currvid == 0) { | 303 | if (data->currvid == maxvid) { |
| 291 | rvosteps = 0; | 304 | rvosteps = 0; |
| 292 | } else { | 305 | } else { |
| 293 | dprintk("ph1: changing vid for rvo, req 0x%x\n", | 306 | dprintk("ph1: changing vid for rvo, req 0x%x\n", |
| @@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
| 671 | * BIOS and Kernel Developer's Guide, which is available on | 684 | * BIOS and Kernel Developer's Guide, which is available on |
| 672 | * www.amd.com | 685 | * www.amd.com |
| 673 | */ | 686 | */ |
| 674 | printk(KERN_ERR PFX "BIOS error - no PSB\n"); | 687 | printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n"); |
| 675 | return -ENODEV; | 688 | return -ENODEV; |
| 676 | } | 689 | } |
| 677 | 690 | ||
| @@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
| 695 | struct cpufreq_frequency_table *powernow_table; | 708 | struct cpufreq_frequency_table *powernow_table; |
| 696 | 709 | ||
| 697 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 710 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
| 698 | dprintk("register performance failed\n"); | 711 | dprintk("register performance failed: bad ACPI data\n"); |
| 699 | return -EIO; | 712 | return -EIO; |
| 700 | } | 713 | } |
| 701 | 714 | ||
| @@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
| 746 | continue; | 759 | continue; |
| 747 | } | 760 | } |
| 748 | 761 | ||
| 749 | if (fid < HI_FID_TABLE_BOTTOM) { | 762 | /* verify only 1 entry from the lo frequency table */ |
| 750 | if (cntlofreq) { | 763 | if (fid < HI_FID_TABLE_BOTTOM) { |
| 751 | /* if both entries are the same, ignore this | 764 | if (cntlofreq) { |
| 752 | * one... | 765 | /* if both entries are the same, ignore this |
| 753 | */ | 766 | * one... |
| 754 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 767 | */ |
| 755 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 768 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || |
| 756 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 769 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { |
| 757 | goto err_out_mem; | 770 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); |
| 758 | } | 771 | goto err_out_mem; |
| 759 | 772 | } | |
| 760 | dprintk("double low frequency table entry, ignoring it.\n"); | 773 | |
| 761 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 774 | dprintk("double low frequency table entry, ignoring it.\n"); |
| 762 | continue; | 775 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; |
| 763 | } else | 776 | continue; |
| 764 | cntlofreq = i; | 777 | } else |
| 778 | cntlofreq = i; | ||
| 765 | } | 779 | } |
| 766 | 780 | ||
| 767 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | 781 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { |
| @@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
| 816 | { | 830 | { |
| 817 | u32 fid; | 831 | u32 fid; |
| 818 | u32 vid; | 832 | u32 vid; |
| 819 | int res; | 833 | int res, i; |
| 820 | struct cpufreq_freqs freqs; | 834 | struct cpufreq_freqs freqs; |
| 821 | 835 | ||
| 822 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); | 836 | dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); |
| @@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
| 841 | } | 855 | } |
| 842 | 856 | ||
| 843 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 857 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { |
| 844 | printk("ignoring illegal change in lo freq table-%x to 0x%x\n", | 858 | printk(KERN_ERR PFX |
| 859 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | ||
| 845 | data->currfid, fid); | 860 | data->currfid, fid); |
| 846 | return 1; | 861 | return 1; |
| 847 | } | 862 | } |
| @@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde | |||
| 850 | smp_processor_id(), fid, vid); | 865 | smp_processor_id(), fid, vid); |
| 851 | 866 | ||
| 852 | freqs.cpu = data->cpu; | 867 | freqs.cpu = data->cpu; |
| 853 | |||
| 854 | freqs.old = find_khz_freq_from_fid(data->currfid); | 868 | freqs.old = find_khz_freq_from_fid(data->currfid); |
| 855 | freqs.new = find_khz_freq_from_fid(fid); | 869 | freqs.new = find_khz_freq_from_fid(fid); |
| 856 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 870 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
| 871 | freqs.cpu = i; | ||
| 872 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
| 873 | } | ||
| 857 | 874 | ||
| 858 | down(&fidvid_sem); | ||
| 859 | res = transition_fid_vid(data, fid, vid); | 875 | res = transition_fid_vid(data, fid, vid); |
| 860 | up(&fidvid_sem); | ||
| 861 | 876 | ||
| 862 | freqs.new = find_khz_freq_from_fid(data->currfid); | 877 | freqs.new = find_khz_freq_from_fid(data->currfid); |
| 863 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 878 | for_each_cpu_mask(i, cpu_core_map[data->cpu]) { |
| 864 | 879 | freqs.cpu = i; | |
| 880 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
| 881 | } | ||
| 865 | return res; | 882 | return res; |
| 866 | } | 883 | } |
| 867 | 884 | ||
| @@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
| 874 | u32 checkvid = data->currvid; | 891 | u32 checkvid = data->currvid; |
| 875 | unsigned int newstate; | 892 | unsigned int newstate; |
| 876 | int ret = -EIO; | 893 | int ret = -EIO; |
| 894 | int i; | ||
| 877 | 895 | ||
| 878 | /* only run on specific CPU from here on */ | 896 | /* only run on specific CPU from here on */ |
| 879 | oldmask = current->cpus_allowed; | 897 | oldmask = current->cpus_allowed; |
| @@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
| 902 | data->currfid, data->currvid); | 920 | data->currfid, data->currvid); |
| 903 | 921 | ||
| 904 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { | 922 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { |
| 905 | printk(KERN_ERR PFX | 923 | printk(KERN_INFO PFX |
| 906 | "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n", | 924 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", |
| 907 | checkfid, data->currfid, checkvid, data->currvid); | 925 | checkfid, data->currfid, checkvid, data->currvid); |
| 908 | } | 926 | } |
| 909 | 927 | ||
| 910 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 928 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) |
| 911 | goto err_out; | 929 | goto err_out; |
| 912 | 930 | ||
| 931 | down(&fidvid_sem); | ||
| 932 | |||
| 933 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
| 934 | /* make sure the sibling is initialized */ | ||
| 935 | if (!powernow_data[i]) { | ||
| 936 | ret = 0; | ||
| 937 | up(&fidvid_sem); | ||
| 938 | goto err_out; | ||
| 939 | } | ||
| 940 | } | ||
| 941 | |||
| 913 | powernow_k8_acpi_pst_values(data, newstate); | 942 | powernow_k8_acpi_pst_values(data, newstate); |
| 914 | 943 | ||
| 915 | if (transition_frequency(data, newstate)) { | 944 | if (transition_frequency(data, newstate)) { |
| 916 | printk(KERN_ERR PFX "transition frequency failed\n"); | 945 | printk(KERN_ERR PFX "transition frequency failed\n"); |
| 917 | ret = 1; | 946 | ret = 1; |
| 947 | up(&fidvid_sem); | ||
| 918 | goto err_out; | 948 | goto err_out; |
| 919 | } | 949 | } |
| 920 | 950 | ||
| 951 | /* Update all the fid/vids of our siblings */ | ||
| 952 | for_each_cpu_mask(i, cpu_core_map[pol->cpu]) { | ||
| 953 | powernow_data[i]->currvid = data->currvid; | ||
| 954 | powernow_data[i]->currfid = data->currfid; | ||
| 955 | } | ||
| 956 | up(&fidvid_sem); | ||
| 957 | |||
| 921 | pol->cur = find_khz_freq_from_fid(data->currfid); | 958 | pol->cur = find_khz_freq_from_fid(data->currfid); |
| 922 | ret = 0; | 959 | ret = 0; |
| 923 | 960 | ||
| @@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 962 | */ | 999 | */ |
| 963 | 1000 | ||
| 964 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { | 1001 | if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { |
| 965 | printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n"); | 1002 | printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); |
| 966 | kfree(data); | 1003 | kfree(data); |
| 967 | return -ENODEV; | 1004 | return -ENODEV; |
| 968 | } | 1005 | } |
| @@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1003 | schedule(); | 1040 | schedule(); |
| 1004 | 1041 | ||
| 1005 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1042 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
| 1043 | pol->cpus = cpu_core_map[pol->cpu]; | ||
| 1006 | 1044 | ||
| 1007 | /* Take a crude guess here. | 1045 | /* Take a crude guess here. |
| 1008 | * That guess was in microseconds, so multiply with 1000 */ | 1046 | * That guess was in microseconds, so multiply with 1000 */ |
| @@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
| 1069 | return 0; | 1107 | return 0; |
| 1070 | } | 1108 | } |
| 1071 | preempt_disable(); | 1109 | preempt_disable(); |
| 1072 | 1110 | ||
| 1073 | if (query_current_values_with_pending_wait(data)) | 1111 | if (query_current_values_with_pending_wait(data)) |
| 1074 | goto out; | 1112 | goto out; |
| 1075 | 1113 | ||
| @@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void) | |||
| 1127 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1165 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
| 1128 | } | 1166 | } |
| 1129 | 1167 | ||
| 1130 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>"); | 1168 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com."); |
| 1131 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1169 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
| 1132 | MODULE_LICENSE("GPL"); | 1170 | MODULE_LICENSE("GPL"); |
| 1133 | 1171 | ||
| 1134 | late_initcall(powernowk8_init); | 1172 | late_initcall(powernowk8_init); |
| 1135 | module_exit(powernowk8_exit); | 1173 | module_exit(powernowk8_exit); |
| 1174 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 63ebc8470f52..9ed5bf221cb7 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h | |||
| @@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
| 174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); | 174 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); |
| 175 | 175 | ||
| 176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); | 176 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); |
| 177 | |||
| 178 | #ifndef for_each_cpu_mask | ||
| 179 | #define for_each_cpu_mask(i,mask) for (i=0;i<1;i++) | ||
| 180 | #endif | ||
| 181 | |||
| 182 | #ifdef CONFIG_SMP | ||
| 183 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
| 184 | { | ||
| 185 | } | ||
| 186 | #else | ||
| 187 | static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) | ||
| 188 | { | ||
| 189 | cpu_set(0, cpu_sharedcore_mask[0]); | ||
| 190 | } | ||
| 191 | #endif | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/sc520_freq.c b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c new file mode 100644 index 000000000000..ef457d50f4ac --- /dev/null +++ b/arch/i386/kernel/cpu/cpufreq/sc520_freq.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | * sc520_freq.c: cpufreq driver for the AMD Elan sc520 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Sean Young <sean@mess.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * Based on elanfreq.c | ||
| 12 | * | ||
| 13 | * 2005-03-30: - initial revision | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | |||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/cpufreq.h> | ||
| 22 | |||
| 23 | #include <asm/msr.h> | ||
| 24 | #include <asm/timex.h> | ||
| 25 | #include <asm/io.h> | ||
| 26 | |||
| 27 | #define MMCR_BASE 0xfffef000 /* The default base address */ | ||
| 28 | #define OFFS_CPUCTL 0x2 /* CPU Control Register */ | ||
| 29 | |||
| 30 | static __u8 __iomem *cpuctl; | ||
| 31 | |||
| 32 | #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg) | ||
| 33 | |||
| 34 | static struct cpufreq_frequency_table sc520_freq_table[] = { | ||
| 35 | {0x01, 100000}, | ||
| 36 | {0x02, 133000}, | ||
| 37 | {0, CPUFREQ_TABLE_END}, | ||
| 38 | }; | ||
| 39 | |||
| 40 | static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu) | ||
| 41 | { | ||
| 42 | u8 clockspeed_reg = *cpuctl; | ||
| 43 | |||
| 44 | switch (clockspeed_reg & 0x03) { | ||
| 45 | default: | ||
| 46 | printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg); | ||
| 47 | case 0x01: | ||
| 48 | return 100000; | ||
| 49 | case 0x02: | ||
| 50 | return 133000; | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 54 | static void sc520_freq_set_cpu_state (unsigned int state) | ||
| 55 | { | ||
| 56 | |||
| 57 | struct cpufreq_freqs freqs; | ||
| 58 | u8 clockspeed_reg; | ||
| 59 | |||
| 60 | freqs.old = sc520_freq_get_cpu_frequency(0); | ||
| 61 | freqs.new = sc520_freq_table[state].frequency; | ||
| 62 | freqs.cpu = 0; /* AMD Elan is UP */ | ||
| 63 | |||
| 64 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
| 65 | |||
| 66 | dprintk("attempting to set frequency to %i kHz\n", | ||
| 67 | sc520_freq_table[state].frequency); | ||
| 68 | |||
| 69 | local_irq_disable(); | ||
| 70 | |||
| 71 | clockspeed_reg = *cpuctl & ~0x03; | ||
| 72 | *cpuctl = clockspeed_reg | sc520_freq_table[state].index; | ||
| 73 | |||
| 74 | local_irq_enable(); | ||
| 75 | |||
| 76 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int sc520_freq_verify (struct cpufreq_policy *policy) | ||
| 80 | { | ||
| 81 | return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]); | ||
| 82 | } | ||
| 83 | |||
| 84 | static int sc520_freq_target (struct cpufreq_policy *policy, | ||
| 85 | unsigned int target_freq, | ||
| 86 | unsigned int relation) | ||
| 87 | { | ||
| 88 | unsigned int newstate = 0; | ||
| 89 | |||
| 90 | if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate)) | ||
| 91 | return -EINVAL; | ||
| 92 | |||
| 93 | sc520_freq_set_cpu_state(newstate); | ||
| 94 | |||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | |||
| 99 | /* | ||
| 100 | * Module init and exit code | ||
| 101 | */ | ||
| 102 | |||
| 103 | static int sc520_freq_cpu_init(struct cpufreq_policy *policy) | ||
| 104 | { | ||
| 105 | struct cpuinfo_x86 *c = cpu_data; | ||
| 106 | int result; | ||
| 107 | |||
| 108 | /* capability check */ | ||
| 109 | if (c->x86_vendor != X86_VENDOR_AMD || | ||
| 110 | c->x86 != 4 || c->x86_model != 9) | ||
| 111 | return -ENODEV; | ||
| 112 | |||
| 113 | /* cpuinfo and default policy values */ | ||
| 114 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
| 115 | policy->cpuinfo.transition_latency = 1000000; /* 1ms */ | ||
| 116 | policy->cur = sc520_freq_get_cpu_frequency(0); | ||
| 117 | |||
| 118 | result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table); | ||
| 119 | if (result) | ||
| 120 | return (result); | ||
| 121 | |||
| 122 | cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu); | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | |||
| 128 | static int sc520_freq_cpu_exit(struct cpufreq_policy *policy) | ||
| 129 | { | ||
| 130 | cpufreq_frequency_table_put_attr(policy->cpu); | ||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | |||
| 135 | static struct freq_attr* sc520_freq_attr[] = { | ||
| 136 | &cpufreq_freq_attr_scaling_available_freqs, | ||
| 137 | NULL, | ||
| 138 | }; | ||
| 139 | |||
| 140 | |||
| 141 | static struct cpufreq_driver sc520_freq_driver = { | ||
| 142 | .get = sc520_freq_get_cpu_frequency, | ||
| 143 | .verify = sc520_freq_verify, | ||
| 144 | .target = sc520_freq_target, | ||
| 145 | .init = sc520_freq_cpu_init, | ||
| 146 | .exit = sc520_freq_cpu_exit, | ||
| 147 | .name = "sc520_freq", | ||
| 148 | .owner = THIS_MODULE, | ||
| 149 | .attr = sc520_freq_attr, | ||
| 150 | }; | ||
| 151 | |||
| 152 | |||
| 153 | static int __init sc520_freq_init(void) | ||
| 154 | { | ||
| 155 | struct cpuinfo_x86 *c = cpu_data; | ||
| 156 | |||
| 157 | /* Test if we have the right hardware */ | ||
| 158 | if(c->x86_vendor != X86_VENDOR_AMD || | ||
| 159 | c->x86 != 4 || c->x86_model != 9) { | ||
| 160 | dprintk("no Elan SC520 processor found!\n"); | ||
| 161 | return -ENODEV; | ||
| 162 | } | ||
| 163 | cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); | ||
| 164 | if(!cpuctl) { | ||
| 165 | printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); | ||
| 166 | return -ENOMEM; | ||
| 167 | } | ||
| 168 | |||
| 169 | return cpufreq_register_driver(&sc520_freq_driver); | ||
| 170 | } | ||
| 171 | |||
| 172 | |||
| 173 | static void __exit sc520_freq_exit(void) | ||
| 174 | { | ||
| 175 | cpufreq_unregister_driver(&sc520_freq_driver); | ||
| 176 | iounmap(cpuctl); | ||
| 177 | } | ||
| 178 | |||
| 179 | |||
| 180 | MODULE_LICENSE("GPL"); | ||
| 181 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
| 182 | MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU"); | ||
| 183 | |||
| 184 | module_init(sc520_freq_init); | ||
| 185 | module_exit(sc520_freq_exit); | ||
| 186 | |||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 07d5612dc00f..7dcbf70fc16f 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
| @@ -54,6 +54,8 @@ enum { | |||
| 54 | CPU_DOTHAN_A1, | 54 | CPU_DOTHAN_A1, |
| 55 | CPU_DOTHAN_A2, | 55 | CPU_DOTHAN_A2, |
| 56 | CPU_DOTHAN_B0, | 56 | CPU_DOTHAN_B0, |
| 57 | CPU_MP4HT_D0, | ||
| 58 | CPU_MP4HT_E0, | ||
| 57 | }; | 59 | }; |
| 58 | 60 | ||
| 59 | static const struct cpu_id cpu_ids[] = { | 61 | static const struct cpu_id cpu_ids[] = { |
| @@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = { | |||
| 61 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, | 63 | [CPU_DOTHAN_A1] = { 6, 13, 1 }, |
| 62 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, | 64 | [CPU_DOTHAN_A2] = { 6, 13, 2 }, |
| 63 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, | 65 | [CPU_DOTHAN_B0] = { 6, 13, 6 }, |
| 66 | [CPU_MP4HT_D0] = {15, 3, 4 }, | ||
| 67 | [CPU_MP4HT_E0] = {15, 4, 1 }, | ||
| 64 | }; | 68 | }; |
| 65 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) | 69 | #define N_IDS (sizeof(cpu_ids)/sizeof(cpu_ids[0])) |
| 66 | 70 | ||
| @@ -226,6 +230,8 @@ static struct cpu_model models[] = | |||
| 226 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, | 230 | { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, |
| 227 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, | 231 | { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, |
| 228 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, | 232 | { &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL }, |
| 233 | { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, | ||
| 234 | { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, | ||
| 229 | 235 | ||
| 230 | { NULL, } | 236 | { NULL, } |
| 231 | }; | 237 | }; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index 8ba430a9c3a2..d368b3f5fce8 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c | |||
| @@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
| 336 | if (!prev_speed) | 336 | if (!prev_speed) |
| 337 | return -EIO; | 337 | return -EIO; |
| 338 | 338 | ||
| 339 | dprintk("previous seped is %u\n", prev_speed); | 339 | dprintk("previous speed is %u\n", prev_speed); |
| 340 | 340 | ||
| 341 | local_irq_save(flags); | 341 | local_irq_save(flags); |
| 342 | 342 | ||
| @@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
| 348 | goto out; | 348 | goto out; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | dprintk("low seped is %u\n", *low_speed); | 351 | dprintk("low speed is %u\n", *low_speed); |
| 352 | 352 | ||
| 353 | /* switch to high state */ | 353 | /* switch to high state */ |
| 354 | set_state(SPEEDSTEP_HIGH); | 354 | set_state(SPEEDSTEP_HIGH); |
| @@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor, | |||
| 358 | goto out; | 358 | goto out; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | dprintk("high seped is %u\n", *high_speed); | 361 | dprintk("high speed is %u\n", *high_speed); |
| 362 | 362 | ||
| 363 | if (*low_speed == *high_speed) { | 363 | if (*low_speed == *high_speed) { |
| 364 | ret = -ENODEV; | 364 | ret = -ENODEV; |
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index 79440b3f087e..b25fb6b635ae 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c | |||
| @@ -357,6 +357,9 @@ static int __init speedstep_init(void) | |||
| 357 | case SPEEDSTEP_PROCESSOR_PIII_C: | 357 | case SPEEDSTEP_PROCESSOR_PIII_C: |
| 358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: | 358 | case SPEEDSTEP_PROCESSOR_PIII_C_EARLY: |
| 359 | break; | 359 | break; |
| 360 | case SPEEDSTEP_PROCESSOR_P4M: | ||
| 361 | printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n"); | ||
| 362 | break; | ||
| 360 | default: | 363 | default: |
| 361 | speedstep_processor = 0; | 364 | speedstep_processor = 0; |
| 362 | } | 365 | } |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index aeb5b4ef8c8b..a710dc4eb20e 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
| @@ -118,7 +118,7 @@ struct _cpuid4_info { | |||
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | #define MAX_CACHE_LEAVES 4 | 120 | #define MAX_CACHE_LEAVES 4 |
| 121 | static unsigned short __devinitdata num_cache_leaves; | 121 | static unsigned short num_cache_leaves; |
| 122 | 122 | ||
| 123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 123 | static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) |
| 124 | { | 124 | { |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 945ec73163c8..2bfbddebdbf8 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
| @@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p) | |||
| 1502 | if (efi_enabled) | 1502 | if (efi_enabled) |
| 1503 | efi_map_memmap(); | 1503 | efi_map_memmap(); |
| 1504 | 1504 | ||
| 1505 | #ifdef CONFIG_ACPI_BOOT | ||
| 1505 | /* | 1506 | /* |
| 1506 | * Parse the ACPI tables for possible boot-time SMP configuration. | 1507 | * Parse the ACPI tables for possible boot-time SMP configuration. |
| 1507 | */ | 1508 | */ |
| 1508 | acpi_boot_table_init(); | 1509 | acpi_boot_table_init(); |
| 1509 | acpi_boot_init(); | 1510 | acpi_boot_init(); |
| 1511 | #endif | ||
| 1510 | 1512 | ||
| 1511 | #ifdef CONFIG_X86_LOCAL_APIC | 1513 | #ifdef CONFIG_X86_LOCAL_APIC |
| 1512 | if (smp_found_config) | 1514 | if (smp_found_config) |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 35bfe138cb1a..bc1bb6919e6a 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
| @@ -1074,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) | |||
| 1074 | cpu_set(cpu, cpu_sibling_map[cpu]); | 1074 | cpu_set(cpu, cpu_sibling_map[cpu]); |
| 1075 | } | 1075 | } |
| 1076 | 1076 | ||
| 1077 | if (siblings != smp_num_siblings) | 1077 | if (siblings != smp_num_siblings) { |
| 1078 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); | 1078 | printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); |
| 1079 | smp_num_siblings = siblings; | ||
| 1080 | } | ||
| 1079 | 1081 | ||
| 1080 | if (c->x86_num_cores > 1) { | 1082 | if (c->x86_num_cores > 1) { |
| 1081 | for (i = 0; i < NR_CPUS; i++) { | 1083 | for (i = 0; i < NR_CPUS; i++) { |
diff --git a/arch/i386/kernel/timers/common.c b/arch/i386/kernel/timers/common.c index f7f90005e22e..8e201219f525 100644 --- a/arch/i386/kernel/timers/common.c +++ b/arch/i386/kernel/timers/common.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/timex.h> | 6 | #include <linux/timex.h> |
| 7 | #include <linux/errno.h> | 7 | #include <linux/errno.h> |
| 8 | #include <linux/jiffies.h> | 8 | #include <linux/jiffies.h> |
| 9 | #include <linux/module.h> | ||
| 9 | 10 | ||
| 10 | #include <asm/io.h> | 11 | #include <asm/io.h> |
| 11 | #include <asm/timer.h> | 12 | #include <asm/timer.h> |
| @@ -24,7 +25,7 @@ | |||
| 24 | 25 | ||
| 25 | #define CALIBRATE_TIME (5 * 1000020/HZ) | 26 | #define CALIBRATE_TIME (5 * 1000020/HZ) |
| 26 | 27 | ||
| 27 | unsigned long __init calibrate_tsc(void) | 28 | unsigned long calibrate_tsc(void) |
| 28 | { | 29 | { |
| 29 | mach_prepare_counter(); | 30 | mach_prepare_counter(); |
| 30 | 31 | ||
| @@ -139,7 +140,7 @@ bad_calibration: | |||
| 139 | #endif | 140 | #endif |
| 140 | 141 | ||
| 141 | /* calculate cpu_khz */ | 142 | /* calculate cpu_khz */ |
| 142 | void __init init_cpu_khz(void) | 143 | void init_cpu_khz(void) |
| 143 | { | 144 | { |
| 144 | if (cpu_has_tsc) { | 145 | if (cpu_has_tsc) { |
| 145 | unsigned long tsc_quotient = calibrate_tsc(); | 146 | unsigned long tsc_quotient = calibrate_tsc(); |
| @@ -158,3 +159,4 @@ void __init init_cpu_khz(void) | |||
| 158 | } | 159 | } |
| 159 | } | 160 | } |
| 160 | } | 161 | } |
| 162 | |||
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index 7926d967be00..180444d87824 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c | |||
| @@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc); | |||
| 320 | static inline void cpufreq_delayed_get(void) { return; } | 320 | static inline void cpufreq_delayed_get(void) { return; } |
| 321 | #endif | 321 | #endif |
| 322 | 322 | ||
| 323 | int recalibrate_cpu_khz(void) | ||
| 324 | { | ||
| 325 | #ifndef CONFIG_SMP | ||
| 326 | unsigned long cpu_khz_old = cpu_khz; | ||
| 327 | |||
| 328 | if (cpu_has_tsc) { | ||
| 329 | init_cpu_khz(); | ||
| 330 | cpu_data[0].loops_per_jiffy = | ||
| 331 | cpufreq_scale(cpu_data[0].loops_per_jiffy, | ||
| 332 | cpu_khz_old, | ||
| 333 | cpu_khz); | ||
| 334 | return 0; | ||
| 335 | } else | ||
| 336 | return -ENODEV; | ||
| 337 | #else | ||
| 338 | return -ENODEV; | ||
| 339 | #endif | ||
| 340 | } | ||
| 341 | EXPORT_SYMBOL(recalibrate_cpu_khz); | ||
| 342 | |||
| 323 | static void mark_offset_tsc(void) | 343 | static void mark_offset_tsc(void) |
| 324 | { | 344 | { |
| 325 | unsigned long lost,delay; | 345 | unsigned long lost,delay; |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 247a21c64aea..c1e20d65dd6c 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
| @@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents, | |||
| 2427 | { | 2427 | { |
| 2428 | struct epoll_event *events64 = NULL; | 2428 | struct epoll_event *events64 = NULL; |
| 2429 | mm_segment_t old_fs = get_fs(); | 2429 | mm_segment_t old_fs = get_fs(); |
| 2430 | int error, numevents, size; | 2430 | int numevents, size; |
| 2431 | int evt_idx; | 2431 | int evt_idx; |
| 2432 | int do_free_pages = 0; | 2432 | int do_free_pages = 0; |
| 2433 | 2433 | ||
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 81c45d447394..d99316c9be28 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
| @@ -1182,7 +1182,7 @@ ENTRY(notify_resume_user) | |||
| 1182 | ;; | 1182 | ;; |
| 1183 | (pNonSys) mov out2=0 // out2==0 => not a syscall | 1183 | (pNonSys) mov out2=0 // out2==0 => not a syscall |
| 1184 | .fframe 16 | 1184 | .fframe 16 |
| 1185 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1185 | .spillsp ar.unat, 16 |
| 1186 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1186 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
| 1187 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch | 1187 | st8 [out1]=loc1,-8 // save ar.pfs, out1=&sigscratch |
| 1188 | .body | 1188 | .body |
| @@ -1208,7 +1208,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend) | |||
| 1208 | adds out2=8,sp // out2=&sigscratch->ar_pfs | 1208 | adds out2=8,sp // out2=&sigscratch->ar_pfs |
| 1209 | ;; | 1209 | ;; |
| 1210 | .fframe 16 | 1210 | .fframe 16 |
| 1211 | .spillpsp ar.unat, 16 // (note that offset is relative to psp+0x10!) | 1211 | .spillsp ar.unat, 16 |
| 1212 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it | 1212 | st8 [sp]=r9,-16 // allocate space for ar.unat and save it |
| 1213 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch | 1213 | st8 [out2]=loc1,-8 // save ar.pfs, out2=&sigscratch |
| 1214 | .body | 1214 | .body |
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 4d6c7b8f667b..736e328b5e61 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
| @@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs) | |||
| 1103 | return IRQ_HANDLED; | 1103 | return IRQ_HANDLED; |
| 1104 | } | 1104 | } |
| 1105 | 1105 | ||
| 1106 | #endif /* CONFIG_ACPI */ | ||
| 1107 | |||
| 1108 | /* | 1106 | /* |
| 1109 | * ia64_mca_cpe_poll | 1107 | * ia64_mca_cpe_poll |
| 1110 | * | 1108 | * |
| @@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy) | |||
| 1122 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); | 1120 | platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0); |
| 1123 | } | 1121 | } |
| 1124 | 1122 | ||
| 1123 | #endif /* CONFIG_ACPI */ | ||
| 1124 | |||
| 1125 | /* | 1125 | /* |
| 1126 | * C portion of the OS INIT handler | 1126 | * C portion of the OS INIT handler |
| 1127 | * | 1127 | * |
| @@ -1390,8 +1390,7 @@ ia64_mca_init(void) | |||
| 1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); | 1390 | register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction); |
| 1391 | 1391 | ||
| 1392 | #ifdef CONFIG_ACPI | 1392 | #ifdef CONFIG_ACPI |
| 1393 | /* Setup the CPEI/P vector and handler */ | 1393 | /* Setup the CPEI/P handler */ |
| 1394 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
| 1395 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); | 1394 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); |
| 1396 | #endif | 1395 | #endif |
| 1397 | 1396 | ||
| @@ -1436,6 +1435,7 @@ ia64_mca_late_init(void) | |||
| 1436 | 1435 | ||
| 1437 | #ifdef CONFIG_ACPI | 1436 | #ifdef CONFIG_ACPI |
| 1438 | /* Setup the CPEI/P vector and handler */ | 1437 | /* Setup the CPEI/P vector and handler */ |
| 1438 | cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI); | ||
| 1439 | init_timer(&cpe_poll_timer); | 1439 | init_timer(&cpe_poll_timer); |
| 1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; | 1440 | cpe_poll_timer.function = ia64_mca_cpe_poll; |
| 1441 | 1441 | ||
diff --git a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h index 1dbc7b2497c9..f6d8a010d99b 100644 --- a/arch/ia64/kernel/minstate.h +++ b/arch/ia64/kernel/minstate.h | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ | 41 | (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;; \ |
| 42 | (pKStk) ld8 r3 = [r3];; \ | 42 | (pKStk) ld8 r3 = [r3];; \ |
| 43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ | 43 | (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;; \ |
| 44 | (pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ | 44 | (pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3; \ |
| 45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ | 45 | (pUStk) mov ar.rsc=0; /* set enforced lazy mode, pl 0, little-endian, loadrs=0 */ \ |
| 46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ | 46 | (pUStk) addl r22=IA64_RBS_OFFSET,r1; /* compute base of register backing store */ \ |
| 47 | ;; \ | 47 | ;; \ |
| @@ -50,7 +50,6 @@ | |||
| 50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ | 50 | (pUStk) mov r23=ar.bspstore; /* save ar.bspstore */ \ |
| 51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ | 51 | (pUStk) dep r22=-1,r22,61,3; /* compute kernel virtual addr of RBS */ \ |
| 52 | ;; \ | 52 | ;; \ |
| 53 | (pKStk) addl r1=-IA64_PT_REGS_SIZE,r1; /* if in kernel mode, use sp (r12) */ \ | ||
| 54 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ | 53 | (pUStk) mov ar.bspstore=r22; /* switch to kernel RBS */ \ |
| 55 | ;; \ | 54 | ;; \ |
| 56 | (pUStk) mov r18=ar.bsp; \ | 55 | (pUStk) mov r18=ar.bsp; \ |
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 71c101601e3e..6407bff6bfd7 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x | 11 | * Version Perfmon-2.x is a rewrite of perfmon-1.x |
| 12 | * by Stephane Eranian, Hewlett Packard Co. | 12 | * by Stephane Eranian, Hewlett Packard Co. |
| 13 | * | 13 | * |
| 14 | * Copyright (C) 1999-2003, 2005 Hewlett Packard Co | 14 | * Copyright (C) 1999-2005 Hewlett Packard Co |
| 15 | * Stephane Eranian <eranian@hpl.hp.com> | 15 | * Stephane Eranian <eranian@hpl.hp.com> |
| 16 | * David Mosberger-Tang <davidm@hpl.hp.com> | 16 | * David Mosberger-Tang <davidm@hpl.hp.com> |
| 17 | * | 17 | * |
| @@ -497,6 +497,9 @@ typedef struct { | |||
| 497 | static pfm_stats_t pfm_stats[NR_CPUS]; | 497 | static pfm_stats_t pfm_stats[NR_CPUS]; |
| 498 | static pfm_session_t pfm_sessions; /* global sessions information */ | 498 | static pfm_session_t pfm_sessions; /* global sessions information */ |
| 499 | 499 | ||
| 500 | static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED; | ||
| 501 | static pfm_intr_handler_desc_t *pfm_alt_intr_handler; | ||
| 502 | |||
| 500 | static struct proc_dir_entry *perfmon_dir; | 503 | static struct proc_dir_entry *perfmon_dir; |
| 501 | static pfm_uuid_t pfm_null_uuid = {0,}; | 504 | static pfm_uuid_t pfm_null_uuid = {0,}; |
| 502 | 505 | ||
| @@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info); | |||
| 606 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); | 609 | DEFINE_PER_CPU(struct task_struct *, pmu_owner); |
| 607 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); | 610 | DEFINE_PER_CPU(pfm_context_t *, pmu_ctx); |
| 608 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); | 611 | DEFINE_PER_CPU(unsigned long, pmu_activation_number); |
| 612 | EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info); | ||
| 609 | 613 | ||
| 610 | 614 | ||
| 611 | /* forward declaration */ | 615 | /* forward declaration */ |
| @@ -1325,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) | |||
| 1325 | error_conflict: | 1329 | error_conflict: |
| 1326 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", | 1330 | DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", |
| 1327 | pfm_sessions.pfs_sys_session[cpu]->pid, | 1331 | pfm_sessions.pfs_sys_session[cpu]->pid, |
| 1328 | smp_processor_id())); | 1332 | cpu)); |
| 1329 | abort: | 1333 | abort: |
| 1330 | UNLOCK_PFS(flags); | 1334 | UNLOCK_PFS(flags); |
| 1331 | 1335 | ||
| @@ -5555,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) | |||
| 5555 | int ret; | 5559 | int ret; |
| 5556 | 5560 | ||
| 5557 | this_cpu = get_cpu(); | 5561 | this_cpu = get_cpu(); |
| 5558 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; | 5562 | if (likely(!pfm_alt_intr_handler)) { |
| 5559 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | 5563 | min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min; |
| 5564 | max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max; | ||
| 5560 | 5565 | ||
| 5561 | start_cycles = ia64_get_itc(); | 5566 | start_cycles = ia64_get_itc(); |
| 5562 | 5567 | ||
| 5563 | ret = pfm_do_interrupt_handler(irq, arg, regs); | 5568 | ret = pfm_do_interrupt_handler(irq, arg, regs); |
| 5564 | 5569 | ||
| 5565 | total_cycles = ia64_get_itc(); | 5570 | total_cycles = ia64_get_itc(); |
| 5566 | 5571 | ||
| 5567 | /* | 5572 | /* |
| 5568 | * don't measure spurious interrupts | 5573 | * don't measure spurious interrupts |
| 5569 | */ | 5574 | */ |
| 5570 | if (likely(ret == 0)) { | 5575 | if (likely(ret == 0)) { |
| 5571 | total_cycles -= start_cycles; | 5576 | total_cycles -= start_cycles; |
| 5572 | 5577 | ||
| 5573 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; | 5578 | if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles; |
| 5574 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; | 5579 | if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles; |
| 5575 | 5580 | ||
| 5576 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; | 5581 | pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles; |
| 5582 | } | ||
| 5583 | } | ||
| 5584 | else { | ||
| 5585 | (*pfm_alt_intr_handler->handler)(irq, arg, regs); | ||
| 5577 | } | 5586 | } |
| 5587 | |||
| 5578 | put_cpu_no_resched(); | 5588 | put_cpu_no_resched(); |
| 5579 | return IRQ_HANDLED; | 5589 | return IRQ_HANDLED; |
| 5580 | } | 5590 | } |
| @@ -6425,6 +6435,141 @@ static struct irqaction perfmon_irqaction = { | |||
| 6425 | .name = "perfmon" | 6435 | .name = "perfmon" |
| 6426 | }; | 6436 | }; |
| 6427 | 6437 | ||
| 6438 | static void | ||
| 6439 | pfm_alt_save_pmu_state(void *data) | ||
| 6440 | { | ||
| 6441 | struct pt_regs *regs; | ||
| 6442 | |||
| 6443 | regs = ia64_task_regs(current); | ||
| 6444 | |||
| 6445 | DPRINT(("called\n")); | ||
| 6446 | |||
| 6447 | /* | ||
| 6448 | * should not be necessary but | ||
| 6449 | * let's take not risk | ||
| 6450 | */ | ||
| 6451 | pfm_clear_psr_up(); | ||
| 6452 | pfm_clear_psr_pp(); | ||
| 6453 | ia64_psr(regs)->pp = 0; | ||
| 6454 | |||
| 6455 | /* | ||
| 6456 | * This call is required | ||
| 6457 | * May cause a spurious interrupt on some processors | ||
| 6458 | */ | ||
| 6459 | pfm_freeze_pmu(); | ||
| 6460 | |||
| 6461 | ia64_srlz_d(); | ||
| 6462 | } | ||
| 6463 | |||
| 6464 | void | ||
| 6465 | pfm_alt_restore_pmu_state(void *data) | ||
| 6466 | { | ||
| 6467 | struct pt_regs *regs; | ||
| 6468 | |||
| 6469 | regs = ia64_task_regs(current); | ||
| 6470 | |||
| 6471 | DPRINT(("called\n")); | ||
| 6472 | |||
| 6473 | /* | ||
| 6474 | * put PMU back in state expected | ||
| 6475 | * by perfmon | ||
| 6476 | */ | ||
| 6477 | pfm_clear_psr_up(); | ||
| 6478 | pfm_clear_psr_pp(); | ||
| 6479 | ia64_psr(regs)->pp = 0; | ||
| 6480 | |||
| 6481 | /* | ||
| 6482 | * perfmon runs with PMU unfrozen at all times | ||
| 6483 | */ | ||
| 6484 | pfm_unfreeze_pmu(); | ||
| 6485 | |||
| 6486 | ia64_srlz_d(); | ||
| 6487 | } | ||
| 6488 | |||
| 6489 | int | ||
| 6490 | pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
| 6491 | { | ||
| 6492 | int ret, i; | ||
| 6493 | int reserve_cpu; | ||
| 6494 | |||
| 6495 | /* some sanity checks */ | ||
| 6496 | if (hdl == NULL || hdl->handler == NULL) return -EINVAL; | ||
| 6497 | |||
| 6498 | /* do the easy test first */ | ||
| 6499 | if (pfm_alt_intr_handler) return -EBUSY; | ||
| 6500 | |||
| 6501 | /* one at a time in the install or remove, just fail the others */ | ||
| 6502 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
| 6503 | return -EBUSY; | ||
| 6504 | } | ||
| 6505 | |||
| 6506 | /* reserve our session */ | ||
| 6507 | for_each_online_cpu(reserve_cpu) { | ||
| 6508 | ret = pfm_reserve_session(NULL, 1, reserve_cpu); | ||
| 6509 | if (ret) goto cleanup_reserve; | ||
| 6510 | } | ||
| 6511 | |||
| 6512 | /* save the current system wide pmu states */ | ||
| 6513 | ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1); | ||
| 6514 | if (ret) { | ||
| 6515 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
| 6516 | goto cleanup_reserve; | ||
| 6517 | } | ||
| 6518 | |||
| 6519 | /* officially change to the alternate interrupt handler */ | ||
| 6520 | pfm_alt_intr_handler = hdl; | ||
| 6521 | |||
| 6522 | spin_unlock(&pfm_alt_install_check); | ||
| 6523 | |||
| 6524 | return 0; | ||
| 6525 | |||
| 6526 | cleanup_reserve: | ||
| 6527 | for_each_online_cpu(i) { | ||
| 6528 | /* don't unreserve more than we reserved */ | ||
| 6529 | if (i >= reserve_cpu) break; | ||
| 6530 | |||
| 6531 | pfm_unreserve_session(NULL, 1, i); | ||
| 6532 | } | ||
| 6533 | |||
| 6534 | spin_unlock(&pfm_alt_install_check); | ||
| 6535 | |||
| 6536 | return ret; | ||
| 6537 | } | ||
| 6538 | EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt); | ||
| 6539 | |||
| 6540 | int | ||
| 6541 | pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl) | ||
| 6542 | { | ||
| 6543 | int i; | ||
| 6544 | int ret; | ||
| 6545 | |||
| 6546 | if (hdl == NULL) return -EINVAL; | ||
| 6547 | |||
| 6548 | /* cannot remove someone else's handler! */ | ||
| 6549 | if (pfm_alt_intr_handler != hdl) return -EINVAL; | ||
| 6550 | |||
| 6551 | /* one at a time in the install or remove, just fail the others */ | ||
| 6552 | if (!spin_trylock(&pfm_alt_install_check)) { | ||
| 6553 | return -EBUSY; | ||
| 6554 | } | ||
| 6555 | |||
| 6556 | pfm_alt_intr_handler = NULL; | ||
| 6557 | |||
| 6558 | ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1); | ||
| 6559 | if (ret) { | ||
| 6560 | DPRINT(("on_each_cpu() failed: %d\n", ret)); | ||
| 6561 | } | ||
| 6562 | |||
| 6563 | for_each_online_cpu(i) { | ||
| 6564 | pfm_unreserve_session(NULL, 1, i); | ||
| 6565 | } | ||
| 6566 | |||
| 6567 | spin_unlock(&pfm_alt_install_check); | ||
| 6568 | |||
| 6569 | return 0; | ||
| 6570 | } | ||
| 6571 | EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt); | ||
| 6572 | |||
| 6428 | /* | 6573 | /* |
| 6429 | * perfmon initialization routine, called from the initcall() table | 6574 | * perfmon initialization routine, called from the initcall() table |
| 6430 | */ | 6575 | */ |
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 907464ee7273..08c8a5eb25ab 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
| @@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
| 692 | unsigned long cfm) | 692 | unsigned long cfm) |
| 693 | { | 693 | { |
| 694 | struct unw_frame_info info, prev_info; | 694 | struct unw_frame_info info, prev_info; |
| 695 | unsigned long ip, pr; | 695 | unsigned long ip, sp, pr; |
| 696 | 696 | ||
| 697 | unw_init_from_blocked_task(&info, child); | 697 | unw_init_from_blocked_task(&info, child); |
| 698 | while (1) { | 698 | while (1) { |
| 699 | prev_info = info; | 699 | prev_info = info; |
| 700 | if (unw_unwind(&info) < 0) | 700 | if (unw_unwind(&info) < 0) |
| 701 | return; | 701 | return; |
| 702 | if (unw_get_rp(&info, &ip) < 0) | 702 | |
| 703 | unw_get_sp(&info, &sp); | ||
| 704 | if ((long)((unsigned long)child + IA64_STK_OFFSET - sp) | ||
| 705 | < IA64_PT_REGS_SIZE) { | ||
| 706 | dprintk("ptrace.%s: ran off the top of the kernel " | ||
| 707 | "stack\n", __FUNCTION__); | ||
| 708 | return; | ||
| 709 | } | ||
| 710 | if (unw_get_pr (&prev_info, &pr) < 0) { | ||
| 711 | unw_get_rp(&prev_info, &ip); | ||
| 712 | dprintk("ptrace.%s: failed to read " | ||
| 713 | "predicate register (ip=0x%lx)\n", | ||
| 714 | __FUNCTION__, ip); | ||
| 703 | return; | 715 | return; |
| 704 | if (ip < FIXADDR_USER_END) | 716 | } |
| 717 | if (unw_is_intr_frame(&info) | ||
| 718 | && (pr & (1UL << PRED_USER_STACK))) | ||
| 705 | break; | 719 | break; |
| 706 | } | 720 | } |
| 707 | 721 | ||
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 0d5ee57c9865..3865f088ffa2 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
| @@ -624,7 +624,7 @@ static struct { | |||
| 624 | __u16 thread_id; | 624 | __u16 thread_id; |
| 625 | __u16 proc_fixed_addr; | 625 | __u16 proc_fixed_addr; |
| 626 | __u8 valid; | 626 | __u8 valid; |
| 627 | }mt_info[NR_CPUS] __devinit; | 627 | } mt_info[NR_CPUS] __devinitdata; |
| 628 | 628 | ||
| 629 | #ifdef CONFIG_HOTPLUG_CPU | 629 | #ifdef CONFIG_HOTPLUG_CPU |
| 630 | static inline void | 630 | static inline void |
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c index a8cf6d8a509c..770fab37928e 100644 --- a/arch/ia64/kernel/sys_ia64.c +++ b/arch/ia64/kernel/sys_ia64.c | |||
| @@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un | |||
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /* | ||
| 186 | * A zero mmap always succeeds in Linux, independent of whether or not the | ||
| 187 | * remaining arguments are valid. | ||
| 188 | */ | ||
| 189 | if (len == 0) | ||
| 190 | goto out; | ||
| 191 | |||
| 192 | /* Careful about overflows.. */ | 185 | /* Careful about overflows.. */ |
| 193 | len = PAGE_ALIGN(len); | 186 | len = PAGE_ALIGN(len); |
| 194 | if (!len || len > TASK_SIZE) { | 187 | if (!len || len > TASK_SIZE) { |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 4fb44984afe6..e64cb8175f7a 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
| @@ -271,6 +271,8 @@ void __init sn_setup(char **cmdline_p) | |||
| 271 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); | 271 | int major = sn_sal_rev_major(), minor = sn_sal_rev_minor(); |
| 272 | extern void sn_cpu_init(void); | 272 | extern void sn_cpu_init(void); |
| 273 | 273 | ||
| 274 | ia64_sn_plat_set_error_handling_features(); | ||
| 275 | |||
| 274 | /* | 276 | /* |
| 275 | * If the generic code has enabled vga console support - lets | 277 | * If the generic code has enabled vga console support - lets |
| 276 | * get rid of it again. This is a kludge for the fact that ACPI | 278 | * get rid of it again. This is a kludge for the fact that ACPI |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 600f23d7fd33..6e6377a69d5b 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
| @@ -1143,12 +1143,12 @@ config PCI_QSPAN | |||
| 1143 | 1143 | ||
| 1144 | config PCI_8260 | 1144 | config PCI_8260 |
| 1145 | bool | 1145 | bool |
| 1146 | depends on PCI && 8260 && !8272 | 1146 | depends on PCI && 8260 |
| 1147 | default y | 1147 | default y |
| 1148 | 1148 | ||
| 1149 | config 8260_PCI9 | 1149 | config 8260_PCI9 |
| 1150 | bool " Enable workaround for MPC826x erratum PCI 9" | 1150 | bool " Enable workaround for MPC826x erratum PCI 9" |
| 1151 | depends on PCI_8260 | 1151 | depends on PCI_8260 && !ADS8272 |
| 1152 | default y | 1152 | default y |
| 1153 | 1153 | ||
| 1154 | choice | 1154 | choice |
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile index f850fb0fb511..c9ac5f5fa9e4 100644 --- a/arch/ppc/boot/images/Makefile +++ b/arch/ppc/boot/images/Makefile | |||
| @@ -22,7 +22,8 @@ targets += uImage | |||
| 22 | $(obj)/uImage: $(obj)/vmlinux.gz | 22 | $(obj)/uImage: $(obj)/vmlinux.gz |
| 23 | $(Q)rm -f $@ | 23 | $(Q)rm -f $@ |
| 24 | $(call if_changed,uimage) | 24 | $(call if_changed,uimage) |
| 25 | @echo ' Image: $@' $(if $(wildcard $@),'is ready','not made') | 25 | @echo -n ' Image: $@ ' |
| 26 | @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi | ||
| 26 | 27 | ||
| 27 | # Files generated that shall be removed upon make clean | 28 | # Files generated that shall be removed upon make clean |
| 28 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage | 29 | clean-files := sImage vmapus vmlinux* miboot* zImage* uImage |
diff --git a/arch/ppc/configs/mpc8555_cds_defconfig b/arch/ppc/configs/mpc8555_cds_defconfig index 728bd9e1a8fa..15abebf46b96 100644 --- a/arch/ppc/configs/mpc8555_cds_defconfig +++ b/arch/ppc/configs/mpc8555_cds_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.11-rc1 | 3 | # Linux kernel version: 2.6.12-rc4 |
| 4 | # Thu Jan 20 01:25:35 2005 | 4 | # Tue May 17 11:56:01 2005 |
| 5 | # | 5 | # |
| 6 | CONFIG_MMU=y | 6 | CONFIG_MMU=y |
| 7 | CONFIG_GENERIC_HARDIRQS=y | 7 | CONFIG_GENERIC_HARDIRQS=y |
| @@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y | |||
| 11 | CONFIG_PPC=y | 11 | CONFIG_PPC=y |
| 12 | CONFIG_PPC32=y | 12 | CONFIG_PPC32=y |
| 13 | CONFIG_GENERIC_NVRAM=y | 13 | CONFIG_GENERIC_NVRAM=y |
| 14 | CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y | ||
| 14 | 15 | ||
| 15 | # | 16 | # |
| 16 | # Code maturity level options | 17 | # Code maturity level options |
| @@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y | |||
| 18 | CONFIG_EXPERIMENTAL=y | 19 | CONFIG_EXPERIMENTAL=y |
| 19 | CONFIG_CLEAN_COMPILE=y | 20 | CONFIG_CLEAN_COMPILE=y |
| 20 | CONFIG_BROKEN_ON_SMP=y | 21 | CONFIG_BROKEN_ON_SMP=y |
| 22 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
| 21 | 23 | ||
| 22 | # | 24 | # |
| 23 | # General setup | 25 | # General setup |
| @@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y | |||
| 29 | # CONFIG_BSD_PROCESS_ACCT is not set | 31 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 30 | CONFIG_SYSCTL=y | 32 | CONFIG_SYSCTL=y |
| 31 | # CONFIG_AUDIT is not set | 33 | # CONFIG_AUDIT is not set |
| 32 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 33 | # CONFIG_HOTPLUG is not set | 34 | # CONFIG_HOTPLUG is not set |
| 34 | CONFIG_KOBJECT_UEVENT=y | 35 | CONFIG_KOBJECT_UEVENT=y |
| 35 | # CONFIG_IKCONFIG is not set | 36 | # CONFIG_IKCONFIG is not set |
| 36 | CONFIG_EMBEDDED=y | 37 | CONFIG_EMBEDDED=y |
| 37 | # CONFIG_KALLSYMS is not set | 38 | # CONFIG_KALLSYMS is not set |
| 39 | CONFIG_PRINTK=y | ||
| 40 | CONFIG_BUG=y | ||
| 41 | CONFIG_BASE_FULL=y | ||
| 38 | CONFIG_FUTEX=y | 42 | CONFIG_FUTEX=y |
| 39 | # CONFIG_EPOLL is not set | 43 | # CONFIG_EPOLL is not set |
| 40 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | 44 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set |
| @@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0 | |||
| 44 | CONFIG_CC_ALIGN_LOOPS=0 | 48 | CONFIG_CC_ALIGN_LOOPS=0 |
| 45 | CONFIG_CC_ALIGN_JUMPS=0 | 49 | CONFIG_CC_ALIGN_JUMPS=0 |
| 46 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
| 51 | CONFIG_BASE_SMALL=0 | ||
| 47 | 52 | ||
| 48 | # | 53 | # |
| 49 | # Loadable module support | 54 | # Loadable module support |
| @@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0 | |||
| 62 | CONFIG_E500=y | 67 | CONFIG_E500=y |
| 63 | CONFIG_BOOKE=y | 68 | CONFIG_BOOKE=y |
| 64 | CONFIG_FSL_BOOKE=y | 69 | CONFIG_FSL_BOOKE=y |
| 70 | # CONFIG_PHYS_64BIT is not set | ||
| 65 | CONFIG_SPE=y | 71 | CONFIG_SPE=y |
| 66 | CONFIG_MATH_EMULATION=y | 72 | CONFIG_MATH_EMULATION=y |
| 67 | # CONFIG_CPU_FREQ is not set | 73 | # CONFIG_CPU_FREQ is not set |
| 68 | CONFIG_PPC_GEN550=y | 74 | CONFIG_PPC_GEN550=y |
| 75 | # CONFIG_PM is not set | ||
| 69 | CONFIG_85xx=y | 76 | CONFIG_85xx=y |
| 70 | CONFIG_PPC_INDIRECT_PCI_BE=y | 77 | CONFIG_PPC_INDIRECT_PCI_BE=y |
| 71 | 78 | ||
| @@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y | |||
| 76 | CONFIG_MPC8555_CDS=y | 83 | CONFIG_MPC8555_CDS=y |
| 77 | # CONFIG_MPC8560_ADS is not set | 84 | # CONFIG_MPC8560_ADS is not set |
| 78 | # CONFIG_SBC8560 is not set | 85 | # CONFIG_SBC8560 is not set |
| 86 | # CONFIG_STX_GP3 is not set | ||
| 79 | CONFIG_MPC8555=y | 87 | CONFIG_MPC8555=y |
| 80 | CONFIG_85xx_PCI2=y | 88 | CONFIG_85xx_PCI2=y |
| 81 | 89 | ||
| @@ -90,6 +98,7 @@ CONFIG_CPM2=y | |||
| 90 | CONFIG_BINFMT_ELF=y | 98 | CONFIG_BINFMT_ELF=y |
| 91 | # CONFIG_BINFMT_MISC is not set | 99 | # CONFIG_BINFMT_MISC is not set |
| 92 | # CONFIG_CMDLINE_BOOL is not set | 100 | # CONFIG_CMDLINE_BOOL is not set |
| 101 | CONFIG_ISA_DMA_API=y | ||
| 93 | 102 | ||
| 94 | # | 103 | # |
| 95 | # Bus options | 104 | # Bus options |
| @@ -105,10 +114,6 @@ CONFIG_PCI_NAMES=y | |||
| 105 | # CONFIG_PCCARD is not set | 114 | # CONFIG_PCCARD is not set |
| 106 | 115 | ||
| 107 | # | 116 | # |
| 108 | # PC-card bridges | ||
| 109 | # | ||
| 110 | |||
| 111 | # | ||
| 112 | # Advanced setup | 117 | # Advanced setup |
| 113 | # | 118 | # |
| 114 | # CONFIG_ADVANCED_OPTIONS is not set | 119 | # CONFIG_ADVANCED_OPTIONS is not set |
| @@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y | |||
| 180 | # | 185 | # |
| 181 | # ATA/ATAPI/MFM/RLL support | 186 | # ATA/ATAPI/MFM/RLL support |
| 182 | # | 187 | # |
| 183 | # CONFIG_IDE is not set | 188 | CONFIG_IDE=y |
| 189 | CONFIG_BLK_DEV_IDE=y | ||
| 190 | |||
| 191 | # | ||
| 192 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
| 193 | # | ||
| 194 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
| 195 | CONFIG_BLK_DEV_IDEDISK=y | ||
| 196 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
| 197 | # CONFIG_BLK_DEV_IDECD is not set | ||
| 198 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
| 199 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
| 200 | # CONFIG_IDE_TASK_IOCTL is not set | ||
| 201 | |||
| 202 | # | ||
| 203 | # IDE chipset support/bugfixes | ||
| 204 | # | ||
| 205 | CONFIG_IDE_GENERIC=y | ||
| 206 | CONFIG_BLK_DEV_IDEPCI=y | ||
| 207 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
| 208 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
| 209 | CONFIG_BLK_DEV_GENERIC=y | ||
| 210 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
| 211 | # CONFIG_BLK_DEV_SL82C105 is not set | ||
| 212 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
| 213 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
| 214 | CONFIG_IDEDMA_PCI_AUTO=y | ||
| 215 | # CONFIG_IDEDMA_ONLYDISK is not set | ||
| 216 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
| 217 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
| 218 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
| 219 | # CONFIG_BLK_DEV_CMD64X is not set | ||
| 220 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
| 221 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
| 222 | # CONFIG_BLK_DEV_CS5520 is not set | ||
| 223 | # CONFIG_BLK_DEV_CS5530 is not set | ||
| 224 | # CONFIG_BLK_DEV_HPT34X is not set | ||
| 225 | # CONFIG_BLK_DEV_HPT366 is not set | ||
| 226 | # CONFIG_BLK_DEV_SC1200 is not set | ||
| 227 | # CONFIG_BLK_DEV_PIIX is not set | ||
| 228 | # CONFIG_BLK_DEV_NS87415 is not set | ||
| 229 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
| 230 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
| 231 | # CONFIG_BLK_DEV_SVWKS is not set | ||
| 232 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
| 233 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
| 234 | # CONFIG_BLK_DEV_TRM290 is not set | ||
| 235 | CONFIG_BLK_DEV_VIA82CXXX=y | ||
| 236 | # CONFIG_IDE_ARM is not set | ||
| 237 | CONFIG_BLK_DEV_IDEDMA=y | ||
| 238 | # CONFIG_IDEDMA_IVB is not set | ||
| 239 | CONFIG_IDEDMA_AUTO=y | ||
| 240 | # CONFIG_BLK_DEV_HD is not set | ||
| 184 | 241 | ||
| 185 | # | 242 | # |
| 186 | # SCSI device support | 243 | # SCSI device support |
| @@ -220,7 +277,6 @@ CONFIG_NET=y | |||
| 220 | # | 277 | # |
| 221 | CONFIG_PACKET=y | 278 | CONFIG_PACKET=y |
| 222 | # CONFIG_PACKET_MMAP is not set | 279 | # CONFIG_PACKET_MMAP is not set |
| 223 | # CONFIG_NETLINK_DEV is not set | ||
| 224 | CONFIG_UNIX=y | 280 | CONFIG_UNIX=y |
| 225 | # CONFIG_NET_KEY is not set | 281 | # CONFIG_NET_KEY is not set |
| 226 | CONFIG_INET=y | 282 | CONFIG_INET=y |
| @@ -370,14 +426,6 @@ CONFIG_INPUT=y | |||
| 370 | # CONFIG_INPUT_EVBUG is not set | 426 | # CONFIG_INPUT_EVBUG is not set |
| 371 | 427 | ||
| 372 | # | 428 | # |
| 373 | # Input I/O drivers | ||
| 374 | # | ||
| 375 | # CONFIG_GAMEPORT is not set | ||
| 376 | CONFIG_SOUND_GAMEPORT=y | ||
| 377 | # CONFIG_SERIO is not set | ||
| 378 | # CONFIG_SERIO_I8042 is not set | ||
| 379 | |||
| 380 | # | ||
| 381 | # Input Device Drivers | 429 | # Input Device Drivers |
| 382 | # | 430 | # |
| 383 | # CONFIG_INPUT_KEYBOARD is not set | 431 | # CONFIG_INPUT_KEYBOARD is not set |
| @@ -387,6 +435,13 @@ CONFIG_SOUND_GAMEPORT=y | |||
| 387 | # CONFIG_INPUT_MISC is not set | 435 | # CONFIG_INPUT_MISC is not set |
| 388 | 436 | ||
| 389 | # | 437 | # |
| 438 | # Hardware I/O ports | ||
| 439 | # | ||
| 440 | # CONFIG_SERIO is not set | ||
| 441 | # CONFIG_GAMEPORT is not set | ||
| 442 | CONFIG_SOUND_GAMEPORT=y | ||
| 443 | |||
| 444 | # | ||
| 390 | # Character devices | 445 | # Character devices |
| 391 | # | 446 | # |
| 392 | # CONFIG_VT is not set | 447 | # CONFIG_VT is not set |
| @@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
| 406 | CONFIG_SERIAL_CORE=y | 461 | CONFIG_SERIAL_CORE=y |
| 407 | CONFIG_SERIAL_CORE_CONSOLE=y | 462 | CONFIG_SERIAL_CORE_CONSOLE=y |
| 408 | # CONFIG_SERIAL_CPM is not set | 463 | # CONFIG_SERIAL_CPM is not set |
| 464 | # CONFIG_SERIAL_JSM is not set | ||
| 409 | CONFIG_UNIX98_PTYS=y | 465 | CONFIG_UNIX98_PTYS=y |
| 410 | CONFIG_LEGACY_PTYS=y | 466 | CONFIG_LEGACY_PTYS=y |
| 411 | CONFIG_LEGACY_PTY_COUNT=256 | 467 | CONFIG_LEGACY_PTY_COUNT=256 |
| @@ -434,6 +490,11 @@ CONFIG_GEN_RTC=y | |||
| 434 | # CONFIG_RAW_DRIVER is not set | 490 | # CONFIG_RAW_DRIVER is not set |
| 435 | 491 | ||
| 436 | # | 492 | # |
| 493 | # TPM devices | ||
| 494 | # | ||
| 495 | # CONFIG_TCG_TPM is not set | ||
| 496 | |||
| 497 | # | ||
| 437 | # I2C support | 498 | # I2C support |
| 438 | # | 499 | # |
| 439 | CONFIG_I2C=y | 500 | CONFIG_I2C=y |
| @@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y | |||
| 456 | # CONFIG_I2C_AMD8111 is not set | 517 | # CONFIG_I2C_AMD8111 is not set |
| 457 | # CONFIG_I2C_I801 is not set | 518 | # CONFIG_I2C_I801 is not set |
| 458 | # CONFIG_I2C_I810 is not set | 519 | # CONFIG_I2C_I810 is not set |
| 520 | # CONFIG_I2C_PIIX4 is not set | ||
| 459 | # CONFIG_I2C_ISA is not set | 521 | # CONFIG_I2C_ISA is not set |
| 460 | CONFIG_I2C_MPC=y | 522 | CONFIG_I2C_MPC=y |
| 461 | # CONFIG_I2C_NFORCE2 is not set | 523 | # CONFIG_I2C_NFORCE2 is not set |
| 462 | # CONFIG_I2C_PARPORT_LIGHT is not set | 524 | # CONFIG_I2C_PARPORT_LIGHT is not set |
| 463 | # CONFIG_I2C_PIIX4 is not set | ||
| 464 | # CONFIG_I2C_PROSAVAGE is not set | 525 | # CONFIG_I2C_PROSAVAGE is not set |
| 465 | # CONFIG_I2C_SAVAGE4 is not set | 526 | # CONFIG_I2C_SAVAGE4 is not set |
| 466 | # CONFIG_SCx200_ACB is not set | 527 | # CONFIG_SCx200_ACB is not set |
| @@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y | |||
| 483 | # CONFIG_SENSORS_ASB100 is not set | 544 | # CONFIG_SENSORS_ASB100 is not set |
| 484 | # CONFIG_SENSORS_DS1621 is not set | 545 | # CONFIG_SENSORS_DS1621 is not set |
| 485 | # CONFIG_SENSORS_FSCHER is not set | 546 | # CONFIG_SENSORS_FSCHER is not set |
| 547 | # CONFIG_SENSORS_FSCPOS is not set | ||
| 486 | # CONFIG_SENSORS_GL518SM is not set | 548 | # CONFIG_SENSORS_GL518SM is not set |
| 549 | # CONFIG_SENSORS_GL520SM is not set | ||
| 487 | # CONFIG_SENSORS_IT87 is not set | 550 | # CONFIG_SENSORS_IT87 is not set |
| 488 | # CONFIG_SENSORS_LM63 is not set | 551 | # CONFIG_SENSORS_LM63 is not set |
| 489 | # CONFIG_SENSORS_LM75 is not set | 552 | # CONFIG_SENSORS_LM75 is not set |
| @@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y | |||
| 494 | # CONFIG_SENSORS_LM85 is not set | 557 | # CONFIG_SENSORS_LM85 is not set |
| 495 | # CONFIG_SENSORS_LM87 is not set | 558 | # CONFIG_SENSORS_LM87 is not set |
| 496 | # CONFIG_SENSORS_LM90 is not set | 559 | # CONFIG_SENSORS_LM90 is not set |
| 560 | # CONFIG_SENSORS_LM92 is not set | ||
| 497 | # CONFIG_SENSORS_MAX1619 is not set | 561 | # CONFIG_SENSORS_MAX1619 is not set |
| 498 | # CONFIG_SENSORS_PC87360 is not set | 562 | # CONFIG_SENSORS_PC87360 is not set |
| 499 | # CONFIG_SENSORS_SMSC47B397 is not set | 563 | # CONFIG_SENSORS_SMSC47B397 is not set |
| 564 | # CONFIG_SENSORS_SIS5595 is not set | ||
| 500 | # CONFIG_SENSORS_SMSC47M1 is not set | 565 | # CONFIG_SENSORS_SMSC47M1 is not set |
| 501 | # CONFIG_SENSORS_VIA686A is not set | 566 | # CONFIG_SENSORS_VIA686A is not set |
| 502 | # CONFIG_SENSORS_W83781D is not set | 567 | # CONFIG_SENSORS_W83781D is not set |
| @@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y | |||
| 506 | # | 571 | # |
| 507 | # Other I2C Chip support | 572 | # Other I2C Chip support |
| 508 | # | 573 | # |
| 574 | # CONFIG_SENSORS_DS1337 is not set | ||
| 509 | # CONFIG_SENSORS_EEPROM is not set | 575 | # CONFIG_SENSORS_EEPROM is not set |
| 510 | # CONFIG_SENSORS_PCF8574 is not set | 576 | # CONFIG_SENSORS_PCF8574 is not set |
| 511 | # CONFIG_SENSORS_PCF8591 is not set | 577 | # CONFIG_SENSORS_PCF8591 is not set |
| 512 | # CONFIG_SENSORS_RTC8564 is not set | 578 | # CONFIG_SENSORS_RTC8564 is not set |
| 579 | # CONFIG_SENSORS_M41T00 is not set | ||
| 513 | # CONFIG_I2C_DEBUG_CORE is not set | 580 | # CONFIG_I2C_DEBUG_CORE is not set |
| 514 | # CONFIG_I2C_DEBUG_ALGO is not set | 581 | # CONFIG_I2C_DEBUG_ALGO is not set |
| 515 | # CONFIG_I2C_DEBUG_BUS is not set | 582 | # CONFIG_I2C_DEBUG_BUS is not set |
| @@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y | |||
| 538 | # Graphics support | 605 | # Graphics support |
| 539 | # | 606 | # |
| 540 | # CONFIG_FB is not set | 607 | # CONFIG_FB is not set |
| 541 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
| 542 | 608 | ||
| 543 | # | 609 | # |
| 544 | # Sound | 610 | # Sound |
| @@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y | |||
| 548 | # | 614 | # |
| 549 | # USB support | 615 | # USB support |
| 550 | # | 616 | # |
| 551 | # CONFIG_USB is not set | ||
| 552 | CONFIG_USB_ARCH_HAS_HCD=y | 617 | CONFIG_USB_ARCH_HAS_HCD=y |
| 553 | CONFIG_USB_ARCH_HAS_OHCI=y | 618 | CONFIG_USB_ARCH_HAS_OHCI=y |
| 554 | 619 | # CONFIG_USB is not set | |
| 555 | # | ||
| 556 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information | ||
| 557 | # | ||
| 558 | 620 | ||
| 559 | # | 621 | # |
| 560 | # USB Gadget Support | 622 | # USB Gadget Support |
| @@ -585,6 +647,10 @@ CONFIG_JBD=y | |||
| 585 | CONFIG_FS_MBCACHE=y | 647 | CONFIG_FS_MBCACHE=y |
| 586 | # CONFIG_REISERFS_FS is not set | 648 | # CONFIG_REISERFS_FS is not set |
| 587 | # CONFIG_JFS_FS is not set | 649 | # CONFIG_JFS_FS is not set |
| 650 | |||
| 651 | # | ||
| 652 | # XFS support | ||
| 653 | # | ||
| 588 | # CONFIG_XFS_FS is not set | 654 | # CONFIG_XFS_FS is not set |
| 589 | # CONFIG_MINIX_FS is not set | 655 | # CONFIG_MINIX_FS is not set |
| 590 | # CONFIG_ROMFS_FS is not set | 656 | # CONFIG_ROMFS_FS is not set |
| @@ -646,7 +712,6 @@ CONFIG_NFS_FS=y | |||
| 646 | # CONFIG_NFSD is not set | 712 | # CONFIG_NFSD is not set |
| 647 | CONFIG_ROOT_NFS=y | 713 | CONFIG_ROOT_NFS=y |
| 648 | CONFIG_LOCKD=y | 714 | CONFIG_LOCKD=y |
| 649 | # CONFIG_EXPORTFS is not set | ||
| 650 | CONFIG_SUNRPC=y | 715 | CONFIG_SUNRPC=y |
| 651 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 716 | # CONFIG_RPCSEC_GSS_KRB5 is not set |
| 652 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 717 | # CONFIG_RPCSEC_GSS_SPKM3 is not set |
| @@ -698,7 +763,9 @@ CONFIG_CRC32=y | |||
| 698 | # | 763 | # |
| 699 | # Kernel hacking | 764 | # Kernel hacking |
| 700 | # | 765 | # |
| 766 | # CONFIG_PRINTK_TIME is not set | ||
| 701 | # CONFIG_DEBUG_KERNEL is not set | 767 | # CONFIG_DEBUG_KERNEL is not set |
| 768 | CONFIG_LOG_BUF_SHIFT=14 | ||
| 702 | # CONFIG_KGDB_CONSOLE is not set | 769 | # CONFIG_KGDB_CONSOLE is not set |
| 703 | # CONFIG_SERIAL_TEXT_DEBUG is not set | 770 | # CONFIG_SERIAL_TEXT_DEBUG is not set |
| 704 | 771 | ||
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S index f22ddce36135..ce36e88ba627 100644 --- a/arch/ppc/kernel/head_fsl_booke.S +++ b/arch/ppc/kernel/head_fsl_booke.S | |||
| @@ -232,7 +232,8 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
| 232 | tlbwe | 232 | tlbwe |
| 233 | 233 | ||
| 234 | /* 7. Jump to KERNELBASE mapping */ | 234 | /* 7. Jump to KERNELBASE mapping */ |
| 235 | li r7,0 | 235 | lis r7,MSR_KERNEL@h |
| 236 | ori r7,r7,MSR_KERNEL@l | ||
| 236 | bl 1f /* Find our address */ | 237 | bl 1f /* Find our address */ |
| 237 | 1: mflr r9 | 238 | 1: mflr r9 |
| 238 | rlwimi r6,r9,0,20,31 | 239 | rlwimi r6,r9,0,20,31 |
| @@ -293,6 +294,18 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
| 293 | mtspr SPRN_HID0, r2 | 294 | mtspr SPRN_HID0, r2 |
| 294 | #endif | 295 | #endif |
| 295 | 296 | ||
| 297 | #if !defined(CONFIG_BDI_SWITCH) | ||
| 298 | /* | ||
| 299 | * The Abatron BDI JTAG debugger does not tolerate others | ||
| 300 | * mucking with the debug registers. | ||
| 301 | */ | ||
| 302 | lis r2,DBCR0_IDM@h | ||
| 303 | mtspr SPRN_DBCR0,r2 | ||
| 304 | /* clear any residual debug events */ | ||
| 305 | li r2,-1 | ||
| 306 | mtspr SPRN_DBSR,r2 | ||
| 307 | #endif | ||
| 308 | |||
| 296 | /* | 309 | /* |
| 297 | * This is where the main kernel code starts. | 310 | * This is where the main kernel code starts. |
| 298 | */ | 311 | */ |
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index f8e7e324a173..c65731e8bc65 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c | |||
| @@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword) | |||
| 408 | 408 | ||
| 409 | /* Early out if we are an invalid form of lswx */ | 409 | /* Early out if we are an invalid form of lswx */ |
| 410 | if ((instword & INST_STRING_MASK) == INST_LSWX) | 410 | if ((instword & INST_STRING_MASK) == INST_LSWX) |
| 411 | if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB)) | 411 | if ((rT == rA) || (rT == NB_RB)) |
| 412 | return -EINVAL; | ||
| 413 | |||
| 414 | /* Early out if we are an invalid form of lswi */ | ||
| 415 | if ((instword & INST_STRING_MASK) == INST_LSWI) | ||
| 416 | if ((rA >= rT) || (rT == rA)) | ||
| 417 | return -EINVAL; | 412 | return -EINVAL; |
| 418 | 413 | ||
| 419 | EA = (rA == 0) ? 0 : regs->gpr[rA]; | 414 | EA = (rA == 0) ? 0 : regs->gpr[rA]; |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index b3b0f51979d2..e6348b5a1ddc 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
| @@ -127,7 +127,6 @@ mpc834x_sys_map_io(void) | |||
| 127 | { | 127 | { |
| 128 | /* we steal the lowest ioremap addr for virt space */ | 128 | /* we steal the lowest ioremap addr for virt space */ |
| 129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); | 129 | io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO); |
| 130 | io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO); | ||
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | int | 132 | int |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h index f4d055ae19c1..a2f6e49d7151 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.h +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h | |||
| @@ -26,9 +26,14 @@ | |||
| 26 | #define VIRT_IMMRBAR ((uint)0xfe000000) | 26 | #define VIRT_IMMRBAR ((uint)0xfe000000) |
| 27 | 27 | ||
| 28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) | 28 | #define BCSR_PHYS_ADDR ((uint)0xf8000000) |
| 29 | #define BCSR_VIRT_ADDR ((uint)0xfe100000) | ||
| 30 | #define BCSR_SIZE ((uint)(32 * 1024)) | 29 | #define BCSR_SIZE ((uint)(32 * 1024)) |
| 31 | 30 | ||
| 31 | #define BCSR_MISC_REG2_OFF 0x07 | ||
| 32 | #define BCSR_MISC_REG2_PORESET 0x01 | ||
| 33 | |||
| 34 | #define BCSR_MISC_REG3_OFF 0x08 | ||
| 35 | #define BCSR_MISC_REG3_CNFLOCK 0x80 | ||
| 36 | |||
| 32 | #ifdef CONFIG_PCI | 37 | #ifdef CONFIG_PCI |
| 33 | /* PCI interrupt controller */ | 38 | /* PCI interrupt controller */ |
| 34 | #define PIRQA MPC83xx_IRQ_IRQ4 | 39 | #define PIRQA MPC83xx_IRQ_IRQ4 |
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 4d857d6d633d..583838ab02d8 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
| @@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 210 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
| 211 | ppc_md.progress = gen550_progress; | 211 | ppc_md.progress = gen550_progress; |
| 212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 212 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
| 213 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
| 214 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
| 215 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
| 213 | 216 | ||
| 214 | if (ppc_md.progress) | 217 | if (ppc_md.progress) |
| 215 | ppc_md.progress("mpc8540ads_init(): exit", 0); | 218 | ppc_md.progress("mpc8540ads_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 6c020d67ad70..e7cfa498568c 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <asm/machdep.h> | 44 | #include <asm/machdep.h> |
| 45 | #include <asm/prom.h> | 45 | #include <asm/prom.h> |
| 46 | #include <asm/open_pic.h> | 46 | #include <asm/open_pic.h> |
| 47 | #include <asm/i8259.h> | ||
| 47 | #include <asm/bootinfo.h> | 48 | #include <asm/bootinfo.h> |
| 48 | #include <asm/pci-bridge.h> | 49 | #include <asm/pci-bridge.h> |
| 49 | #include <asm/mpc85xx.h> | 50 | #include <asm/mpc85xx.h> |
| @@ -181,6 +182,7 @@ void __init | |||
| 181 | mpc85xx_cds_init_IRQ(void) | 182 | mpc85xx_cds_init_IRQ(void) |
| 182 | { | 183 | { |
| 183 | bd_t *binfo = (bd_t *) __res; | 184 | bd_t *binfo = (bd_t *) __res; |
| 185 | int i; | ||
| 184 | 186 | ||
| 185 | /* Determine the Physical Address of the OpenPIC regs */ | 187 | /* Determine the Physical Address of the OpenPIC regs */ |
| 186 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; | 188 | phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; |
| @@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void) | |||
| 198 | */ | 200 | */ |
| 199 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); | 201 | openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); |
| 200 | 202 | ||
| 203 | #ifdef CONFIG_PCI | ||
| 204 | openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq); | ||
| 205 | |||
| 206 | for (i = 0; i < NUM_8259_INTERRUPTS; i++) | ||
| 207 | irq_desc[i].handler = &i8259_pic; | ||
| 208 | |||
| 209 | i8259_init(0); | ||
| 210 | #endif | ||
| 211 | |||
| 201 | #ifdef CONFIG_CPM2 | 212 | #ifdef CONFIG_CPM2 |
| 202 | /* Setup CPM2 PIC */ | 213 | /* Setup CPM2 PIC */ |
| 203 | cpm2_init_IRQ(); | 214 | cpm2_init_IRQ(); |
| @@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | |||
| 231 | * interrupt on slot */ | 242 | * interrupt on slot */ |
| 232 | { | 243 | { |
| 233 | { 0, 1, 2, 3 }, /* 16 - PMC */ | 244 | { 0, 1, 2, 3 }, /* 16 - PMC */ |
| 234 | { 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */ | 245 | { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ |
| 235 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ | 246 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ |
| 236 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ | 247 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ |
| 237 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ | 248 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ |
| @@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) | |||
| 280 | return PCIBIOS_DEVICE_NOT_FOUND; | 291 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 281 | #endif | 292 | #endif |
| 282 | /* We explicitly do not go past the Tundra 320 Bridge */ | 293 | /* We explicitly do not go past the Tundra 320 Bridge */ |
| 283 | if (bus == 1) | 294 | if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
| 284 | return PCIBIOS_DEVICE_NOT_FOUND; | 295 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 285 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | 296 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) |
| 286 | return PCIBIOS_DEVICE_NOT_FOUND; | 297 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 287 | else | 298 | else |
| 288 | return PCIBIOS_SUCCESSFUL; | 299 | return PCIBIOS_SUCCESSFUL; |
| 289 | } | 300 | } |
| 301 | |||
| 302 | void __init | ||
| 303 | mpc85xx_cds_enable_via(struct pci_controller *hose) | ||
| 304 | { | ||
| 305 | u32 pci_class; | ||
| 306 | u16 vid, did; | ||
| 307 | |||
| 308 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
| 309 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
| 310 | return; | ||
| 311 | |||
| 312 | /* Configure P2P so that we can reach bus 1 */ | ||
| 313 | early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0); | ||
| 314 | early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1); | ||
| 315 | early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff); | ||
| 316 | |||
| 317 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
| 318 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
| 319 | |||
| 320 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
| 321 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
| 322 | return; | ||
| 323 | |||
| 324 | /* Enable USB and IDE functions */ | ||
| 325 | early_write_config_byte(hose, 1, 0x10, 0x48, 0x08); | ||
| 326 | } | ||
| 327 | |||
| 328 | void __init | ||
| 329 | mpc85xx_cds_fixup_via(struct pci_controller *hose) | ||
| 330 | { | ||
| 331 | u32 pci_class; | ||
| 332 | u16 vid, did; | ||
| 333 | |||
| 334 | early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class); | ||
| 335 | if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI) | ||
| 336 | return; | ||
| 337 | |||
| 338 | /* | ||
| 339 | * Force the backplane P2P bridge to have a window | ||
| 340 | * open from 0x00000000-0x00001fff in PCI I/O space. | ||
| 341 | * This allows legacy I/O (i8259, etc) on the VIA | ||
| 342 | * southbridge to be accessed. | ||
| 343 | */ | ||
| 344 | early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00); | ||
| 345 | early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000); | ||
| 346 | early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10); | ||
| 347 | early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000); | ||
| 348 | |||
| 349 | early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid); | ||
| 350 | early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did); | ||
| 351 | if ((vid != PCI_VENDOR_ID_VIA) || | ||
| 352 | (did != PCI_DEVICE_ID_VIA_82C686)) | ||
| 353 | return; | ||
| 354 | |||
| 355 | /* | ||
| 356 | * Since the P2P window was forced to cover the fixed | ||
| 357 | * legacy I/O addresses, it is necessary to manually | ||
| 358 | * place the base addresses for the IDE and USB functions | ||
| 359 | * within this window. | ||
| 360 | */ | ||
| 361 | /* Function 1, IDE */ | ||
| 362 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8); | ||
| 363 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4); | ||
| 364 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8); | ||
| 365 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4); | ||
| 366 | early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0); | ||
| 367 | |||
| 368 | /* Function 2, USB ports 0-1 */ | ||
| 369 | early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0); | ||
| 370 | |||
| 371 | /* Function 3, USB ports 2-3 */ | ||
| 372 | early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80); | ||
| 373 | |||
| 374 | /* Function 5, Power Management */ | ||
| 375 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00); | ||
| 376 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc); | ||
| 377 | early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8); | ||
| 378 | |||
| 379 | /* Function 6, AC97 Interface */ | ||
| 380 | early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00); | ||
| 381 | } | ||
| 382 | |||
| 383 | void __init | ||
| 384 | mpc85xx_cds_pcibios_fixup(void) | ||
| 385 | { | ||
| 386 | struct pci_dev *dev = NULL; | ||
| 387 | u_char c; | ||
| 388 | |||
| 389 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
| 390 | PCI_DEVICE_ID_VIA_82C586_1, NULL))) { | ||
| 391 | /* | ||
| 392 | * U-Boot does not set the enable bits | ||
| 393 | * for the IDE device. Force them on here. | ||
| 394 | */ | ||
| 395 | pci_read_config_byte(dev, 0x40, &c); | ||
| 396 | c |= 0x03; /* IDE: Chip Enable Bits */ | ||
| 397 | pci_write_config_byte(dev, 0x40, c); | ||
| 398 | |||
| 399 | /* | ||
| 400 | * Since only primary interface works, force the | ||
| 401 | * IDE function to standard primary IDE interrupt | ||
| 402 | * w/ 8259 offset | ||
| 403 | */ | ||
| 404 | dev->irq = 14; | ||
| 405 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 409 | * Force legacy USB interrupt routing | ||
| 410 | */ | ||
| 411 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
| 412 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | ||
| 413 | dev->irq = 10; | ||
| 414 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | ||
| 415 | } | ||
| 416 | |||
| 417 | if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, | ||
| 418 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | ||
| 419 | dev->irq = 11; | ||
| 420 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | ||
| 421 | } | ||
| 422 | } | ||
| 290 | #endif /* CONFIG_PCI */ | 423 | #endif /* CONFIG_PCI */ |
| 291 | 424 | ||
| 292 | TODC_ALLOC(); | 425 | TODC_ALLOC(); |
| @@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void) | |||
| 328 | loops_per_jiffy = freq / HZ; | 461 | loops_per_jiffy = freq / HZ; |
| 329 | 462 | ||
| 330 | #ifdef CONFIG_PCI | 463 | #ifdef CONFIG_PCI |
| 464 | /* VIA IDE configuration */ | ||
| 465 | ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; | ||
| 466 | |||
| 331 | /* setup PCI host bridges */ | 467 | /* setup PCI host bridges */ |
| 332 | mpc85xx_setup_hose(); | 468 | mpc85xx_setup_hose(); |
| 333 | #endif | 469 | #endif |
| @@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 459 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 595 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
| 460 | ppc_md.progress = gen550_progress; | 596 | ppc_md.progress = gen550_progress; |
| 461 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 597 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
| 598 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
| 599 | ppc_md.early_serial_map = mpc85xx_early_serial_map; | ||
| 600 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
| 462 | 601 | ||
| 463 | if (ppc_md.progress) | 602 | if (ppc_md.progress) |
| 464 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); | 603 | ppc_md.progress("mpc85xx_cds_init(): exit", 0); |
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h index 7627d77504bd..12b292c6ae32 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h | |||
| @@ -77,4 +77,7 @@ | |||
| 77 | 77 | ||
| 78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 | 78 | #define MPC85XX_PCI2_IO_SIZE 0x01000000 |
| 79 | 79 | ||
| 80 | #define NR_8259_INTS 16 | ||
| 81 | #define CPM_IRQ_OFFSET NR_8259_INTS | ||
| 82 | |||
| 80 | #endif /* __MACH_MPC85XX_CDS_H__ */ | 83 | #endif /* __MACH_MPC85XX_CDS_H__ */ |
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 9ab05e590c3e..7b9e1543e175 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
| @@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) | 221 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) |
| 222 | ppc_md.progress = gen550_progress; | 222 | ppc_md.progress = gen550_progress; |
| 223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ | 223 | #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ |
| 224 | #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) | ||
| 225 | ppc_md.early_serial_map = sbc8560_early_serial_map; | ||
| 226 | #endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ | ||
| 224 | 227 | ||
| 225 | if (ppc_md.progress) | 228 | if (ppc_md.progress) |
| 226 | ppc_md.progress("sbc8560_init(): exit", 0); | 229 | ppc_md.progress("sbc8560_init(): exit", 0); |
diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index f7fb2786cd50..937f46df711e 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c | |||
| @@ -85,14 +85,11 @@ static int no_schedule; | |||
| 85 | static int has_cpu_l2lve; | 85 | static int has_cpu_l2lve; |
| 86 | 86 | ||
| 87 | 87 | ||
| 88 | #define PMAC_CPU_LOW_SPEED 1 | ||
| 89 | #define PMAC_CPU_HIGH_SPEED 0 | ||
| 90 | |||
| 91 | /* There are only two frequency states for each processor. Values | 88 | /* There are only two frequency states for each processor. Values |
| 92 | * are in kHz for the time being. | 89 | * are in kHz for the time being. |
| 93 | */ | 90 | */ |
| 94 | #define CPUFREQ_HIGH PMAC_CPU_HIGH_SPEED | 91 | #define CPUFREQ_HIGH 0 |
| 95 | #define CPUFREQ_LOW PMAC_CPU_LOW_SPEED | 92 | #define CPUFREQ_LOW 1 |
| 96 | 93 | ||
| 97 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | 94 | static struct cpufreq_frequency_table pmac_cpu_freqs[] = { |
| 98 | {CPUFREQ_HIGH, 0}, | 95 | {CPUFREQ_HIGH, 0}, |
| @@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = { | |||
| 100 | {0, CPUFREQ_TABLE_END}, | 97 | {0, CPUFREQ_TABLE_END}, |
| 101 | }; | 98 | }; |
| 102 | 99 | ||
| 100 | static struct freq_attr* pmac_cpu_freqs_attr[] = { | ||
| 101 | &cpufreq_freq_attr_scaling_available_freqs, | ||
| 102 | NULL, | ||
| 103 | }; | ||
| 104 | |||
| 103 | static inline void local_delay(unsigned long ms) | 105 | static inline void local_delay(unsigned long ms) |
| 104 | { | 106 | { |
| 105 | if (no_schedule) | 107 | if (no_schedule) |
| @@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
| 269 | #ifdef DEBUG_FREQ | 271 | #ifdef DEBUG_FREQ |
| 270 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 272 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); |
| 271 | #endif | 273 | #endif |
| 274 | pmu_suspend(); | ||
| 275 | |||
| 272 | /* Disable all interrupt sources on openpic */ | 276 | /* Disable all interrupt sources on openpic */ |
| 273 | pic_prio = openpic_get_priority(); | 277 | pic_prio = openpic_get_priority(); |
| 274 | openpic_set_priority(0xf); | 278 | openpic_set_priority(0xf); |
| @@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed) | |||
| 343 | debug_calc_bogomips(); | 347 | debug_calc_bogomips(); |
| 344 | #endif | 348 | #endif |
| 345 | 349 | ||
| 350 | pmu_resume(); | ||
| 351 | |||
| 346 | preempt_enable(); | 352 | preempt_enable(); |
| 347 | 353 | ||
| 348 | return 0; | 354 | return 0; |
| @@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
| 355 | static unsigned long prev_l3cr; | 361 | static unsigned long prev_l3cr; |
| 356 | 362 | ||
| 357 | freqs.old = cur_freq; | 363 | freqs.old = cur_freq; |
| 358 | freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 364 | freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
| 359 | freqs.cpu = smp_processor_id(); | 365 | freqs.cpu = smp_processor_id(); |
| 360 | 366 | ||
| 361 | if (freqs.old == freqs.new) | 367 | if (freqs.old == freqs.new) |
| @@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
| 363 | 369 | ||
| 364 | if (notify) | 370 | if (notify) |
| 365 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 371 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
| 366 | if (speed_mode == PMAC_CPU_LOW_SPEED && | 372 | if (speed_mode == CPUFREQ_LOW && |
| 367 | cpu_has_feature(CPU_FTR_L3CR)) { | 373 | cpu_has_feature(CPU_FTR_L3CR)) { |
| 368 | l3cr = _get_L3CR(); | 374 | l3cr = _get_L3CR(); |
| 369 | if (l3cr & L3CR_L3E) { | 375 | if (l3cr & L3CR_L3E) { |
| @@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
| 371 | _set_L3CR(0); | 377 | _set_L3CR(0); |
| 372 | } | 378 | } |
| 373 | } | 379 | } |
| 374 | set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED); | 380 | set_speed_proc(speed_mode == CPUFREQ_LOW); |
| 375 | if (speed_mode == PMAC_CPU_HIGH_SPEED && | 381 | if (speed_mode == CPUFREQ_HIGH && |
| 376 | cpu_has_feature(CPU_FTR_L3CR)) { | 382 | cpu_has_feature(CPU_FTR_L3CR)) { |
| 377 | l3cr = _get_L3CR(); | 383 | l3cr = _get_L3CR(); |
| 378 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) | 384 | if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr) |
| @@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify) | |||
| 380 | } | 386 | } |
| 381 | if (notify) | 387 | if (notify) |
| 382 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 388 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
| 383 | cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq; | 389 | cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq; |
| 384 | 390 | ||
| 385 | return 0; | 391 | return 0; |
| 386 | } | 392 | } |
| @@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
| 423 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | 429 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; |
| 424 | policy->cur = cur_freq; | 430 | policy->cur = cur_freq; |
| 425 | 431 | ||
| 426 | return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]); | 432 | cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu); |
| 433 | return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs); | ||
| 427 | } | 434 | } |
| 428 | 435 | ||
| 429 | static u32 __pmac read_gpio(struct device_node *np) | 436 | static u32 __pmac read_gpio(struct device_node *np) |
| @@ -457,7 +464,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) | |||
| 457 | no_schedule = 1; | 464 | no_schedule = 1; |
| 458 | sleep_freq = cur_freq; | 465 | sleep_freq = cur_freq; |
| 459 | if (cur_freq == low_freq) | 466 | if (cur_freq == low_freq) |
| 460 | do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0); | 467 | do_set_cpu_speed(CPUFREQ_HIGH, 0); |
| 461 | return 0; | 468 | return 0; |
| 462 | } | 469 | } |
| 463 | 470 | ||
| @@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy) | |||
| 473 | * is that we force a switch to whatever it was, which is | 480 | * is that we force a switch to whatever it was, which is |
| 474 | * probably high speed due to our suspend() routine | 481 | * probably high speed due to our suspend() routine |
| 475 | */ | 482 | */ |
| 476 | do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED | 483 | do_set_cpu_speed(sleep_freq == low_freq ? |
| 477 | : PMAC_CPU_HIGH_SPEED, 0); | 484 | CPUFREQ_LOW : CPUFREQ_HIGH, 0); |
| 478 | 485 | ||
| 479 | no_schedule = 0; | 486 | no_schedule = 0; |
| 480 | return 0; | 487 | return 0; |
| @@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = { | |||
| 488 | .suspend = pmac_cpufreq_suspend, | 495 | .suspend = pmac_cpufreq_suspend, |
| 489 | .resume = pmac_cpufreq_resume, | 496 | .resume = pmac_cpufreq_resume, |
| 490 | .flags = CPUFREQ_PM_NO_WARN, | 497 | .flags = CPUFREQ_PM_NO_WARN, |
| 498 | .attr = pmac_cpu_freqs_attr, | ||
| 491 | .name = "powermac", | 499 | .name = "powermac", |
| 492 | .owner = THIS_MODULE, | 500 | .owner = THIS_MODULE, |
| 493 | }; | 501 | }; |
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h index cf5e5dd06d63..067d9a5aebc1 100644 --- a/arch/ppc/platforms/pq2ads.h +++ b/arch/ppc/platforms/pq2ads.h | |||
| @@ -49,10 +49,10 @@ | |||
| 49 | /* PCI interrupt controller */ | 49 | /* PCI interrupt controller */ |
| 50 | #define PCI_INT_STAT_REG 0xF8200000 | 50 | #define PCI_INT_STAT_REG 0xF8200000 |
| 51 | #define PCI_INT_MASK_REG 0xF8200004 | 51 | #define PCI_INT_MASK_REG 0xF8200004 |
| 52 | #define PIRQA (NR_SIU_INTS + 0) | 52 | #define PIRQA (NR_CPM_INTS + 0) |
| 53 | #define PIRQB (NR_SIU_INTS + 1) | 53 | #define PIRQB (NR_CPM_INTS + 1) |
| 54 | #define PIRQC (NR_SIU_INTS + 2) | 54 | #define PIRQC (NR_CPM_INTS + 2) |
| 55 | #define PIRQD (NR_SIU_INTS + 3) | 55 | #define PIRQD (NR_CPM_INTS + 3) |
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| 58 | * PCI memory map definitions for MPC8266ADS-PCI. | 58 | * PCI memory map definitions for MPC8266ADS-PCI. |
| @@ -68,28 +68,23 @@ | |||
| 68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory | 68 | * 0x00000000-0x1FFFFFFF 0x00000000-0x1FFFFFFF MPC8266 local memory |
| 69 | */ | 69 | */ |
| 70 | 70 | ||
| 71 | /* window for a PCI master to access MPC8266 memory */ | 71 | /* All the other PCI memory map definitions reside at syslib/m82xx_pci.h |
| 72 | #define PCI_SLV_MEM_LOCAL 0x00000000 /* Local base */ | 72 | Here we should redefine what is unique for this board */ |
| 73 | #define PCI_SLV_MEM_BUS 0x00000000 /* PCI base */ | 73 | #define M82xx_PCI_SLAVE_MEM_LOCAL 0x00000000 /* Local base */ |
| 74 | #define M82xx_PCI_SLAVE_MEM_BUS 0x00000000 /* PCI base */ | ||
| 75 | #define M82xx_PCI_SLAVE_MEM_SIZE 0x10000000 /* 256 Mb */ | ||
| 74 | 76 | ||
| 75 | /* window for the processor to access PCI memory with prefetching */ | 77 | #define M82xx_PCI_SLAVE_SEC_WND_SIZE ~(0x40000000 - 1U) /* 2 x 512Mb */ |
| 76 | #define PCI_MSTR_MEM_LOCAL 0x80000000 /* Local base */ | 78 | #define M82xx_PCI_SLAVE_SEC_WND_BASE 0x80000000 /* PCI Memory base */ |
| 77 | #define PCI_MSTR_MEM_BUS 0x80000000 /* PCI base */ | ||
| 78 | #define PCI_MSTR_MEM_SIZE 0x20000000 /* 512MB */ | ||
| 79 | 79 | ||
| 80 | /* window for the processor to access PCI memory without prefetching */ | 80 | #if defined(CONFIG_ADS8272) |
| 81 | #define PCI_MSTR_MEMIO_LOCAL 0xA0000000 /* Local base */ | 81 | #define PCI_INT_TO_SIU SIU_INT_IRQ2 |
| 82 | #define PCI_MSTR_MEMIO_BUS 0xA0000000 /* PCI base */ | 82 | #elif defined(CONFIG_PQ2FADS) |
| 83 | #define PCI_MSTR_MEMIO_SIZE 0x20000000 /* 512MB */ | 83 | #define PCI_INT_TO_SIU SIU_INT_IRQ6 |
| 84 | #else | ||
| 85 | #warning PCI Bridge will be without interrupts support | ||
| 86 | #endif | ||
| 84 | 87 | ||
| 85 | /* window for the processor to access PCI I/O */ | ||
| 86 | #define PCI_MSTR_IO_LOCAL 0xF4000000 /* Local base */ | ||
| 87 | #define PCI_MSTR_IO_BUS 0x00000000 /* PCI base */ | ||
| 88 | #define PCI_MSTR_IO_SIZE 0x04000000 /* 64MB */ | ||
| 89 | |||
| 90 | #define _IO_BASE PCI_MSTR_IO_LOCAL | ||
| 91 | #define _ISA_MEM_BASE PCI_MSTR_MEMIO_LOCAL | ||
| 92 | #define PCI_DRAM_OFFSET PCI_SLV_MEM_BUS | ||
| 93 | #endif /* CONFIG_PCI */ | 88 | #endif /* CONFIG_PCI */ |
| 94 | 89 | ||
| 95 | #endif /* __MACH_ADS8260_DEFS */ | 90 | #endif /* __MACH_ADS8260_DEFS */ |
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index dd418ea3426c..96acf85800d4 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile | |||
| @@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx) += todc_time.o | |||
| 81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ | 81 | obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ |
| 82 | todc_time.o | 82 | todc_time.o |
| 83 | obj-$(CONFIG_8260) += m8260_setup.o | 83 | obj-$(CONFIG_8260) += m8260_setup.o |
| 84 | obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o | 84 | obj-$(CONFIG_PCI_8260) += m82xx_pci.o indirect_pci.o pci_auto.o |
| 85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o | 85 | obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o |
| 86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o | 86 | obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o |
| 87 | ifeq ($(CONFIG_PPC_GEN550),y) | 87 | ifeq ($(CONFIG_PPC_GEN550),y) |
| @@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC) += open_pic.o | |||
| 97 | obj-$(CONFIG_40x) += dcr.o | 97 | obj-$(CONFIG_40x) += dcr.o |
| 98 | obj-$(CONFIG_BOOKE) += dcr.o | 98 | obj-$(CONFIG_BOOKE) += dcr.o |
| 99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ | 99 | obj-$(CONFIG_85xx) += open_pic.o ppc85xx_common.o ppc85xx_setup.o \ |
| 100 | ppc_sys.o mpc85xx_sys.o \ | 100 | ppc_sys.o i8259.o mpc85xx_sys.o \ |
| 101 | mpc85xx_devices.o | 101 | mpc85xx_devices.o |
| 102 | ifeq ($(CONFIG_85xx),y) | 102 | ifeq ($(CONFIG_85xx),y) |
| 103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o | 103 | obj-$(CONFIG_PCI) += indirect_pci.o pci_auto.o |
diff --git a/arch/ppc/syslib/m8260_pci.c b/arch/ppc/syslib/m8260_pci.c deleted file mode 100644 index 057cc3f8ff37..000000000000 --- a/arch/ppc/syslib/m8260_pci.c +++ /dev/null | |||
| @@ -1,193 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * (C) Copyright 2003 | ||
| 3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
| 4 | * | ||
| 5 | * (C) Copyright 2004 Red Hat, Inc. | ||
| 6 | * | ||
| 7 | * See file CREDITS for list of people who contributed to this | ||
| 8 | * project. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License as | ||
| 12 | * published by the Free Software Foundation; either version 2 of | ||
| 13 | * the License, or (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
| 23 | * MA 02111-1307 USA | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/pci.h> | ||
| 29 | #include <linux/slab.h> | ||
| 30 | #include <linux/delay.h> | ||
| 31 | |||
| 32 | #include <asm/byteorder.h> | ||
| 33 | #include <asm/io.h> | ||
| 34 | #include <asm/irq.h> | ||
| 35 | #include <asm/uaccess.h> | ||
| 36 | #include <asm/machdep.h> | ||
| 37 | #include <asm/pci-bridge.h> | ||
| 38 | #include <asm/immap_cpm2.h> | ||
| 39 | #include <asm/mpc8260.h> | ||
| 40 | |||
| 41 | #include "m8260_pci.h" | ||
| 42 | |||
| 43 | |||
| 44 | /* PCI bus configuration registers. | ||
| 45 | */ | ||
| 46 | |||
| 47 | static void __init m8260_setup_pci(struct pci_controller *hose) | ||
| 48 | { | ||
| 49 | volatile cpm2_map_t *immap = cpm2_immr; | ||
| 50 | unsigned long pocmr; | ||
| 51 | u16 tempShort; | ||
| 52 | |||
| 53 | #ifndef CONFIG_ATC /* already done in U-Boot */ | ||
| 54 | /* | ||
| 55 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
| 56 | * and local bus for PCI (SIUMCR [LBPC]). | ||
| 57 | */ | ||
| 58 | immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000; | ||
| 59 | #endif | ||
| 60 | |||
| 61 | /* Make PCI lowest priority */ | ||
| 62 | /* Each 4 bits is a device bus request and the MS 4bits | ||
| 63 | is highest priority */ | ||
| 64 | /* Bus 4bit value | ||
| 65 | --- ---------- | ||
| 66 | CPM high 0b0000 | ||
| 67 | CPM middle 0b0001 | ||
| 68 | CPM low 0b0010 | ||
| 69 | PCI reguest 0b0011 | ||
| 70 | Reserved 0b0100 | ||
| 71 | Reserved 0b0101 | ||
| 72 | Internal Core 0b0110 | ||
| 73 | External Master 1 0b0111 | ||
| 74 | External Master 2 0b1000 | ||
| 75 | External Master 3 0b1001 | ||
| 76 | The rest are reserved */ | ||
| 77 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
| 78 | |||
| 79 | /* Park bus on core while modifying PCI Bus accesses */ | ||
| 80 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Set up master window that allows the CPU to access PCI space. This | ||
| 84 | * window is set up using the first SIU PCIBR registers. | ||
| 85 | */ | ||
| 86 | immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK; | ||
| 87 | immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE; | ||
| 88 | |||
| 89 | /* Disable machine check on no response or target abort */ | ||
| 90 | immap->im_pci.pci_emr = cpu_to_le32(0x1fe7); | ||
| 91 | /* Release PCI RST (by default the PCI RST signal is held low) */ | ||
| 92 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
| 93 | |||
| 94 | /* give it some time */ | ||
| 95 | mdelay(1); | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Set up master window that allows the CPU to access PCI Memory (prefetch) | ||
| 99 | * space. This window is set up using the first set of Outbound ATU registers. | ||
| 100 | */ | ||
| 101 | immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12); | ||
| 102 | immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12); | ||
| 103 | pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff; | ||
| 104 | immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN); | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Set up master window that allows the CPU to access PCI Memory (non-prefetch) | ||
| 108 | * space. This window is set up using the second set of Outbound ATU registers. | ||
| 109 | */ | ||
| 110 | immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12); | ||
| 111 | immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12); | ||
| 112 | pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff; | ||
| 113 | immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE); | ||
| 114 | |||
| 115 | /* | ||
| 116 | * Set up master window that allows the CPU to access PCI IO space. This window | ||
| 117 | * is set up using the third set of Outbound ATU registers. | ||
| 118 | */ | ||
| 119 | immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12); | ||
| 120 | immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12); | ||
| 121 | pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff; | ||
| 122 | immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * Set up slave window that allows PCI masters to access MPC826x local memory. | ||
| 126 | * This window is set up using the first set of Inbound ATU registers | ||
| 127 | */ | ||
| 128 | |||
| 129 | immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12); | ||
| 130 | immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12); | ||
| 131 | pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff; | ||
| 132 | immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN); | ||
| 133 | |||
| 134 | /* See above for description - puts PCI request as highest priority */ | ||
| 135 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
| 136 | |||
| 137 | /* Park the bus on the PCI */ | ||
| 138 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
| 139 | |||
| 140 | /* Host mode - specify the bridge as a host-PCI bridge */ | ||
| 141 | early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST); | ||
| 142 | |||
| 143 | /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ | ||
| 144 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort); | ||
| 145 | early_write_config_word(hose, 0, 0, PCI_COMMAND, | ||
| 146 | tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | ||
| 147 | } | ||
| 148 | |||
| 149 | void __init m8260_find_bridges(void) | ||
| 150 | { | ||
| 151 | extern int pci_assign_all_busses; | ||
| 152 | struct pci_controller * hose; | ||
| 153 | |||
| 154 | pci_assign_all_busses = 1; | ||
| 155 | |||
| 156 | hose = pcibios_alloc_controller(); | ||
| 157 | |||
| 158 | if (!hose) | ||
| 159 | return; | ||
| 160 | |||
| 161 | ppc_md.pci_swizzle = common_swizzle; | ||
| 162 | |||
| 163 | hose->first_busno = 0; | ||
| 164 | hose->bus_offset = 0; | ||
| 165 | hose->last_busno = 0xff; | ||
| 166 | |||
| 167 | setup_m8260_indirect_pci(hose, | ||
| 168 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
| 169 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
| 170 | |||
| 171 | m8260_setup_pci(hose); | ||
| 172 | hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; | ||
| 173 | |||
| 174 | hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE, | ||
| 175 | MPC826x_PCI_IO_SIZE); | ||
| 176 | isa_io_base = (unsigned long) hose->io_base_virt; | ||
| 177 | |||
| 178 | /* setup resources */ | ||
| 179 | pci_init_resource(&hose->mem_resources[0], | ||
| 180 | MPC826x_PCI_LOWER_MEM, | ||
| 181 | MPC826x_PCI_UPPER_MEM, | ||
| 182 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
| 183 | |||
| 184 | pci_init_resource(&hose->mem_resources[1], | ||
| 185 | MPC826x_PCI_LOWER_MMIO, | ||
| 186 | MPC826x_PCI_UPPER_MMIO, | ||
| 187 | IORESOURCE_MEM, "PCI memory"); | ||
| 188 | |||
| 189 | pci_init_resource(&hose->io_resource, | ||
| 190 | MPC826x_PCI_LOWER_IO, | ||
| 191 | MPC826x_PCI_UPPER_IO, | ||
| 192 | IORESOURCE_IO, "PCI I/O"); | ||
| 193 | } | ||
diff --git a/arch/ppc/syslib/m8260_pci.h b/arch/ppc/syslib/m8260_pci.h deleted file mode 100644 index d1352120acd7..000000000000 --- a/arch/ppc/syslib/m8260_pci.h +++ /dev/null | |||
| @@ -1,76 +0,0 @@ | |||
| 1 | |||
| 2 | #ifndef _PPC_KERNEL_M8260_PCI_H | ||
| 3 | #define _PPC_KERNEL_M8260_PCI_H | ||
| 4 | |||
| 5 | #include <asm/m8260_pci.h> | ||
| 6 | |||
| 7 | /* | ||
| 8 | * Local->PCI map (from CPU) controlled by | ||
| 9 | * MPC826x master window | ||
| 10 | * | ||
| 11 | * 0x80000000 - 0xBFFFFFFF Total CPU2PCI space PCIBR0 | ||
| 12 | * | ||
| 13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
| 14 | * 0xA0000000 - 0xAFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
| 15 | * 0xB0000000 - 0xB0FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
| 16 | * | ||
| 17 | * PCI->Local map (from PCI) | ||
| 18 | * MPC826x slave window controlled by | ||
| 19 | * | ||
| 20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
| 25 | * This window is set up using the first set of Inbound ATU registers | ||
| 26 | */ | ||
| 27 | |||
| 28 | #ifndef MPC826x_PCI_SLAVE_MEM_LOCAL | ||
| 29 | #define MPC826x_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
| 30 | #define MPC826x_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
| 31 | #define MPC826x_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | /* | ||
| 35 | * This is the window that allows the CPU to access PCI address space. | ||
| 36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
| 37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
| 38 | * and IO space (see below), must all fit within this window. | ||
| 39 | */ | ||
| 40 | #ifndef MPC826x_PCI_BASE | ||
| 41 | #define MPC826x_PCI_BASE 0x80000000 | ||
| 42 | #define MPC826x_PCI_MASK 0xc0000000 | ||
| 43 | #endif | ||
| 44 | |||
| 45 | #ifndef MPC826x_PCI_LOWER_MEM | ||
| 46 | #define MPC826x_PCI_LOWER_MEM 0x80000000 | ||
| 47 | #define MPC826x_PCI_UPPER_MEM 0x9fffffff | ||
| 48 | #define MPC826x_PCI_MEM_OFFSET 0x00000000 | ||
| 49 | #endif | ||
| 50 | |||
| 51 | #ifndef MPC826x_PCI_LOWER_MMIO | ||
| 52 | #define MPC826x_PCI_LOWER_MMIO 0xa0000000 | ||
| 53 | #define MPC826x_PCI_UPPER_MMIO 0xafffffff | ||
| 54 | #define MPC826x_PCI_MMIO_OFFSET 0x00000000 | ||
| 55 | #endif | ||
| 56 | |||
| 57 | #ifndef MPC826x_PCI_LOWER_IO | ||
| 58 | #define MPC826x_PCI_LOWER_IO 0x00000000 | ||
| 59 | #define MPC826x_PCI_UPPER_IO 0x00ffffff | ||
| 60 | #define MPC826x_PCI_IO_BASE 0xb0000000 | ||
| 61 | #define MPC826x_PCI_IO_SIZE 0x01000000 | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifndef _IO_BASE | ||
| 65 | #define _IO_BASE isa_io_base | ||
| 66 | #endif | ||
| 67 | |||
| 68 | #ifdef CONFIG_8260_PCI9 | ||
| 69 | struct pci_controller; | ||
| 70 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
| 71 | u32 cfg_addr, u32 cfg_data); | ||
| 72 | #else | ||
| 73 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
| 74 | #endif | ||
| 75 | |||
| 76 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c index 9c0582d639e0..1dc7e4e1d491 100644 --- a/arch/ppc/syslib/m8260_pci_erratum9.c +++ b/arch/ppc/syslib/m8260_pci_erratum9.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <asm/immap_cpm2.h> | 31 | #include <asm/immap_cpm2.h> |
| 32 | #include <asm/cpm2.h> | 32 | #include <asm/cpm2.h> |
| 33 | 33 | ||
| 34 | #include "m8260_pci.h" | 34 | #include "m82xx_pci.h" |
| 35 | 35 | ||
| 36 | #ifdef CONFIG_8260_PCI9 | 36 | #ifdef CONFIG_8260_PCI9 |
| 37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ | 37 | /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */ |
| @@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le); | |||
| 248 | 248 | ||
| 249 | static inline int is_pci_mem(unsigned long addr) | 249 | static inline int is_pci_mem(unsigned long addr) |
| 250 | { | 250 | { |
| 251 | if (addr >= MPC826x_PCI_LOWER_MMIO && | 251 | if (addr >= M82xx_PCI_LOWER_MMIO && |
| 252 | addr <= MPC826x_PCI_UPPER_MMIO) | 252 | addr <= M82xx_PCI_UPPER_MMIO) |
| 253 | return 1; | 253 | return 1; |
| 254 | if (addr >= MPC826x_PCI_LOWER_MEM && | 254 | if (addr >= M82xx_PCI_LOWER_MEM && |
| 255 | addr <= MPC826x_PCI_UPPER_MEM) | 255 | addr <= M82xx_PCI_UPPER_MEM) |
| 256 | return 1; | 256 | return 1; |
| 257 | return 0; | 257 | return 0; |
| 258 | } | 258 | } |
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c index 23ea3f694de2..fda75d79050c 100644 --- a/arch/ppc/syslib/m8260_setup.c +++ b/arch/ppc/syslib/m8260_setup.c | |||
| @@ -34,7 +34,8 @@ | |||
| 34 | unsigned char __res[sizeof(bd_t)]; | 34 | unsigned char __res[sizeof(bd_t)]; |
| 35 | 35 | ||
| 36 | extern void cpm2_reset(void); | 36 | extern void cpm2_reset(void); |
| 37 | extern void m8260_find_bridges(void); | 37 | extern void pq2_find_bridges(void); |
| 38 | extern void pq2pci_init_irq(void); | ||
| 38 | extern void idma_pci9_init(void); | 39 | extern void idma_pci9_init(void); |
| 39 | 40 | ||
| 40 | /* Place-holder for board-specific init */ | 41 | /* Place-holder for board-specific init */ |
| @@ -56,7 +57,7 @@ m8260_setup_arch(void) | |||
| 56 | idma_pci9_init(); | 57 | idma_pci9_init(); |
| 57 | #endif | 58 | #endif |
| 58 | #ifdef CONFIG_PCI_8260 | 59 | #ifdef CONFIG_PCI_8260 |
| 59 | m8260_find_bridges(); | 60 | pq2_find_bridges(); |
| 60 | #endif | 61 | #endif |
| 61 | #ifdef CONFIG_BLK_DEV_INITRD | 62 | #ifdef CONFIG_BLK_DEV_INITRD |
| 62 | if (initrd_start) | 63 | if (initrd_start) |
| @@ -173,6 +174,12 @@ m8260_init_IRQ(void) | |||
| 173 | * in case the boot rom changed something on us. | 174 | * in case the boot rom changed something on us. |
| 174 | */ | 175 | */ |
| 175 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; | 176 | cpm2_immr->im_intctl.ic_siprr = 0x05309770; |
| 177 | |||
| 178 | #if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS)) | ||
| 179 | /* Initialize stuff for the 82xx CPLD IC and install demux */ | ||
| 180 | pq2pci_init_irq(); | ||
| 181 | #endif | ||
| 182 | |||
| 176 | } | 183 | } |
| 177 | 184 | ||
| 178 | /* | 185 | /* |
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c new file mode 100644 index 000000000000..5e7a7edcea74 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.c | |||
| @@ -0,0 +1,383 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * (C) Copyright 2003 | ||
| 4 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | ||
| 5 | * | ||
| 6 | * (C) Copyright 2004 Red Hat, Inc. | ||
| 7 | * | ||
| 8 | * 2005 (c) MontaVista Software, Inc. | ||
| 9 | * Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 10 | * | ||
| 11 | * See file CREDITS for list of people who contributed to this | ||
| 12 | * project. | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or | ||
| 15 | * modify it under the terms of the GNU General Public License as | ||
| 16 | * published by the Free Software Foundation; either version 2 of | ||
| 17 | * the License, or (at your option) any later version. | ||
| 18 | * | ||
| 19 | * This program is distributed in the hope that it will be useful, | ||
| 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 22 | * GNU General Public License for more details. | ||
| 23 | * | ||
| 24 | * You should have received a copy of the GNU General Public License | ||
| 25 | * along with this program; if not, write to the Free Software | ||
| 26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
| 27 | * MA 02111-1307 USA | ||
| 28 | */ | ||
| 29 | |||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/init.h> | ||
| 32 | #include <linux/pci.h> | ||
| 33 | #include <linux/slab.h> | ||
| 34 | #include <linux/delay.h> | ||
| 35 | #include <linux/irq.h> | ||
| 36 | #include <linux/interrupt.h> | ||
| 37 | |||
| 38 | #include <asm/byteorder.h> | ||
| 39 | #include <asm/io.h> | ||
| 40 | #include <asm/irq.h> | ||
| 41 | #include <asm/uaccess.h> | ||
| 42 | #include <asm/machdep.h> | ||
| 43 | #include <asm/pci-bridge.h> | ||
| 44 | #include <asm/immap_cpm2.h> | ||
| 45 | #include <asm/mpc8260.h> | ||
| 46 | #include <asm/cpm2.h> | ||
| 47 | |||
| 48 | #include "m82xx_pci.h" | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Interrupt routing | ||
| 52 | */ | ||
| 53 | |||
| 54 | static inline int | ||
| 55 | pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
| 56 | { | ||
| 57 | static char pci_irq_table[][4] = | ||
| 58 | /* | ||
| 59 | * PCI IDSEL/INTPIN->INTLINE | ||
| 60 | * A B C D | ||
| 61 | */ | ||
| 62 | { | ||
| 63 | { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */ | ||
| 64 | { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */ | ||
| 65 | { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */ | ||
| 66 | }; | ||
| 67 | |||
| 68 | const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4; | ||
| 69 | return PCI_IRQ_TABLE_LOOKUP; | ||
| 70 | } | ||
| 71 | |||
| 72 | static void | ||
| 73 | pq2pci_mask_irq(unsigned int irq) | ||
| 74 | { | ||
| 75 | int bit = irq - NR_CPM_INTS; | ||
| 76 | |||
| 77 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
| 78 | return; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void | ||
| 82 | pq2pci_unmask_irq(unsigned int irq) | ||
| 83 | { | ||
| 84 | int bit = irq - NR_CPM_INTS; | ||
| 85 | |||
| 86 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | static void | ||
| 91 | pq2pci_mask_and_ack(unsigned int irq) | ||
| 92 | { | ||
| 93 | int bit = irq - NR_CPM_INTS; | ||
| 94 | |||
| 95 | *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit)); | ||
| 96 | return; | ||
| 97 | } | ||
| 98 | |||
| 99 | static void | ||
| 100 | pq2pci_end_irq(unsigned int irq) | ||
| 101 | { | ||
| 102 | int bit = irq - NR_CPM_INTS; | ||
| 103 | |||
| 104 | *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit)); | ||
| 105 | return; | ||
| 106 | } | ||
| 107 | |||
| 108 | struct hw_interrupt_type pq2pci_ic = { | ||
| 109 | "PQ2 PCI", | ||
| 110 | NULL, | ||
| 111 | NULL, | ||
| 112 | pq2pci_unmask_irq, | ||
| 113 | pq2pci_mask_irq, | ||
| 114 | pq2pci_mask_and_ack, | ||
| 115 | pq2pci_end_irq, | ||
| 116 | 0 | ||
| 117 | }; | ||
| 118 | |||
| 119 | static irqreturn_t | ||
| 120 | pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs) | ||
| 121 | { | ||
| 122 | unsigned long stat, mask, pend; | ||
| 123 | int bit; | ||
| 124 | |||
| 125 | for(;;) { | ||
| 126 | stat = *(volatile unsigned long *) PCI_INT_STAT_REG; | ||
| 127 | mask = *(volatile unsigned long *) PCI_INT_MASK_REG; | ||
| 128 | pend = stat & ~mask & 0xf0000000; | ||
| 129 | if (!pend) | ||
| 130 | break; | ||
| 131 | for (bit = 0; pend != 0; ++bit, pend <<= 1) { | ||
| 132 | if (pend & 0x80000000) | ||
| 133 | __do_IRQ(NR_CPM_INTS + bit, regs); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | return IRQ_HANDLED; | ||
| 138 | } | ||
| 139 | |||
| 140 | static struct irqaction pq2pci_irqaction = { | ||
| 141 | .handler = pq2pci_irq_demux, | ||
| 142 | .flags = SA_INTERRUPT, | ||
| 143 | .mask = CPU_MASK_NONE, | ||
| 144 | .name = "PQ2 PCI cascade", | ||
| 145 | }; | ||
| 146 | |||
| 147 | |||
| 148 | void | ||
| 149 | pq2pci_init_irq(void) | ||
| 150 | { | ||
| 151 | int irq; | ||
| 152 | volatile cpm2_map_t *immap = cpm2_immr; | ||
| 153 | #if defined CONFIG_ADS8272 | ||
| 154 | /* configure chip select for PCI interrupt controller */ | ||
| 155 | immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801; | ||
| 156 | immap->im_memctl.memc_or3 = 0xffff8010; | ||
| 157 | #elif defined CONFIG_PQ2FADS | ||
| 158 | immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801; | ||
| 159 | immap->im_memctl.memc_or8 = 0xffff8010; | ||
| 160 | #endif | ||
| 161 | for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) | ||
| 162 | irq_desc[irq].handler = &pq2pci_ic; | ||
| 163 | |||
| 164 | /* make PCI IRQ level sensitive */ | ||
| 165 | immap->im_intctl.ic_siexr &= | ||
| 166 | ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1))); | ||
| 167 | |||
| 168 | /* mask all PCI interrupts */ | ||
| 169 | *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000; | ||
| 170 | |||
| 171 | /* install the demultiplexer for the PCI cascade interrupt */ | ||
| 172 | setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction); | ||
| 173 | return; | ||
| 174 | } | ||
| 175 | |||
| 176 | static int | ||
| 177 | pq2pci_exclude_device(u_char bus, u_char devfn) | ||
| 178 | { | ||
| 179 | return PCIBIOS_SUCCESSFUL; | ||
| 180 | } | ||
| 181 | |||
| 182 | /* PCI bus configuration registers. | ||
| 183 | */ | ||
| 184 | static void | ||
| 185 | pq2ads_setup_pci(struct pci_controller *hose) | ||
| 186 | { | ||
| 187 | __u32 val; | ||
| 188 | volatile cpm2_map_t *immap = cpm2_immr; | ||
| 189 | bd_t* binfo = (bd_t*) __res; | ||
| 190 | u32 sccr = immap->im_clkrst.car_sccr; | ||
| 191 | uint pci_div,freq,time; | ||
| 192 | /* PCI int lowest prio */ | ||
| 193 | /* Each 4 bits is a device bus request and the MS 4bits | ||
| 194 | is highest priority */ | ||
| 195 | /* Bus 4bit value | ||
| 196 | --- ---------- | ||
| 197 | CPM high 0b0000 | ||
| 198 | CPM middle 0b0001 | ||
| 199 | CPM low 0b0010 | ||
| 200 | PCI reguest 0b0011 | ||
| 201 | Reserved 0b0100 | ||
| 202 | Reserved 0b0101 | ||
| 203 | Internal Core 0b0110 | ||
| 204 | External Master 1 0b0111 | ||
| 205 | External Master 2 0b1000 | ||
| 206 | External Master 3 0b1001 | ||
| 207 | The rest are reserved | ||
| 208 | */ | ||
| 209 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | ||
| 210 | /* park bus on core */ | ||
| 211 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE; | ||
| 212 | /* | ||
| 213 | * Set up master windows that allow the CPU to access PCI space. These | ||
| 214 | * windows are set up using the two SIU PCIBR registers. | ||
| 215 | */ | ||
| 216 | |||
| 217 | immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE; | ||
| 218 | immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE; | ||
| 219 | |||
| 220 | #ifdef M82xx_PCI_SEC_WND_SIZE | ||
| 221 | immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE; | ||
| 222 | immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE; | ||
| 223 | #endif | ||
| 224 | |||
| 225 | #if defined CONFIG_ADS8272 | ||
| 226 | immap->im_siu_conf.siu_82xx.sc_siumcr = | ||
| 227 | (immap->im_siu_conf.siu_82xx.sc_siumcr & | ||
| 228 | ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE | | ||
| 229 | SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 | | ||
| 230 | SIUMCR_LBPC11 | SIUMCR_APPC11 | | ||
| 231 | SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) | | ||
| 232 | SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 | | ||
| 233 | SIUMCR_APPC10 | SIUMCR_CS10PC00 | | ||
| 234 | SIUMCR_BCTLC00 | SIUMCR_MMR11 ; | ||
| 235 | |||
| 236 | #elif defined CONFIG_PQ2FADS | ||
| 237 | /* | ||
| 238 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | ||
| 239 | * and local bus for PCI (SIUMCR [LBPC]). | ||
| 240 | */ | ||
| 241 | immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr & | ||
| 242 | ~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) | | ||
| 243 | SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10; | ||
| 244 | #endif | ||
| 245 | /* Enable PCI */ | ||
| 246 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | ||
| 247 | |||
| 248 | pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) * | ||
| 249 | ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1); | ||
| 250 | freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div)); | ||
| 251 | time = (int)666666/freq; | ||
| 252 | /* due to PCI Local Bus spec, some devices needs to wait such a long | ||
| 253 | time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */ | ||
| 254 | printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq, | ||
| 255 | (time==1) ? "0.5 seconds":"1 second" ); | ||
| 256 | |||
| 257 | { | ||
| 258 | int i; | ||
| 259 | for(i=0;i<(500*time);i++) | ||
| 260 | udelay(1000); | ||
| 261 | } | ||
| 262 | |||
| 263 | /* setup ATU registers */ | ||
| 264 | immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO | | ||
| 265 | ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT)); | ||
| 266 | immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT); | ||
| 267 | immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT); | ||
| 268 | |||
| 269 | /* Set-up non-prefetchable window */ | ||
| 270 | immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT)); | ||
| 271 | immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT); | ||
| 272 | immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT); | ||
| 273 | |||
| 274 | /* Set-up prefetchable window */ | ||
| 275 | immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN | | ||
| 276 | (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT)); | ||
| 277 | immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT); | ||
| 278 | immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT); | ||
| 279 | |||
| 280 | /* Inbound transactions from PCI memory space */ | ||
| 281 | immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN | | ||
| 282 | ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT)); | ||
| 283 | immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT); | ||
| 284 | immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT); | ||
| 285 | |||
| 286 | #if defined CONFIG_ADS8272 | ||
| 287 | /* PCI int highest prio */ | ||
| 288 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745; | ||
| 289 | #elif defined CONFIG_PQ2FADS | ||
| 290 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | ||
| 291 | #endif | ||
| 292 | /* park bus on PCI */ | ||
| 293 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | ||
| 294 | |||
| 295 | /* Enable bus mastering and inbound memory transactions */ | ||
| 296 | early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val); | ||
| 297 | val &= 0xffff0000; | ||
| 298 | val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER; | ||
| 299 | early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val); | ||
| 300 | |||
| 301 | } | ||
| 302 | |||
| 303 | void __init pq2_find_bridges(void) | ||
| 304 | { | ||
| 305 | extern int pci_assign_all_busses; | ||
| 306 | struct pci_controller * hose; | ||
| 307 | int host_bridge; | ||
| 308 | |||
| 309 | pci_assign_all_busses = 1; | ||
| 310 | |||
| 311 | hose = pcibios_alloc_controller(); | ||
| 312 | |||
| 313 | if (!hose) | ||
| 314 | return; | ||
| 315 | |||
| 316 | ppc_md.pci_swizzle = common_swizzle; | ||
| 317 | |||
| 318 | hose->first_busno = 0; | ||
| 319 | hose->bus_offset = 0; | ||
| 320 | hose->last_busno = 0xff; | ||
| 321 | |||
| 322 | #ifdef CONFIG_ADS8272 | ||
| 323 | hose->set_cfg_type = 1; | ||
| 324 | #endif | ||
| 325 | |||
| 326 | setup_m8260_indirect_pci(hose, | ||
| 327 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | ||
| 328 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | ||
| 329 | |||
| 330 | /* Make sure it is a supported bridge */ | ||
| 331 | early_read_config_dword(hose, | ||
| 332 | 0, | ||
| 333 | PCI_DEVFN(0,0), | ||
| 334 | PCI_VENDOR_ID, | ||
| 335 | &host_bridge); | ||
| 336 | switch (host_bridge) { | ||
| 337 | case PCI_DEVICE_ID_MPC8265: | ||
| 338 | break; | ||
| 339 | case PCI_DEVICE_ID_MPC8272: | ||
| 340 | break; | ||
| 341 | default: | ||
| 342 | printk("Attempting to use unrecognized host bridge ID" | ||
| 343 | " 0x%08x.\n", host_bridge); | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | |||
| 347 | pq2ads_setup_pci(hose); | ||
| 348 | |||
| 349 | hose->io_space.start = M82xx_PCI_LOWER_IO; | ||
| 350 | hose->io_space.end = M82xx_PCI_UPPER_IO; | ||
| 351 | hose->mem_space.start = M82xx_PCI_LOWER_MEM; | ||
| 352 | hose->mem_space.end = M82xx_PCI_UPPER_MMIO; | ||
| 353 | hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET; | ||
| 354 | |||
| 355 | isa_io_base = | ||
| 356 | (unsigned long) ioremap(M82xx_PCI_IO_BASE, | ||
| 357 | M82xx_PCI_IO_SIZE); | ||
| 358 | hose->io_base_virt = (void *) isa_io_base; | ||
| 359 | |||
| 360 | /* setup resources */ | ||
| 361 | pci_init_resource(&hose->mem_resources[0], | ||
| 362 | M82xx_PCI_LOWER_MEM, | ||
| 363 | M82xx_PCI_UPPER_MEM, | ||
| 364 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | ||
| 365 | |||
| 366 | pci_init_resource(&hose->mem_resources[1], | ||
| 367 | M82xx_PCI_LOWER_MMIO, | ||
| 368 | M82xx_PCI_UPPER_MMIO, | ||
| 369 | IORESOURCE_MEM, "PCI memory"); | ||
| 370 | |||
| 371 | pci_init_resource(&hose->io_resource, | ||
| 372 | M82xx_PCI_LOWER_IO, | ||
| 373 | M82xx_PCI_UPPER_IO, | ||
| 374 | IORESOURCE_IO | 1, "PCI I/O"); | ||
| 375 | |||
| 376 | ppc_md.pci_exclude_device = pq2pci_exclude_device; | ||
| 377 | hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); | ||
| 378 | |||
| 379 | ppc_md.pci_map_irq = pq2pci_map_irq; | ||
| 380 | ppc_md.pcibios_fixup = NULL; | ||
| 381 | ppc_md.pcibios_fixup_bus = NULL; | ||
| 382 | |||
| 383 | } | ||
diff --git a/arch/ppc/syslib/m82xx_pci.h b/arch/ppc/syslib/m82xx_pci.h new file mode 100644 index 000000000000..924f73f8e595 --- /dev/null +++ b/arch/ppc/syslib/m82xx_pci.h | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | |||
| 2 | #ifndef _PPC_KERNEL_M82XX_PCI_H | ||
| 3 | #define _PPC_KERNEL_M82XX_PCI_H | ||
| 4 | |||
| 5 | #include <asm/m8260_pci.h> | ||
| 6 | /* | ||
| 7 | * Local->PCI map (from CPU) controlled by | ||
| 8 | * MPC826x master window | ||
| 9 | * | ||
| 10 | * 0xF6000000 - 0xF7FFFFFF IO space | ||
| 11 | * 0x80000000 - 0xBFFFFFFF CPU2PCI memory space PCIBR0 | ||
| 12 | * | ||
| 13 | * 0x80000000 - 0x9FFFFFFF PCI Mem with prefetch (Outbound ATU #1) | ||
| 14 | * 0xA0000000 - 0xBFFFFFFF PCI Mem w/o prefetch (Outbound ATU #2) | ||
| 15 | * 0xF6000000 - 0xF7FFFFFF 32-bit PCI IO (Outbound ATU #3) | ||
| 16 | * | ||
| 17 | * PCI->Local map (from PCI) | ||
| 18 | * MPC826x slave window controlled by | ||
| 19 | * | ||
| 20 | * 0x00000000 - 0x07FFFFFF MPC826x local memory (Inbound ATU #1) | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Slave window that allows PCI masters to access MPC826x local memory. | ||
| 25 | * This window is set up using the first set of Inbound ATU registers | ||
| 26 | */ | ||
| 27 | |||
| 28 | #ifndef M82xx_PCI_SLAVE_MEM_LOCAL | ||
| 29 | #define M82xx_PCI_SLAVE_MEM_LOCAL (((struct bd_info *)__res)->bi_memstart) | ||
| 30 | #define M82xx_PCI_SLAVE_MEM_BUS (((struct bd_info *)__res)->bi_memstart) | ||
| 31 | #define M82xx_PCI_SLAVE_MEM_SIZE (((struct bd_info *)__res)->bi_memsize) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | /* | ||
| 35 | * This is the window that allows the CPU to access PCI address space. | ||
| 36 | * It will be setup with the SIU PCIBR0 register. All three PCI master | ||
| 37 | * windows, which allow the CPU to access PCI prefetch, non prefetch, | ||
| 38 | * and IO space (see below), must all fit within this window. | ||
| 39 | */ | ||
| 40 | |||
| 41 | #ifndef M82xx_PCI_LOWER_MEM | ||
| 42 | #define M82xx_PCI_LOWER_MEM 0x80000000 | ||
| 43 | #define M82xx_PCI_UPPER_MEM 0x9fffffff | ||
| 44 | #define M82xx_PCI_MEM_OFFSET 0x00000000 | ||
| 45 | #define M82xx_PCI_MEM_SIZE 0x20000000 | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #ifndef M82xx_PCI_LOWER_MMIO | ||
| 49 | #define M82xx_PCI_LOWER_MMIO 0xa0000000 | ||
| 50 | #define M82xx_PCI_UPPER_MMIO 0xafffffff | ||
| 51 | #define M82xx_PCI_MMIO_OFFSET 0x00000000 | ||
| 52 | #define M82xx_PCI_MMIO_SIZE 0x20000000 | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #ifndef M82xx_PCI_LOWER_IO | ||
| 56 | #define M82xx_PCI_LOWER_IO 0x00000000 | ||
| 57 | #define M82xx_PCI_UPPER_IO 0x01ffffff | ||
| 58 | #define M82xx_PCI_IO_BASE 0xf6000000 | ||
| 59 | #define M82xx_PCI_IO_SIZE 0x02000000 | ||
| 60 | #endif | ||
| 61 | |||
| 62 | #ifndef M82xx_PCI_PRIM_WND_SIZE | ||
| 63 | #define M82xx_PCI_PRIM_WND_SIZE ~(M82xx_PCI_IO_SIZE - 1U) | ||
| 64 | #define M82xx_PCI_PRIM_WND_BASE (M82xx_PCI_IO_BASE) | ||
| 65 | #endif | ||
| 66 | |||
| 67 | #ifndef M82xx_PCI_SEC_WND_SIZE | ||
| 68 | #define M82xx_PCI_SEC_WND_SIZE ~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U) | ||
| 69 | #define M82xx_PCI_SEC_WND_BASE (M82xx_PCI_LOWER_MEM) | ||
| 70 | #endif | ||
| 71 | |||
| 72 | #ifndef POTA_ADDR_SHIFT | ||
| 73 | #define POTA_ADDR_SHIFT 12 | ||
| 74 | #endif | ||
| 75 | |||
| 76 | #ifndef PITA_ADDR_SHIFT | ||
| 77 | #define PITA_ADDR_SHIFT 12 | ||
| 78 | #endif | ||
| 79 | |||
| 80 | #ifndef _IO_BASE | ||
| 81 | #define _IO_BASE isa_io_base | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #ifdef CONFIG_8260_PCI9 | ||
| 85 | struct pci_controller; | ||
| 86 | extern void setup_m8260_indirect_pci(struct pci_controller* hose, | ||
| 87 | u32 cfg_addr, u32 cfg_data); | ||
| 88 | #else | ||
| 89 | #define setup_m8260_indirect_pci setup_indirect_pci | ||
| 90 | #endif | ||
| 91 | |||
| 92 | #endif /* _PPC_KERNEL_M8260_PCI_H */ | ||
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 9d4ed68b5804..000ba47c67cb 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
| @@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void) | |||
| 275 | } | 275 | } |
| 276 | #endif | 276 | #endif |
| 277 | 277 | ||
| 278 | #if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM) | 278 | #if defined(CONFIG_EPIC_SERIAL_MODE) |
| 279 | static void openpic_reset(void) | 279 | static void openpic_reset(void) |
| 280 | { | 280 | { |
| 281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, | 281 | openpic_setfield(&OpenPIC->Global.Global_Configuration0, |
| @@ -993,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev) | |||
| 993 | return 0; | 993 | return 0; |
| 994 | } | 994 | } |
| 995 | 995 | ||
| 996 | openpic_reset(); | ||
| 997 | |||
| 998 | /* OpenPIC sometimes seem to need some time to be fully back up... */ | 996 | /* OpenPIC sometimes seem to need some time to be fully back up... */ |
| 999 | do { | 997 | do { |
| 1000 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); | 998 | openpic_set_spurious(OPENPIC_VEC_SPURIOUS); |
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index c28f9d679484..843cf8873e60 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <asm/mmu.h> | 29 | #include <asm/mmu.h> |
| 30 | #include <asm/ppc_sys.h> | 30 | #include <asm/ppc_sys.h> |
| 31 | #include <asm/kgdb.h> | 31 | #include <asm/kgdb.h> |
| 32 | #include <asm/delay.h> | ||
| 32 | 33 | ||
| 33 | #include <syslib/ppc83xx_setup.h> | 34 | #include <syslib/ppc83xx_setup.h> |
| 34 | 35 | ||
| @@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void) | |||
| 117 | void | 118 | void |
| 118 | mpc83xx_restart(char *cmd) | 119 | mpc83xx_restart(char *cmd) |
| 119 | { | 120 | { |
| 121 | volatile unsigned char __iomem *reg; | ||
| 122 | unsigned char tmp; | ||
| 123 | |||
| 124 | reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE); | ||
| 125 | |||
| 120 | local_irq_disable(); | 126 | local_irq_disable(); |
| 127 | |||
| 128 | /* | ||
| 129 | * Unlock the BCSR bits so a PRST will update the contents. | ||
| 130 | * Otherwise the reset asserts but doesn't clear. | ||
| 131 | */ | ||
| 132 | tmp = in_8(reg + BCSR_MISC_REG3_OFF); | ||
| 133 | tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */ | ||
| 134 | out_8(reg + BCSR_MISC_REG3_OFF, tmp); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Trigger a reset via a low->high transition of the | ||
| 138 | * PORESET bit. | ||
| 139 | */ | ||
| 140 | tmp = in_8(reg + BCSR_MISC_REG2_OFF); | ||
| 141 | tmp &= ~BCSR_MISC_REG2_PORESET; | ||
| 142 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
| 143 | |||
| 144 | udelay(1); | ||
| 145 | |||
| 146 | tmp |= BCSR_MISC_REG2_PORESET; | ||
| 147 | out_8(reg + BCSR_MISC_REG2_OFF, tmp); | ||
| 148 | |||
| 121 | for(;;); | 149 | for(;;); |
| 122 | } | 150 | } |
| 123 | 151 | ||
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 152c3ef1312a..f3277f469e78 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c | |||
| @@ -132,6 +132,12 @@ mpc85xx_halt(void) | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | #ifdef CONFIG_PCI | 134 | #ifdef CONFIG_PCI |
| 135 | |||
| 136 | #if defined(CONFIG_MPC8555_CDS) | ||
| 137 | extern void mpc85xx_cds_enable_via(struct pci_controller *hose); | ||
| 138 | extern void mpc85xx_cds_fixup_via(struct pci_controller *hose); | ||
| 139 | #endif | ||
| 140 | |||
| 135 | static void __init | 141 | static void __init |
| 136 | mpc85xx_setup_pci1(struct pci_controller *hose) | 142 | mpc85xx_setup_pci1(struct pci_controller *hose) |
| 137 | { | 143 | { |
| @@ -302,8 +308,18 @@ mpc85xx_setup_hose(void) | |||
| 302 | 308 | ||
| 303 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | 309 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; |
| 304 | 310 | ||
| 311 | #if defined(CONFIG_MPC8555_CDS) | ||
| 312 | /* Pre pciauto_bus_scan VIA init */ | ||
| 313 | mpc85xx_cds_enable_via(hose_a); | ||
| 314 | #endif | ||
| 315 | |||
| 305 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); | 316 | hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); |
| 306 | 317 | ||
| 318 | #if defined(CONFIG_MPC8555_CDS) | ||
| 319 | /* Post pciauto_bus_scan VIA fixup */ | ||
| 320 | mpc85xx_cds_fixup_via(hose_a); | ||
| 321 | #endif | ||
| 322 | |||
| 307 | #ifdef CONFIG_85xx_PCI2 | 323 | #ifdef CONFIG_85xx_PCI2 |
| 308 | hose_b = pcibios_alloc_controller(); | 324 | hose_b = pcibios_alloc_controller(); |
| 309 | 325 | ||
diff --git a/arch/ppc/syslib/prom_init.c b/arch/ppc/syslib/prom_init.c index 2cee87137f2e..7f15136830f4 100644 --- a/arch/ppc/syslib/prom_init.c +++ b/arch/ppc/syslib/prom_init.c | |||
| @@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad, | |||
| 626 | l = call_prom("package-to-path", 3, 1, node, | 626 | l = call_prom("package-to-path", 3, 1, node, |
| 627 | mem_start, mem_end - mem_start); | 627 | mem_start, mem_end - mem_start); |
| 628 | if (l >= 0) { | 628 | if (l >= 0) { |
| 629 | char *p, *ep; | ||
| 630 | |||
| 629 | np->full_name = PTRUNRELOC((char *) mem_start); | 631 | np->full_name = PTRUNRELOC((char *) mem_start); |
| 630 | *(char *)(mem_start + l) = 0; | 632 | *(char *)(mem_start + l) = 0; |
| 633 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
| 634 | * middle of the path in some properties | ||
| 635 | */ | ||
| 636 | for (p = (char *)mem_start, ep = p + l; p < ep; p++) | ||
| 637 | if ((*p) == '\0') { | ||
| 638 | memmove(p, p+1, ep - p); | ||
| 639 | ep--; | ||
| 640 | } | ||
| 631 | mem_start = ALIGNUL(mem_start + l + 1); | 641 | mem_start = ALIGNUL(mem_start + l + 1); |
| 632 | } | 642 | } |
| 633 | 643 | ||
diff --git a/arch/ppc64/kernel/pSeries_reconfig.c b/arch/ppc64/kernel/pSeries_reconfig.c index cb5443f2e49b..dc2a69d412a2 100644 --- a/arch/ppc64/kernel/pSeries_reconfig.c +++ b/arch/ppc64/kernel/pSeries_reconfig.c | |||
| @@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np) | |||
| 47 | remove_proc_entry(pp->name, np->pde); | 47 | remove_proc_entry(pp->name, np->pde); |
| 48 | pp = pp->next; | 48 | pp = pp->next; |
| 49 | } | 49 | } |
| 50 | |||
| 51 | /* Assuming that symlinks have the same parent directory as | ||
| 52 | * np->pde. | ||
| 53 | */ | ||
| 54 | if (np->name_link) | ||
| 55 | remove_proc_entry(np->name_link->name, parent->pde); | ||
| 56 | if (np->addr_link) | ||
| 57 | remove_proc_entry(np->addr_link->name, parent->pde); | ||
| 58 | if (np->pde) | 50 | if (np->pde) |
| 59 | remove_proc_entry(np->pde->name, parent->pde); | 51 | remove_proc_entry(np->pde->name, parent->pde); |
| 60 | } | 52 | } |
diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 6f79b7b9b445..1ac531ba7056 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c | |||
| @@ -211,13 +211,23 @@ struct { | |||
| 211 | */ | 211 | */ |
| 212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) | 212 | #define ADDR(x) (u32) ((unsigned long)(x) - offset) |
| 213 | 213 | ||
| 214 | /* | ||
| 215 | * Error results ... some OF calls will return "-1" on error, some | ||
| 216 | * will return 0, some will return either. To simplify, here are | ||
| 217 | * macros to use with any ihandle or phandle return value to check if | ||
| 218 | * it is valid | ||
| 219 | */ | ||
| 220 | |||
| 221 | #define PROM_ERROR (-1u) | ||
| 222 | #define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) | ||
| 223 | #define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) | ||
| 224 | |||
| 225 | |||
| 214 | /* This is the one and *ONLY* place where we actually call open | 226 | /* This is the one and *ONLY* place where we actually call open |
| 215 | * firmware from, since we need to make sure we're running in 32b | 227 | * firmware from, since we need to make sure we're running in 32b |
| 216 | * mode when we do. We switch back to 64b mode upon return. | 228 | * mode when we do. We switch back to 64b mode upon return. |
| 217 | */ | 229 | */ |
| 218 | 230 | ||
| 219 | #define PROM_ERROR (-1) | ||
| 220 | |||
| 221 | static int __init call_prom(const char *service, int nargs, int nret, ...) | 231 | static int __init call_prom(const char *service, int nargs, int nret, ...) |
| 222 | { | 232 | { |
| 223 | int i; | 233 | int i; |
| @@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void) | |||
| 587 | { | 597 | { |
| 588 | unsigned long offset = reloc_offset(); | 598 | unsigned long offset = reloc_offset(); |
| 589 | ihandle elfloader; | 599 | ihandle elfloader; |
| 590 | int ret; | ||
| 591 | 600 | ||
| 592 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); | 601 | elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); |
| 593 | if (elfloader == 0) { | 602 | if (elfloader == 0) { |
| 594 | prom_printf("couldn't open /packages/elf-loader\n"); | 603 | prom_printf("couldn't open /packages/elf-loader\n"); |
| 595 | return; | 604 | return; |
| 596 | } | 605 | } |
| 597 | ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), | 606 | call_prom("call-method", 3, 1, ADDR("process-elf-header"), |
| 598 | elfloader, ADDR(&fake_elf)); | 607 | elfloader, ADDR(&fake_elf)); |
| 599 | call_prom("close", 1, 0, elfloader); | 608 | call_prom("close", 1, 0, elfloader); |
| 600 | } | 609 | } |
| @@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) | |||
| 646 | base = _ALIGN_UP(base + 0x100000, align)) { | 655 | base = _ALIGN_UP(base + 0x100000, align)) { |
| 647 | prom_debug(" trying: 0x%x\n\r", base); | 656 | prom_debug(" trying: 0x%x\n\r", base); |
| 648 | addr = (unsigned long)prom_claim(base, size, 0); | 657 | addr = (unsigned long)prom_claim(base, size, 0); |
| 649 | if ((int)addr != PROM_ERROR) | 658 | if (addr != PROM_ERROR) |
| 650 | break; | 659 | break; |
| 651 | addr = 0; | 660 | addr = 0; |
| 652 | if (align == 0) | 661 | if (align == 0) |
| @@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, | |||
| 708 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { | 717 | for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { |
| 709 | prom_debug(" trying: 0x%x\n\r", base); | 718 | prom_debug(" trying: 0x%x\n\r", base); |
| 710 | addr = (unsigned long)prom_claim(base, size, 0); | 719 | addr = (unsigned long)prom_claim(base, size, 0); |
| 711 | if ((int)addr != PROM_ERROR) | 720 | if (addr != PROM_ERROR) |
| 712 | break; | 721 | break; |
| 713 | addr = 0; | 722 | addr = 0; |
| 714 | } | 723 | } |
| @@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void) | |||
| 902 | { | 911 | { |
| 903 | unsigned long offset = reloc_offset(); | 912 | unsigned long offset = reloc_offset(); |
| 904 | struct prom_t *_prom = PTRRELOC(&prom); | 913 | struct prom_t *_prom = PTRRELOC(&prom); |
| 905 | phandle prom_rtas, rtas_node; | 914 | phandle rtas_node; |
| 915 | ihandle rtas_inst; | ||
| 906 | u32 base, entry = 0; | 916 | u32 base, entry = 0; |
| 907 | u32 size = 0; | 917 | u32 size = 0; |
| 908 | 918 | ||
| 909 | prom_debug("prom_instantiate_rtas: start...\n"); | 919 | prom_debug("prom_instantiate_rtas: start...\n"); |
| 910 | 920 | ||
| 911 | prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 921 | rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
| 912 | prom_debug("prom_rtas: %x\n", prom_rtas); | 922 | prom_debug("rtas_node: %x\n", rtas_node); |
| 913 | if (prom_rtas == (phandle) -1) | 923 | if (!PHANDLE_VALID(rtas_node)) |
| 914 | return; | 924 | return; |
| 915 | 925 | ||
| 916 | prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); | 926 | prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); |
| 917 | if (size == 0) | 927 | if (size == 0) |
| 918 | return; | 928 | return; |
| 919 | 929 | ||
| @@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void) | |||
| 922 | prom_printf("RTAS allocation failed !\n"); | 932 | prom_printf("RTAS allocation failed !\n"); |
| 923 | return; | 933 | return; |
| 924 | } | 934 | } |
| 925 | prom_printf("instantiating rtas at 0x%x", base); | ||
| 926 | 935 | ||
| 927 | rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); | 936 | rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); |
| 928 | prom_printf("..."); | 937 | if (!IHANDLE_VALID(rtas_inst)) { |
| 938 | prom_printf("opening rtas package failed"); | ||
| 939 | return; | ||
| 940 | } | ||
| 941 | |||
| 942 | prom_printf("instantiating rtas at 0x%x ...", base); | ||
| 929 | 943 | ||
| 930 | if (call_prom("call-method", 3, 2, | 944 | if (call_prom("call-method", 3, 2, |
| 931 | ADDR("instantiate-rtas"), | 945 | ADDR("instantiate-rtas"), |
| 932 | rtas_node, base) != PROM_ERROR) { | 946 | rtas_inst, base) != PROM_ERROR) { |
| 933 | entry = (long)_prom->args.rets[1]; | 947 | entry = (long)_prom->args.rets[1]; |
| 934 | } | 948 | } |
| 935 | if (entry == 0) { | 949 | if (entry == 0) { |
| @@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void) | |||
| 940 | 954 | ||
| 941 | reserve_mem(base, size); | 955 | reserve_mem(base, size); |
| 942 | 956 | ||
| 943 | prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); | 957 | prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); |
| 944 | prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); | 958 | prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); |
| 945 | 959 | ||
| 946 | prom_debug("rtas base = 0x%x\n", base); | 960 | prom_debug("rtas base = 0x%x\n", base); |
| 947 | prom_debug("rtas entry = 0x%x\n", entry); | 961 | prom_debug("rtas entry = 0x%x\n", entry); |
| @@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void) | |||
| 1062 | 1076 | ||
| 1063 | prom_printf("opening PHB %s", path); | 1077 | prom_printf("opening PHB %s", path); |
| 1064 | phb_node = call_prom("open", 1, 1, path); | 1078 | phb_node = call_prom("open", 1, 1, path); |
| 1065 | if ( (long)phb_node <= 0) | 1079 | if (phb_node == 0) |
| 1066 | prom_printf("... failed\n"); | 1080 | prom_printf("... failed\n"); |
| 1067 | else | 1081 | else |
| 1068 | prom_printf("... done\n"); | 1082 | prom_printf("... done\n"); |
| @@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp) | |||
| 1279 | 1293 | ||
| 1280 | /* get a handle for the stdout device */ | 1294 | /* get a handle for the stdout device */ |
| 1281 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); | 1295 | _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); |
| 1282 | if ((long)_prom->chosen <= 0) | 1296 | if (!PHANDLE_VALID(_prom->chosen)) |
| 1283 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ | 1297 | prom_panic("cannot find chosen"); /* msg won't be printed :( */ |
| 1284 | 1298 | ||
| 1285 | /* get device tree root */ | 1299 | /* get device tree root */ |
| 1286 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); | 1300 | _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); |
| 1287 | if ((long)_prom->root <= 0) | 1301 | if (!PHANDLE_VALID(_prom->root)) |
| 1288 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ | 1302 | prom_panic("cannot find device tree root"); /* msg won't be printed :( */ |
| 1289 | } | 1303 | } |
| 1290 | 1304 | ||
| @@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void) | |||
| 1356 | } | 1370 | } |
| 1357 | /* Default to pSeries. We need to know if we are running LPAR */ | 1371 | /* Default to pSeries. We need to know if we are running LPAR */ |
| 1358 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); | 1372 | rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); |
| 1359 | if (rtas != (phandle) -1) { | 1373 | if (!PHANDLE_VALID(rtas)) { |
| 1360 | unsigned long x; | 1374 | int x = prom_getproplen(rtas, "ibm,hypertas-functions"); |
| 1361 | x = prom_getproplen(rtas, "ibm,hypertas-functions"); | ||
| 1362 | if (x != PROM_ERROR) { | 1375 | if (x != PROM_ERROR) { |
| 1363 | prom_printf("Hypertas detected, assuming LPAR !\n"); | 1376 | prom_printf("Hypertas detected, assuming LPAR !\n"); |
| 1364 | return PLATFORM_PSERIES_LPAR; | 1377 | return PLATFORM_PSERIES_LPAR; |
| @@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void) | |||
| 1426 | * leave some room at the end of the path for appending extra | 1439 | * leave some room at the end of the path for appending extra |
| 1427 | * arguments | 1440 | * arguments |
| 1428 | */ | 1441 | */ |
| 1429 | if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) | 1442 | if (call_prom("package-to-path", 3, 1, node, path, |
| 1443 | PROM_SCRATCH_SIZE-10) == PROM_ERROR) | ||
| 1430 | continue; | 1444 | continue; |
| 1431 | prom_printf("found display : %s, opening ... ", path); | 1445 | prom_printf("found display : %s, opening ... ", path); |
| 1432 | 1446 | ||
| 1433 | ih = call_prom("open", 1, 1, path); | 1447 | ih = call_prom("open", 1, 1, path); |
| 1434 | if (ih == (ihandle)0 || ih == (ihandle)-1) { | 1448 | if (ih == 0) { |
| 1435 | prom_printf("failed\n"); | 1449 | prom_printf("failed\n"); |
| 1436 | continue; | 1450 | continue; |
| 1437 | } | 1451 | } |
| @@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str) | |||
| 1514 | return 0; | 1528 | return 0; |
| 1515 | } | 1529 | } |
| 1516 | 1530 | ||
| 1531 | /* | ||
| 1532 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
| 1533 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
| 1534 | */ | ||
| 1535 | #define MAX_PROPERTY_NAME 64 | ||
| 1536 | |||
| 1517 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | 1537 | static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, |
| 1518 | unsigned long *mem_end) | 1538 | unsigned long *mem_end) |
| 1519 | { | 1539 | { |
| @@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
| 1527 | /* get and store all property names */ | 1547 | /* get and store all property names */ |
| 1528 | prev_name = RELOC(""); | 1548 | prev_name = RELOC(""); |
| 1529 | for (;;) { | 1549 | for (;;) { |
| 1530 | 1550 | int rc; | |
| 1531 | /* 32 is max len of name including nul. */ | 1551 | |
| 1532 | namep = make_room(mem_start, mem_end, 32, 1); | 1552 | /* 64 is max len of name including nul. */ |
| 1533 | if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { | 1553 | namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); |
| 1554 | rc = call_prom("nextprop", 3, 1, node, prev_name, namep); | ||
| 1555 | if (rc != 1) { | ||
| 1534 | /* No more nodes: unwind alloc */ | 1556 | /* No more nodes: unwind alloc */ |
| 1535 | *mem_start = (unsigned long)namep; | 1557 | *mem_start = (unsigned long)namep; |
| 1536 | break; | 1558 | break; |
| @@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, | |||
| 1555 | } | 1577 | } |
| 1556 | } | 1578 | } |
| 1557 | 1579 | ||
| 1558 | /* | ||
| 1559 | * The Open Firmware 1275 specification states properties must be 31 bytes or | ||
| 1560 | * less, however not all firmwares obey this. Make it 64 bytes to be safe. | ||
| 1561 | */ | ||
| 1562 | #define MAX_PROPERTY_NAME 64 | ||
| 1563 | |||
| 1564 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | 1580 | static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, |
| 1565 | unsigned long *mem_end) | 1581 | unsigned long *mem_end) |
| 1566 | { | 1582 | { |
| 1567 | int l, align; | 1583 | int l, align; |
| 1568 | phandle child; | 1584 | phandle child; |
| 1569 | char *namep, *prev_name, *sstart; | 1585 | char *namep, *prev_name, *sstart, *p, *ep; |
| 1570 | unsigned long soff; | 1586 | unsigned long soff; |
| 1571 | unsigned char *valp; | 1587 | unsigned char *valp; |
| 1572 | unsigned long offset = reloc_offset(); | 1588 | unsigned long offset = reloc_offset(); |
| @@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
| 1588 | call_prom("package-to-path", 3, 1, node, namep, l); | 1604 | call_prom("package-to-path", 3, 1, node, namep, l); |
| 1589 | } | 1605 | } |
| 1590 | namep[l] = '\0'; | 1606 | namep[l] = '\0'; |
| 1607 | /* Fixup an Apple bug where they have bogus \0 chars in the | ||
| 1608 | * middle of the path in some properties | ||
| 1609 | */ | ||
| 1610 | for (p = namep, ep = namep + l; p < ep; p++) | ||
| 1611 | if (*p == '\0') { | ||
| 1612 | memmove(p, p+1, ep - p); | ||
| 1613 | ep--; l--; | ||
| 1614 | } | ||
| 1591 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); | 1615 | *mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4); |
| 1592 | } | 1616 | } |
| 1593 | 1617 | ||
| @@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
| 1599 | prev_name = RELOC(""); | 1623 | prev_name = RELOC(""); |
| 1600 | sstart = (char *)RELOC(dt_string_start); | 1624 | sstart = (char *)RELOC(dt_string_start); |
| 1601 | for (;;) { | 1625 | for (;;) { |
| 1602 | if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) | 1626 | int rc; |
| 1627 | |||
| 1628 | rc = call_prom("nextprop", 3, 1, node, prev_name, pname); | ||
| 1629 | if (rc != 1) | ||
| 1603 | break; | 1630 | break; |
| 1604 | 1631 | ||
| 1605 | /* find string offset */ | 1632 | /* find string offset */ |
| @@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, | |||
| 1615 | l = call_prom("getproplen", 2, 1, node, pname); | 1642 | l = call_prom("getproplen", 2, 1, node, pname); |
| 1616 | 1643 | ||
| 1617 | /* sanity checks */ | 1644 | /* sanity checks */ |
| 1618 | if (l < 0) | 1645 | if (l == PROM_ERROR) |
| 1619 | continue; | 1646 | continue; |
| 1620 | if (l > MAX_PROPERTY_LENGTH) { | 1647 | if (l > MAX_PROPERTY_LENGTH) { |
| 1621 | prom_printf("WARNING: ignoring large property "); | 1648 | prom_printf("WARNING: ignoring large property "); |
| @@ -1763,17 +1790,18 @@ static void __init fixup_device_tree(void) | |||
| 1763 | 1790 | ||
| 1764 | /* Some G5s have a missing interrupt definition, fix it up here */ | 1791 | /* Some G5s have a missing interrupt definition, fix it up here */ |
| 1765 | u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); | 1792 | u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); |
| 1766 | if ((long)u3 <= 0) | 1793 | if (!PHANDLE_VALID(u3)) |
| 1767 | return; | 1794 | return; |
| 1768 | i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); | 1795 | i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); |
| 1769 | if ((long)i2c <= 0) | 1796 | if (!PHANDLE_VALID(i2c)) |
| 1770 | return; | 1797 | return; |
| 1771 | mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); | 1798 | mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); |
| 1772 | if ((long)mpic <= 0) | 1799 | if (!PHANDLE_VALID(mpic)) |
| 1773 | return; | 1800 | return; |
| 1774 | 1801 | ||
| 1775 | /* check if proper rev of u3 */ | 1802 | /* check if proper rev of u3 */ |
| 1776 | if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0) | 1803 | if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) |
| 1804 | == PROM_ERROR) | ||
| 1777 | return; | 1805 | return; |
| 1778 | if (u3_rev != 0x35) | 1806 | if (u3_rev != 0x35) |
| 1779 | return; | 1807 | return; |
| @@ -1881,6 +1909,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long | |||
| 1881 | &getprop_rval, sizeof(getprop_rval)); | 1909 | &getprop_rval, sizeof(getprop_rval)); |
| 1882 | 1910 | ||
| 1883 | /* | 1911 | /* |
| 1912 | * On pSeries, inform the firmware about our capabilities | ||
| 1913 | */ | ||
| 1914 | if (RELOC(of_platform) & PLATFORM_PSERIES) | ||
| 1915 | prom_send_capabilities(); | ||
| 1916 | |||
| 1917 | /* | ||
| 1884 | * On pSeries, copy the CPU hold code | 1918 | * On pSeries, copy the CPU hold code |
| 1885 | */ | 1919 | */ |
| 1886 | if (RELOC(of_platform) & PLATFORM_PSERIES) | 1920 | if (RELOC(of_platform) & PLATFORM_PSERIES) |
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 3d54745108c7..33364a7d2cd2 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
| @@ -325,9 +325,7 @@ int timer_interrupt(struct pt_regs * regs) | |||
| 325 | 325 | ||
| 326 | irq_enter(); | 326 | irq_enter(); |
| 327 | 327 | ||
| 328 | #ifndef CONFIG_PPC_ISERIES | ||
| 329 | profile_tick(CPU_PROFILING, regs); | 328 | profile_tick(CPU_PROFILING, regs); |
| 330 | #endif | ||
| 331 | 329 | ||
| 332 | lpaca->lppaca.int_dword.fields.decr_int = 0; | 330 | lpaca->lppaca.int_dword.fields.decr_int = 0; |
| 333 | 331 | ||
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 33ca56c90da2..2803bc7c2c79 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
| @@ -196,6 +196,34 @@ static iopte_t *alloc_consistent_cluster(struct pci_iommu *iommu, unsigned long | |||
| 196 | return NULL; | 196 | return NULL; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | static int iommu_alloc_ctx(struct pci_iommu *iommu) | ||
| 200 | { | ||
| 201 | int lowest = iommu->ctx_lowest_free; | ||
| 202 | int sz = IOMMU_NUM_CTXS - lowest; | ||
| 203 | int n = find_next_zero_bit(iommu->ctx_bitmap, sz, lowest); | ||
| 204 | |||
| 205 | if (unlikely(n == sz)) { | ||
| 206 | n = find_next_zero_bit(iommu->ctx_bitmap, lowest, 1); | ||
| 207 | if (unlikely(n == lowest)) { | ||
| 208 | printk(KERN_WARNING "IOMMU: Ran out of contexts.\n"); | ||
| 209 | n = 0; | ||
| 210 | } | ||
| 211 | } | ||
| 212 | if (n) | ||
| 213 | __set_bit(n, iommu->ctx_bitmap); | ||
| 214 | |||
| 215 | return n; | ||
| 216 | } | ||
| 217 | |||
| 218 | static inline void iommu_free_ctx(struct pci_iommu *iommu, int ctx) | ||
| 219 | { | ||
| 220 | if (likely(ctx)) { | ||
| 221 | __clear_bit(ctx, iommu->ctx_bitmap); | ||
| 222 | if (ctx < iommu->ctx_lowest_free) | ||
| 223 | iommu->ctx_lowest_free = ctx; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 199 | /* Allocate and map kernel buffer of size SIZE using consistent mode | 227 | /* Allocate and map kernel buffer of size SIZE using consistent mode |
| 200 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if | 228 | * DMA for PCI device PDEV. Return non-NULL cpu-side address if |
| 201 | * successful and set *DMA_ADDRP to the PCI side dma address. | 229 | * successful and set *DMA_ADDRP to the PCI side dma address. |
| @@ -236,7 +264,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad | |||
| 236 | npages = size >> IO_PAGE_SHIFT; | 264 | npages = size >> IO_PAGE_SHIFT; |
| 237 | ctx = 0; | 265 | ctx = 0; |
| 238 | if (iommu->iommu_ctxflush) | 266 | if (iommu->iommu_ctxflush) |
| 239 | ctx = iommu->iommu_cur_ctx++; | 267 | ctx = iommu_alloc_ctx(iommu); |
| 240 | first_page = __pa(first_page); | 268 | first_page = __pa(first_page); |
| 241 | while (npages--) { | 269 | while (npages--) { |
| 242 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | | 270 | iopte_val(*iopte) = (IOPTE_CONSISTENT(ctx) | |
| @@ -317,6 +345,8 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ | |||
| 317 | } | 345 | } |
| 318 | } | 346 | } |
| 319 | 347 | ||
| 348 | iommu_free_ctx(iommu, ctx); | ||
| 349 | |||
| 320 | spin_unlock_irqrestore(&iommu->lock, flags); | 350 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 321 | 351 | ||
| 322 | order = get_order(size); | 352 | order = get_order(size); |
| @@ -360,7 +390,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct | |||
| 360 | base_paddr = __pa(oaddr & IO_PAGE_MASK); | 390 | base_paddr = __pa(oaddr & IO_PAGE_MASK); |
| 361 | ctx = 0; | 391 | ctx = 0; |
| 362 | if (iommu->iommu_ctxflush) | 392 | if (iommu->iommu_ctxflush) |
| 363 | ctx = iommu->iommu_cur_ctx++; | 393 | ctx = iommu_alloc_ctx(iommu); |
| 364 | if (strbuf->strbuf_enabled) | 394 | if (strbuf->strbuf_enabled) |
| 365 | iopte_protection = IOPTE_STREAMING(ctx); | 395 | iopte_protection = IOPTE_STREAMING(ctx); |
| 366 | else | 396 | else |
| @@ -380,39 +410,53 @@ bad: | |||
| 380 | return PCI_DMA_ERROR_CODE; | 410 | return PCI_DMA_ERROR_CODE; |
| 381 | } | 411 | } |
| 382 | 412 | ||
| 383 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages) | 413 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages, int direction) |
| 384 | { | 414 | { |
| 385 | int limit; | 415 | int limit; |
| 386 | 416 | ||
| 387 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
| 388 | if (strbuf->strbuf_ctxflush && | 417 | if (strbuf->strbuf_ctxflush && |
| 389 | iommu->iommu_ctxflush) { | 418 | iommu->iommu_ctxflush) { |
| 390 | unsigned long matchreg, flushreg; | 419 | unsigned long matchreg, flushreg; |
| 420 | u64 val; | ||
| 391 | 421 | ||
| 392 | flushreg = strbuf->strbuf_ctxflush; | 422 | flushreg = strbuf->strbuf_ctxflush; |
| 393 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | 423 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); |
| 394 | 424 | ||
| 395 | limit = 100000; | ||
| 396 | pci_iommu_write(flushreg, ctx); | 425 | pci_iommu_write(flushreg, ctx); |
| 397 | for(;;) { | 426 | val = pci_iommu_read(matchreg); |
| 398 | if (((long)pci_iommu_read(matchreg)) >= 0L) | 427 | val &= 0xffff; |
| 399 | break; | 428 | if (!val) |
| 400 | limit--; | 429 | goto do_flush_sync; |
| 401 | if (!limit) | 430 | |
| 402 | break; | 431 | while (val) { |
| 403 | udelay(1); | 432 | if (val & 0x1) |
| 433 | pci_iommu_write(flushreg, ctx); | ||
| 434 | val >>= 1; | ||
| 404 | } | 435 | } |
| 405 | if (!limit) | 436 | val = pci_iommu_read(matchreg); |
| 437 | if (unlikely(val)) { | ||
| 406 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " | 438 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " |
| 407 | "timeout vaddr[%08x] ctx[%lx]\n", | 439 | "timeout matchreg[%lx] ctx[%lx]\n", |
| 408 | vaddr, ctx); | 440 | val, ctx); |
| 441 | goto do_page_flush; | ||
| 442 | } | ||
| 409 | } else { | 443 | } else { |
| 410 | unsigned long i; | 444 | unsigned long i; |
| 411 | 445 | ||
| 446 | do_page_flush: | ||
| 412 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | 447 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) |
| 413 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | 448 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); |
| 414 | } | 449 | } |
| 415 | 450 | ||
| 451 | do_flush_sync: | ||
| 452 | /* If the device could not have possibly put dirty data into | ||
| 453 | * the streaming cache, no flush-flag synchronization needs | ||
| 454 | * to be performed. | ||
| 455 | */ | ||
| 456 | if (direction == PCI_DMA_TODEVICE) | ||
| 457 | return; | ||
| 458 | |||
| 459 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
| 416 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | 460 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); |
| 417 | (void) pci_iommu_read(iommu->write_complete_reg); | 461 | (void) pci_iommu_read(iommu->write_complete_reg); |
| 418 | 462 | ||
| @@ -466,7 +510,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
| 466 | 510 | ||
| 467 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 511 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
| 468 | if (strbuf->strbuf_enabled) | 512 | if (strbuf->strbuf_enabled) |
| 469 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 513 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
| 470 | 514 | ||
| 471 | /* Step 2: Clear out first TSB entry. */ | 515 | /* Step 2: Clear out first TSB entry. */ |
| 472 | iopte_make_dummy(iommu, base); | 516 | iopte_make_dummy(iommu, base); |
| @@ -474,6 +518,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
| 474 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 518 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
| 475 | npages, ctx); | 519 | npages, ctx); |
| 476 | 520 | ||
| 521 | iommu_free_ctx(iommu, ctx); | ||
| 522 | |||
| 477 | spin_unlock_irqrestore(&iommu->lock, flags); | 523 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 478 | } | 524 | } |
| 479 | 525 | ||
| @@ -613,7 +659,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int | |||
| 613 | /* Step 4: Choose a context if necessary. */ | 659 | /* Step 4: Choose a context if necessary. */ |
| 614 | ctx = 0; | 660 | ctx = 0; |
| 615 | if (iommu->iommu_ctxflush) | 661 | if (iommu->iommu_ctxflush) |
| 616 | ctx = iommu->iommu_cur_ctx++; | 662 | ctx = iommu_alloc_ctx(iommu); |
| 617 | 663 | ||
| 618 | /* Step 5: Create the mappings. */ | 664 | /* Step 5: Create the mappings. */ |
| 619 | if (strbuf->strbuf_enabled) | 665 | if (strbuf->strbuf_enabled) |
| @@ -678,7 +724,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
| 678 | 724 | ||
| 679 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 725 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
| 680 | if (strbuf->strbuf_enabled) | 726 | if (strbuf->strbuf_enabled) |
| 681 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
| 682 | 728 | ||
| 683 | /* Step 2: Clear out first TSB entry. */ | 729 | /* Step 2: Clear out first TSB entry. */ |
| 684 | iopte_make_dummy(iommu, base); | 730 | iopte_make_dummy(iommu, base); |
| @@ -686,6 +732,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
| 686 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, | 732 | free_streaming_cluster(iommu, bus_addr - iommu->page_table_map_base, |
| 687 | npages, ctx); | 733 | npages, ctx); |
| 688 | 734 | ||
| 735 | iommu_free_ctx(iommu, ctx); | ||
| 736 | |||
| 689 | spin_unlock_irqrestore(&iommu->lock, flags); | 737 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 690 | } | 738 | } |
| 691 | 739 | ||
| @@ -724,7 +772,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size | |||
| 724 | } | 772 | } |
| 725 | 773 | ||
| 726 | /* Step 2: Kick data out of streaming buffers. */ | 774 | /* Step 2: Kick data out of streaming buffers. */ |
| 727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 775 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
| 728 | 776 | ||
| 729 | spin_unlock_irqrestore(&iommu->lock, flags); | 777 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 730 | } | 778 | } |
| @@ -768,7 +816,7 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
| 768 | i--; | 816 | i--; |
| 769 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) | 817 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) |
| 770 | - bus_addr) >> IO_PAGE_SHIFT; | 818 | - bus_addr) >> IO_PAGE_SHIFT; |
| 771 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); | 819 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); |
| 772 | 820 | ||
| 773 | spin_unlock_irqrestore(&iommu->lock, flags); | 821 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 774 | } | 822 | } |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 3567fa879e1f..534320ef0db2 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
| @@ -1212,7 +1212,7 @@ static void __init psycho_iommu_init(struct pci_controller_info *p) | |||
| 1212 | 1212 | ||
| 1213 | /* Setup initial software IOMMU state. */ | 1213 | /* Setup initial software IOMMU state. */ |
| 1214 | spin_lock_init(&iommu->lock); | 1214 | spin_lock_init(&iommu->lock); |
| 1215 | iommu->iommu_cur_ctx = 0; | 1215 | iommu->ctx_lowest_free = 1; |
| 1216 | 1216 | ||
| 1217 | /* Register addresses. */ | 1217 | /* Register addresses. */ |
| 1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; | 1218 | iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 5525d1ec4af8..53d333b4a4e8 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
| @@ -1265,7 +1265,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, | |||
| 1265 | 1265 | ||
| 1266 | /* Setup initial software IOMMU state. */ | 1266 | /* Setup initial software IOMMU state. */ |
| 1267 | spin_lock_init(&iommu->lock); | 1267 | spin_lock_init(&iommu->lock); |
| 1268 | iommu->iommu_cur_ctx = 0; | 1268 | iommu->ctx_lowest_free = 1; |
| 1269 | 1269 | ||
| 1270 | /* Register addresses. */ | 1270 | /* Register addresses. */ |
| 1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; | 1271 | iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e93fcadc3722..5753175b94e6 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
| @@ -1753,7 +1753,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) | |||
| 1753 | 1753 | ||
| 1754 | /* Setup initial software IOMMU state. */ | 1754 | /* Setup initial software IOMMU state. */ |
| 1755 | spin_lock_init(&iommu->lock); | 1755 | spin_lock_init(&iommu->lock); |
| 1756 | iommu->iommu_cur_ctx = 0; | 1756 | iommu->ctx_lowest_free = 1; |
| 1757 | 1757 | ||
| 1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ | 1758 | /* Register addresses, SCHIZO has iommu ctx flushing. */ |
| 1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; | 1759 | iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 76ea6455433f..89f5e019f24c 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
| @@ -117,17 +117,25 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages | |||
| 117 | 117 | ||
| 118 | #define STRBUF_TAG_VALID 0x02UL | 118 | #define STRBUF_TAG_VALID 0x02UL |
| 119 | 119 | ||
| 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) | 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction) |
| 121 | { | 121 | { |
| 122 | unsigned long n; | 122 | unsigned long n; |
| 123 | int limit; | 123 | int limit; |
| 124 | 124 | ||
| 125 | iommu->strbuf_flushflag = 0UL; | ||
| 126 | n = npages; | 125 | n = npages; |
| 127 | while (n--) | 126 | while (n--) |
| 128 | upa_writeq(base + (n << IO_PAGE_SHIFT), | 127 | upa_writeq(base + (n << IO_PAGE_SHIFT), |
| 129 | iommu->strbuf_regs + STRBUF_PFLUSH); | 128 | iommu->strbuf_regs + STRBUF_PFLUSH); |
| 130 | 129 | ||
| 130 | /* If the device could not have possibly put dirty data into | ||
| 131 | * the streaming cache, no flush-flag synchronization needs | ||
| 132 | * to be performed. | ||
| 133 | */ | ||
| 134 | if (direction == SBUS_DMA_TODEVICE) | ||
| 135 | return; | ||
| 136 | |||
| 137 | iommu->strbuf_flushflag = 0UL; | ||
| 138 | |||
| 131 | /* Whoopee cushion! */ | 139 | /* Whoopee cushion! */ |
| 132 | upa_writeq(__pa(&iommu->strbuf_flushflag), | 140 | upa_writeq(__pa(&iommu->strbuf_flushflag), |
| 133 | iommu->strbuf_regs + STRBUF_FSYNC); | 141 | iommu->strbuf_regs + STRBUF_FSYNC); |
| @@ -421,7 +429,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, | |||
| 421 | 429 | ||
| 422 | spin_lock_irqsave(&iommu->lock, flags); | 430 | spin_lock_irqsave(&iommu->lock, flags); |
| 423 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); | 431 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
| 424 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); | 432 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT, direction); |
| 425 | spin_unlock_irqrestore(&iommu->lock, flags); | 433 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 426 | } | 434 | } |
| 427 | 435 | ||
| @@ -584,7 +592,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int | |||
| 584 | iommu = sdev->bus->iommu; | 592 | iommu = sdev->bus->iommu; |
| 585 | spin_lock_irqsave(&iommu->lock, flags); | 593 | spin_lock_irqsave(&iommu->lock, flags); |
| 586 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 594 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
| 587 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 595 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT, direction); |
| 588 | spin_unlock_irqrestore(&iommu->lock, flags); | 596 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 589 | } | 597 | } |
| 590 | 598 | ||
| @@ -596,7 +604,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t | |||
| 596 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); | 604 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
| 597 | 605 | ||
| 598 | spin_lock_irqsave(&iommu->lock, flags); | 606 | spin_lock_irqsave(&iommu->lock, flags); |
| 599 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); | 607 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT, direction); |
| 600 | spin_unlock_irqrestore(&iommu->lock, flags); | 608 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 601 | } | 609 | } |
| 602 | 610 | ||
| @@ -620,7 +628,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int | |||
| 620 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; | 628 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
| 621 | 629 | ||
| 622 | spin_lock_irqsave(&iommu->lock, flags); | 630 | spin_lock_irqsave(&iommu->lock, flags); |
| 623 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); | 631 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT, direction); |
| 624 | spin_unlock_irqrestore(&iommu->lock, flags); | 632 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 625 | } | 633 | } |
| 626 | 634 | ||
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index b89989de364d..bd41e4286d0d 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug | |||
| @@ -2,10 +2,6 @@ menu "Kernel hacking" | |||
| 2 | 2 | ||
| 3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
| 4 | 4 | ||
| 5 | config FRAME_POINTER | ||
| 6 | bool | ||
| 7 | default y if DEBUG_INFO | ||
| 8 | |||
| 9 | config PT_PROXY | 5 | config PT_PROXY |
| 10 | bool "Enable ptrace proxy" | 6 | bool "Enable ptrace proxy" |
| 11 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT | 7 | depends on XTERM_CHAN && DEBUG_INFO && MODE_TT |
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c index d43e9fab05a7..f9e22198e011 100644 --- a/arch/um/drivers/random.c +++ b/arch/um/drivers/random.c | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | /* Much of this ripped from hw_random.c */ | 1 | /* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */ |
| 2 | 2 | /* Much of this ripped from drivers/char/hw_random.c, see there for other | |
| 3 | * copyright. | ||
| 4 | * | ||
| 5 | * This software may be used and distributed according to the terms | ||
| 6 | * of the GNU General Public License, incorporated herein by reference. | ||
| 7 | */ | ||
| 3 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 4 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
| 5 | #include <linux/miscdevice.h> | 10 | #include <linux/miscdevice.h> |
| @@ -12,8 +17,6 @@ | |||
| 12 | */ | 17 | */ |
| 13 | #define RNG_VERSION "1.0.0" | 18 | #define RNG_VERSION "1.0.0" |
| 14 | #define RNG_MODULE_NAME "random" | 19 | #define RNG_MODULE_NAME "random" |
| 15 | #define RNG_DRIVER_NAME RNG_MODULE_NAME " virtual driver " RNG_VERSION | ||
| 16 | #define PFX RNG_MODULE_NAME ": " | ||
| 17 | 20 | ||
| 18 | #define RNG_MISCDEV_MINOR 183 /* official */ | 21 | #define RNG_MISCDEV_MINOR 183 /* official */ |
| 19 | 22 | ||
| @@ -98,7 +101,7 @@ static int __init rng_init (void) | |||
| 98 | 101 | ||
| 99 | err = misc_register (&rng_miscdev); | 102 | err = misc_register (&rng_miscdev); |
| 100 | if (err) { | 103 | if (err) { |
| 101 | printk (KERN_ERR PFX "misc device register failed\n"); | 104 | printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n"); |
| 102 | goto err_out_cleanup_hw; | 105 | goto err_out_cleanup_hw; |
| 103 | } | 106 | } |
| 104 | 107 | ||
| @@ -120,3 +123,6 @@ static void __exit rng_cleanup (void) | |||
| 120 | 123 | ||
| 121 | module_init (rng_init); | 124 | module_init (rng_init); |
| 122 | module_exit (rng_cleanup); | 125 | module_exit (rng_cleanup); |
| 126 | |||
| 127 | MODULE_DESCRIPTION("UML Host Random Number Generator (RNG) driver"); | ||
| 128 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index a2bac429f3d4..b32a77010fbe 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include "init.h" | 22 | #include "init.h" |
| 23 | #include "irq_user.h" | 23 | #include "irq_user.h" |
| 24 | #include "mconsole_kern.h" | 24 | #include "mconsole_kern.h" |
| 25 | #include "2_5compat.h" | ||
| 26 | 25 | ||
| 27 | static int ssl_version = 1; | 26 | static int ssl_version = 1; |
| 28 | 27 | ||
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 361d0be342b3..afbe1e71ed83 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include "irq_user.h" | 28 | #include "irq_user.h" |
| 29 | #include "mconsole_kern.h" | 29 | #include "mconsole_kern.h" |
| 30 | #include "init.h" | 30 | #include "init.h" |
| 31 | #include "2_5compat.h" | ||
| 32 | 31 | ||
| 33 | #define MAX_TTYS (16) | 32 | #define MAX_TTYS (16) |
| 34 | 33 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 88f956c34fed..2a7f6892c55c 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
| @@ -49,7 +49,6 @@ | |||
| 49 | #include "irq_user.h" | 49 | #include "irq_user.h" |
| 50 | #include "irq_kern.h" | 50 | #include "irq_kern.h" |
| 51 | #include "ubd_user.h" | 51 | #include "ubd_user.h" |
| 52 | #include "2_5compat.h" | ||
| 53 | #include "os.h" | 52 | #include "os.h" |
| 54 | #include "mem.h" | 53 | #include "mem.h" |
| 55 | #include "mem_kern.h" | 54 | #include "mem_kern.h" |
| @@ -440,9 +439,9 @@ static int udb_setup(char *str) | |||
| 440 | __setup("udb", udb_setup); | 439 | __setup("udb", udb_setup); |
| 441 | __uml_help(udb_setup, | 440 | __uml_help(udb_setup, |
| 442 | "udb\n" | 441 | "udb\n" |
| 443 | " This option is here solely to catch ubd -> udb typos, which can be\n\n" | 442 | " This option is here solely to catch ubd -> udb typos, which can be\n" |
| 444 | " to impossible to catch visually unless you specifically look for\n\n" | 443 | " to impossible to catch visually unless you specifically look for\n" |
| 445 | " them. The only result of any option starting with 'udb' is an error\n\n" | 444 | " them. The only result of any option starting with 'udb' is an error\n" |
| 446 | " in the boot output.\n\n" | 445 | " in the boot output.\n\n" |
| 447 | ); | 446 | ); |
| 448 | 447 | ||
diff --git a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h deleted file mode 100644 index abdb015a4d71..000000000000 --- a/arch/um/include/2_5compat.h +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __2_5_COMPAT_H__ | ||
| 7 | #define __2_5_COMPAT_H__ | ||
| 8 | |||
| 9 | #define INIT_HARDSECT(arr, maj, sizes) | ||
| 10 | |||
| 11 | #define SET_PRI(task) do ; while(0) | ||
| 12 | |||
| 13 | #endif | ||
| 14 | |||
| 15 | /* | ||
| 16 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 17 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 18 | * adjust the settings for this buffer only. This must remain at the end | ||
| 19 | * of the file. | ||
| 20 | * --------------------------------------------------------------------------- | ||
| 21 | * Local variables: | ||
| 22 | * c-file-style: "linux" | ||
| 23 | * End: | ||
| 24 | */ | ||
diff --git a/arch/um/include/sysrq.h b/arch/um/include/sysrq.h index 2ce9423460b3..c8d332b56b98 100644 --- a/arch/um/include/sysrq.h +++ b/arch/um/include/sysrq.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef __UM_SYSRQ_H | 1 | #ifndef __UM_SYSRQ_H |
| 2 | #define __UM_SYSRQ_H | 2 | #define __UM_SYSRQ_H |
| 3 | 3 | ||
| 4 | extern void show_trace(unsigned long *stack); | 4 | struct task_struct; |
| 5 | extern void show_trace(struct task_struct* task, unsigned long *stack); | ||
| 5 | 6 | ||
| 6 | #endif | 7 | #endif |
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c index 49ddabe69be7..efd222ffe20e 100644 --- a/arch/um/kernel/exec_kern.c +++ b/arch/um/kernel/exec_kern.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include "kern.h" | 16 | #include "kern.h" |
| 17 | #include "irq_user.h" | 17 | #include "irq_user.h" |
| 18 | #include "tlb.h" | 18 | #include "tlb.h" |
| 19 | #include "2_5compat.h" | ||
| 20 | #include "os.h" | 19 | #include "os.h" |
| 21 | #include "time_user.h" | 20 | #include "time_user.h" |
| 22 | #include "choose-mode.h" | 21 | #include "choose-mode.h" |
diff --git a/arch/um/kernel/initrd_kern.c b/arch/um/kernel/initrd_kern.c deleted file mode 100644 index fc568af468b9..000000000000 --- a/arch/um/kernel/initrd_kern.c +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "linux/init.h" | ||
| 7 | #include "linux/bootmem.h" | ||
| 8 | #include "linux/initrd.h" | ||
| 9 | #include "asm/types.h" | ||
| 10 | #include "user_util.h" | ||
| 11 | #include "kern_util.h" | ||
| 12 | #include "initrd.h" | ||
| 13 | #include "init.h" | ||
| 14 | #include "os.h" | ||
| 15 | |||
| 16 | /* Changed by uml_initrd_setup, which is a setup */ | ||
| 17 | static char *initrd __initdata = NULL; | ||
| 18 | |||
| 19 | static int __init read_initrd(void) | ||
| 20 | { | ||
| 21 | void *area; | ||
| 22 | long long size; | ||
| 23 | int err; | ||
| 24 | |||
| 25 | if(initrd == NULL) return 0; | ||
| 26 | err = os_file_size(initrd, &size); | ||
| 27 | if(err) return 0; | ||
| 28 | area = alloc_bootmem(size); | ||
| 29 | if(area == NULL) return 0; | ||
| 30 | if(load_initrd(initrd, area, size) == -1) return 0; | ||
| 31 | initrd_start = (unsigned long) area; | ||
| 32 | initrd_end = initrd_start + size; | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | __uml_postsetup(read_initrd); | ||
| 37 | |||
| 38 | static int __init uml_initrd_setup(char *line, int *add) | ||
| 39 | { | ||
| 40 | initrd = line; | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | |||
| 44 | __uml_setup("initrd=", uml_initrd_setup, | ||
| 45 | "initrd=<initrd image>\n" | ||
| 46 | " This is used to boot UML from an initrd image. The argument is the\n" | ||
| 47 | " name of the file containing the image.\n\n" | ||
| 48 | ); | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 52 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 53 | * adjust the settings for this buffer only. This must remain at the end | ||
| 54 | * of the file. | ||
| 55 | * --------------------------------------------------------------------------- | ||
| 56 | * Local variables: | ||
| 57 | * c-file-style: "linux" | ||
| 58 | * End: | ||
| 59 | */ | ||
diff --git a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c deleted file mode 100644 index cb90681e151c..000000000000 --- a/arch/um/kernel/initrd_user.c +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <unistd.h> | ||
| 7 | #include <sys/types.h> | ||
| 8 | #include <sys/stat.h> | ||
| 9 | #include <errno.h> | ||
| 10 | |||
| 11 | #include "user_util.h" | ||
| 12 | #include "kern_util.h" | ||
| 13 | #include "user.h" | ||
| 14 | #include "initrd.h" | ||
| 15 | #include "os.h" | ||
| 16 | |||
| 17 | int load_initrd(char *filename, void *buf, int size) | ||
| 18 | { | ||
| 19 | int fd, n; | ||
| 20 | |||
| 21 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | ||
| 22 | if(fd < 0){ | ||
| 23 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | ||
| 24 | return(-1); | ||
| 25 | } | ||
| 26 | n = os_read_file(fd, buf, size); | ||
| 27 | if(n != size){ | ||
| 28 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | ||
| 29 | filename, -n); | ||
| 30 | return(-1); | ||
| 31 | } | ||
| 32 | |||
| 33 | os_close_file(fd); | ||
| 34 | return(0); | ||
| 35 | } | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 39 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 40 | * adjust the settings for this buffer only. This must remain at the end | ||
| 41 | * of the file. | ||
| 42 | * --------------------------------------------------------------------------- | ||
| 43 | * Local variables: | ||
| 44 | * c-file-style: "linux" | ||
| 45 | * End: | ||
| 46 | */ | ||
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index a17c49703f9b..e42e6364ca13 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c | |||
| @@ -71,7 +71,7 @@ static __init void do_uml_initcalls(void) | |||
| 71 | 71 | ||
| 72 | static void last_ditch_exit(int sig) | 72 | static void last_ditch_exit(int sig) |
| 73 | { | 73 | { |
| 74 | CHOOSE_MODE(kmalloc_ok = 0, (void) 0); | 74 | kmalloc_ok = 0; |
| 75 | signal(SIGINT, SIG_DFL); | 75 | signal(SIGINT, SIG_DFL); |
| 76 | signal(SIGTERM, SIG_DFL); | 76 | signal(SIGTERM, SIG_DFL); |
| 77 | signal(SIGHUP, SIG_DFL); | 77 | signal(SIGHUP, SIG_DFL); |
| @@ -87,7 +87,7 @@ int main(int argc, char **argv, char **envp) | |||
| 87 | { | 87 | { |
| 88 | char **new_argv; | 88 | char **new_argv; |
| 89 | sigset_t mask; | 89 | sigset_t mask; |
| 90 | int ret, i; | 90 | int ret, i, err; |
| 91 | 91 | ||
| 92 | /* Enable all signals except SIGIO - in some environments, we can | 92 | /* Enable all signals except SIGIO - in some environments, we can |
| 93 | * enter with some signals blocked | 93 | * enter with some signals blocked |
| @@ -160,27 +160,29 @@ int main(int argc, char **argv, char **envp) | |||
| 160 | */ | 160 | */ |
| 161 | change_sig(SIGPROF, 0); | 161 | change_sig(SIGPROF, 0); |
| 162 | 162 | ||
| 163 | /* Reboot */ | 163 | /* This signal stuff used to be in the reboot case. However, |
| 164 | if(ret){ | 164 | * sometimes a SIGVTALRM can come in when we're halting (reproducably |
| 165 | int err; | 165 | * when writing out gcov information, presumably because that takes |
| 166 | 166 | * some time) and cause a segfault. | |
| 167 | printf("\n"); | 167 | */ |
| 168 | 168 | ||
| 169 | /* stop timers and set SIG*ALRM to be ignored */ | 169 | /* stop timers and set SIG*ALRM to be ignored */ |
| 170 | disable_timer(); | 170 | disable_timer(); |
| 171 | 171 | ||
| 172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ | 172 | /* disable SIGIO for the fds and set SIGIO to be ignored */ |
| 173 | err = deactivate_all_fds(); | 173 | err = deactivate_all_fds(); |
| 174 | if(err) | 174 | if(err) |
| 175 | printf("deactivate_all_fds failed, errno = %d\n", | 175 | printf("deactivate_all_fds failed, errno = %d\n", -err); |
| 176 | -err); | ||
| 177 | 176 | ||
| 178 | /* Let any pending signals fire now. This ensures | 177 | /* Let any pending signals fire now. This ensures |
| 179 | * that they won't be delivered after the exec, when | 178 | * that they won't be delivered after the exec, when |
| 180 | * they are definitely not expected. | 179 | * they are definitely not expected. |
| 181 | */ | 180 | */ |
| 182 | unblock_signals(); | 181 | unblock_signals(); |
| 183 | 182 | ||
| 183 | /* Reboot */ | ||
| 184 | if(ret){ | ||
| 185 | printf("\n"); | ||
| 184 | execvp(new_argv[0], new_argv); | 186 | execvp(new_argv[0], new_argv); |
| 185 | perror("Failed to exec kernel"); | 187 | perror("Failed to exec kernel"); |
| 186 | ret = 1; | 188 | ret = 1; |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index c1adf7ba3fd1..804c6bbdf67c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | #include "tlb.h" | 43 | #include "tlb.h" |
| 44 | #include "frame_kern.h" | 44 | #include "frame_kern.h" |
| 45 | #include "sigcontext.h" | 45 | #include "sigcontext.h" |
| 46 | #include "2_5compat.h" | ||
| 47 | #include "os.h" | 46 | #include "os.h" |
| 48 | #include "mode.h" | 47 | #include "mode.h" |
| 49 | #include "mode_kern.h" | 48 | #include "mode_kern.h" |
| @@ -55,18 +54,6 @@ | |||
| 55 | */ | 54 | */ |
| 56 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; | 55 | struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; |
| 57 | 56 | ||
| 58 | struct task_struct *get_task(int pid, int require) | ||
| 59 | { | ||
| 60 | struct task_struct *ret; | ||
| 61 | |||
| 62 | read_lock(&tasklist_lock); | ||
| 63 | ret = find_task_by_pid(pid); | ||
| 64 | read_unlock(&tasklist_lock); | ||
| 65 | |||
| 66 | if(require && (ret == NULL)) panic("get_task couldn't find a task\n"); | ||
| 67 | return(ret); | ||
| 68 | } | ||
| 69 | |||
| 70 | int external_pid(void *t) | 57 | int external_pid(void *t) |
| 71 | { | 58 | { |
| 72 | struct task_struct *task = t ? t : current; | 59 | struct task_struct *task = t ? t : current; |
| @@ -189,7 +176,6 @@ void default_idle(void) | |||
| 189 | 176 | ||
| 190 | while(1){ | 177 | while(1){ |
| 191 | /* endless idle loop with no priority at all */ | 178 | /* endless idle loop with no priority at all */ |
| 192 | SET_PRI(current); | ||
| 193 | 179 | ||
| 194 | /* | 180 | /* |
| 195 | * although we are an idle CPU, we do not want to | 181 | * although we are an idle CPU, we do not want to |
| @@ -212,11 +198,6 @@ int page_size(void) | |||
| 212 | return(PAGE_SIZE); | 198 | return(PAGE_SIZE); |
| 213 | } | 199 | } |
| 214 | 200 | ||
| 215 | unsigned long page_mask(void) | ||
| 216 | { | ||
| 217 | return(PAGE_MASK); | ||
| 218 | } | ||
| 219 | |||
| 220 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, | 201 | void *um_virt_to_phys(struct task_struct *task, unsigned long addr, |
| 221 | pte_t *pte_out) | 202 | pte_t *pte_out) |
| 222 | { | 203 | { |
| @@ -349,11 +330,6 @@ char *uml_strdup(char *string) | |||
| 349 | return(new); | 330 | return(new); |
| 350 | } | 331 | } |
| 351 | 332 | ||
| 352 | void *get_init_task(void) | ||
| 353 | { | ||
| 354 | return(&init_thread_union.thread_info.task); | ||
| 355 | } | ||
| 356 | |||
| 357 | int copy_to_user_proc(void __user *to, void *from, int size) | 333 | int copy_to_user_proc(void __user *to, void *from, int size) |
| 358 | { | 334 | { |
| 359 | return(copy_to_user(to, from, size)); | 335 | return(copy_to_user(to, from, size)); |
| @@ -480,15 +456,3 @@ unsigned long arch_align_stack(unsigned long sp) | |||
| 480 | return sp & ~0xf; | 456 | return sp & ~0xf; |
| 481 | } | 457 | } |
| 482 | #endif | 458 | #endif |
| 483 | |||
| 484 | |||
| 485 | /* | ||
| 486 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 487 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 488 | * adjust the settings for this buffer only. This must remain at the end | ||
| 489 | * of the file. | ||
| 490 | * --------------------------------------------------------------------------- | ||
| 491 | * Local variables: | ||
| 492 | * c-file-style: "linux" | ||
| 493 | * End: | ||
| 494 | */ | ||
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 2925e15324de..71af4d503899 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
| @@ -322,11 +322,9 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
| 322 | UPT_SYSCALL_ARG2(regs), | 322 | UPT_SYSCALL_ARG2(regs), |
| 323 | UPT_SYSCALL_ARG3(regs), | 323 | UPT_SYSCALL_ARG3(regs), |
| 324 | UPT_SYSCALL_ARG4(regs)); | 324 | UPT_SYSCALL_ARG4(regs)); |
| 325 | else { | 325 | else audit_syscall_exit(current, |
| 326 | int res = UPT_SYSCALL_RET(regs); | 326 | AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), |
| 327 | audit_syscall_exit(current, AUDITSC_RESULT(res), | 327 | UPT_SYSCALL_RET(regs)); |
| 328 | res); | ||
| 329 | } | ||
| 330 | } | 328 | } |
| 331 | 329 | ||
| 332 | /* Fake a debug trap */ | 330 | /* Fake a debug trap */ |
| @@ -356,14 +354,3 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) | |||
| 356 | current->exit_code = 0; | 354 | current->exit_code = 0; |
| 357 | } | 355 | } |
| 358 | } | 356 | } |
| 359 | |||
| 360 | /* | ||
| 361 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 362 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 363 | * adjust the settings for this buffer only. This must remain at the end | ||
| 364 | * of the file. | ||
| 365 | * --------------------------------------------------------------------------- | ||
| 366 | * Local variables: | ||
| 367 | * c-file-style: "linux" | ||
| 368 | * End: | ||
| 369 | */ | ||
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index e630438f9e73..f80850091e79 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include "linux/config.h" | ||
| 6 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
| 7 | #include "linux/kernel.h" | 8 | #include "linux/kernel.h" |
| 8 | #include "linux/module.h" | 9 | #include "linux/module.h" |
| @@ -12,14 +13,14 @@ | |||
| 12 | #include "sysrq.h" | 13 | #include "sysrq.h" |
| 13 | #include "user_util.h" | 14 | #include "user_util.h" |
| 14 | 15 | ||
| 15 | void show_trace(unsigned long * stack) | 16 | /* Catch non-i386 SUBARCH's. */ |
| 17 | #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) | ||
| 18 | void show_trace(struct task_struct *task, unsigned long * stack) | ||
| 16 | { | 19 | { |
| 17 | /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from | ||
| 18 | * arch/i386/kernel/traps.c, and then move this to sys-i386/sysrq.c.*/ | ||
| 19 | unsigned long addr; | 20 | unsigned long addr; |
| 20 | 21 | ||
| 21 | if (!stack) { | 22 | if (!stack) { |
| 22 | stack = (unsigned long*) &stack; | 23 | stack = (unsigned long*) &stack; |
| 23 | WARN_ON(1); | 24 | WARN_ON(1); |
| 24 | } | 25 | } |
| 25 | 26 | ||
| @@ -35,6 +36,7 @@ void show_trace(unsigned long * stack) | |||
| 35 | } | 36 | } |
| 36 | printk("\n"); | 37 | printk("\n"); |
| 37 | } | 38 | } |
| 39 | #endif | ||
| 38 | 40 | ||
| 39 | /* | 41 | /* |
| 40 | * stack dumps generator - this is used by arch-independent code. | 42 | * stack dumps generator - this is used by arch-independent code. |
| @@ -44,7 +46,7 @@ void dump_stack(void) | |||
| 44 | { | 46 | { |
| 45 | unsigned long stack; | 47 | unsigned long stack; |
| 46 | 48 | ||
| 47 | show_trace(&stack); | 49 | show_trace(current, &stack); |
| 48 | } | 50 | } |
| 49 | EXPORT_SYMBOL(dump_stack); | 51 | EXPORT_SYMBOL(dump_stack); |
| 50 | 52 | ||
| @@ -59,7 +61,11 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
| 59 | int i; | 61 | int i; |
| 60 | 62 | ||
| 61 | if (esp == NULL) { | 63 | if (esp == NULL) { |
| 62 | if (task != current) { | 64 | if (task != current && task != NULL) { |
| 65 | /* XXX: Isn't this bogus? I.e. isn't this the | ||
| 66 | * *userspace* stack of this task? If not so, use this | ||
| 67 | * even when task == current (as in i386). | ||
| 68 | */ | ||
| 63 | esp = (unsigned long *) KSTK_ESP(task); | 69 | esp = (unsigned long *) KSTK_ESP(task); |
| 64 | /* Which one? No actual difference - just coding style.*/ | 70 | /* Which one? No actual difference - just coding style.*/ |
| 65 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); | 71 | //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs); |
| @@ -77,5 +83,6 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
| 77 | printk("%08lx ", *stack++); | 83 | printk("%08lx ", *stack++); |
| 78 | } | 84 | } |
| 79 | 85 | ||
| 80 | show_trace(esp); | 86 | printk("Call Trace: \n"); |
| 87 | show_trace(current, esp); | ||
| 81 | } | 88 | } |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 1de22d8a313a..c20aef120598 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "kern.h" | 23 | #include "kern.h" |
| 24 | #include "chan_kern.h" | 24 | #include "chan_kern.h" |
| 25 | #include "mconsole_kern.h" | 25 | #include "mconsole_kern.h" |
| 26 | #include "2_5compat.h" | ||
| 27 | #include "mem.h" | 26 | #include "mem.h" |
| 28 | #include "mem_kern.h" | 27 | #include "mem_kern.h" |
| 29 | 28 | ||
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index df810ca8fc12..776310fd5b8b 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
| @@ -32,10 +32,6 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
| 32 | unsigned long flags; | 32 | unsigned long flags; |
| 33 | int err, vtalrm, alrm, prof, cpu; | 33 | int err, vtalrm, alrm, prof, cpu; |
| 34 | char c; | 34 | char c; |
| 35 | /* jailing and SMP are incompatible, so this doesn't need to be | ||
| 36 | * made per-cpu | ||
| 37 | */ | ||
| 38 | static int reading; | ||
| 39 | 35 | ||
| 40 | from = prev; | 36 | from = prev; |
| 41 | to = next; | 37 | to = next; |
| @@ -59,13 +55,11 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
| 59 | c = 0; | 55 | c = 0; |
| 60 | set_current(to); | 56 | set_current(to); |
| 61 | 57 | ||
| 62 | reading = 0; | ||
| 63 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); | 58 | err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); |
| 64 | if(err != sizeof(c)) | 59 | if(err != sizeof(c)) |
| 65 | panic("write of switch_pipe failed, err = %d", -err); | 60 | panic("write of switch_pipe failed, err = %d", -err); |
| 66 | 61 | ||
| 67 | reading = 1; | 62 | if(from->thread.mode.tt.switch_pipe[0] == -1) |
| 68 | if(from->thread.mode.tt.switch_pipe[0] == -1) | ||
| 69 | os_kill_process(os_getpid(), 0); | 63 | os_kill_process(os_getpid(), 0); |
| 70 | 64 | ||
| 71 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); | 65 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 4d10ec372a67..418427107b29 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
| @@ -111,12 +111,6 @@ struct seq_operations cpuinfo_op = { | |||
| 111 | .show = show_cpuinfo, | 111 | .show = show_cpuinfo, |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | pte_t * __bad_pagetable(void) | ||
| 115 | { | ||
| 116 | panic("Someone should implement __bad_pagetable"); | ||
| 117 | return(NULL); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* Set in linux_main */ | 114 | /* Set in linux_main */ |
| 121 | unsigned long host_task_size; | 115 | unsigned long host_task_size; |
| 122 | unsigned long task_size; | 116 | unsigned long task_size; |
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c index 281fc7b8ca00..e3706d15c4f5 100644 --- a/arch/um/sys-i386/sysrq.c +++ b/arch/um/sys-i386/sysrq.c | |||
| @@ -3,12 +3,15 @@ | |||
| 3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include "linux/config.h" | ||
| 6 | #include "linux/kernel.h" | 7 | #include "linux/kernel.h" |
| 7 | #include "linux/smp.h" | 8 | #include "linux/smp.h" |
| 8 | #include "linux/sched.h" | 9 | #include "linux/sched.h" |
| 10 | #include "linux/kallsyms.h" | ||
| 9 | #include "asm/ptrace.h" | 11 | #include "asm/ptrace.h" |
| 10 | #include "sysrq.h" | 12 | #include "sysrq.h" |
| 11 | 13 | ||
| 14 | /* This is declared by <linux/sched.h> */ | ||
| 12 | void show_regs(struct pt_regs *regs) | 15 | void show_regs(struct pt_regs *regs) |
| 13 | { | 16 | { |
| 14 | printk("\n"); | 17 | printk("\n"); |
| @@ -31,5 +34,80 @@ void show_regs(struct pt_regs *regs) | |||
| 31 | 0xffff & PT_REGS_DS(regs), | 34 | 0xffff & PT_REGS_DS(regs), |
| 32 | 0xffff & PT_REGS_ES(regs)); | 35 | 0xffff & PT_REGS_ES(regs)); |
| 33 | 36 | ||
| 34 | show_trace((unsigned long *) ®s); | 37 | show_trace(NULL, (unsigned long *) ®s); |
| 35 | } | 38 | } |
| 39 | |||
| 40 | /* Copied from i386. */ | ||
| 41 | static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | ||
| 42 | { | ||
| 43 | return p > (void *)tinfo && | ||
| 44 | p < (void *)tinfo + THREAD_SIZE - 3; | ||
| 45 | } | ||
| 46 | |||
| 47 | /* Adapted from i386 (we also print the address we read from). */ | ||
| 48 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | ||
| 49 | unsigned long *stack, unsigned long ebp) | ||
| 50 | { | ||
| 51 | unsigned long addr; | ||
| 52 | |||
| 53 | #ifdef CONFIG_FRAME_POINTER | ||
| 54 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | ||
| 55 | addr = *(unsigned long *)(ebp + 4); | ||
| 56 | printk("%08lx: [<%08lx>]", ebp + 4, addr); | ||
| 57 | print_symbol(" %s", addr); | ||
| 58 | printk("\n"); | ||
| 59 | ebp = *(unsigned long *)ebp; | ||
| 60 | } | ||
| 61 | #else | ||
| 62 | while (valid_stack_ptr(tinfo, stack)) { | ||
| 63 | addr = *stack; | ||
| 64 | if (__kernel_text_address(addr)) { | ||
| 65 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
| 66 | print_symbol(" %s", addr); | ||
| 67 | printk("\n"); | ||
| 68 | } | ||
| 69 | stack++; | ||
| 70 | } | ||
| 71 | #endif | ||
| 72 | return ebp; | ||
| 73 | } | ||
| 74 | |||
| 75 | void show_trace(struct task_struct* task, unsigned long * stack) | ||
| 76 | { | ||
| 77 | unsigned long ebp; | ||
| 78 | struct thread_info *context; | ||
| 79 | |||
| 80 | /* Turn this into BUG_ON if possible. */ | ||
| 81 | if (!stack) { | ||
| 82 | stack = (unsigned long*) &stack; | ||
| 83 | printk("show_trace: got NULL stack, implicit assumption task == current"); | ||
| 84 | WARN_ON(1); | ||
| 85 | } | ||
| 86 | |||
| 87 | if (!task) | ||
| 88 | task = current; | ||
| 89 | |||
| 90 | if (task != current) { | ||
| 91 | //ebp = (unsigned long) KSTK_EBP(task); | ||
| 92 | /* Which one? No actual difference - just coding style.*/ | ||
| 93 | ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs); | ||
| 94 | } else { | ||
| 95 | asm ("movl %%ebp, %0" : "=r" (ebp) : ); | ||
| 96 | } | ||
| 97 | |||
| 98 | context = (struct thread_info *) | ||
| 99 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | ||
| 100 | print_context_stack(context, stack, ebp); | ||
| 101 | |||
| 102 | /*while (((long) stack & (THREAD_SIZE-1)) != 0) { | ||
| 103 | addr = *stack; | ||
| 104 | if (__kernel_text_address(addr)) { | ||
| 105 | printk("%08lx: [<%08lx>]", (unsigned long) stack, addr); | ||
| 106 | print_symbol(" %s", addr); | ||
| 107 | printk("\n"); | ||
| 108 | } | ||
| 109 | stack++; | ||
| 110 | }*/ | ||
| 111 | printk("\n"); | ||
| 112 | } | ||
| 113 | |||
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c index 82d6e9335bb6..2f816f1a0ff4 100644 --- a/arch/um/sys-ppc/sysrq.c +++ b/arch/um/sys-ppc/sysrq.c | |||
| @@ -27,17 +27,5 @@ void show_regs(struct pt_regs_subarch *regs) | |||
| 27 | 0xffff & regs->xds, 0xffff & regs->xes); | 27 | 0xffff & regs->xds, 0xffff & regs->xes); |
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | show_trace(®s->gpr[1]); | 30 | show_trace(current, ®s->gpr[1]); |
| 31 | } | 31 | } |
| 32 | |||
| 33 | |||
| 34 | /* | ||
| 35 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 36 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 37 | * adjust the settings for this buffer only. This must remain at the end | ||
| 38 | * of the file. | ||
| 39 | * --------------------------------------------------------------------------- | ||
| 40 | * Local variables: | ||
| 41 | * c-file-style: "linux" | ||
| 42 | * End: | ||
| 43 | */ | ||
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index d4a59657fb99..6f44f40204ed 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
| @@ -133,23 +133,27 @@ static long arch_prctl_tt(int code, unsigned long addr) | |||
| 133 | 133 | ||
| 134 | #ifdef CONFIG_MODE_SKAS | 134 | #ifdef CONFIG_MODE_SKAS |
| 135 | 135 | ||
| 136 | /* XXX: Must also call arch_prctl in the host, beside saving the segment bases! */ | ||
| 136 | static long arch_prctl_skas(int code, unsigned long addr) | 137 | static long arch_prctl_skas(int code, unsigned long addr) |
| 137 | { | 138 | { |
| 138 | long ret = 0; | 139 | long ret = 0; |
| 139 | 140 | ||
| 140 | switch(code){ | 141 | switch(code){ |
| 141 | case ARCH_SET_GS: | ||
| 142 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
| 143 | break; | ||
| 144 | case ARCH_SET_FS: | 142 | case ARCH_SET_FS: |
| 145 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; | 143 | current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr; |
| 146 | break; | 144 | break; |
| 145 | case ARCH_SET_GS: | ||
| 146 | current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr; | ||
| 147 | break; | ||
| 147 | case ARCH_GET_FS: | 148 | case ARCH_GET_FS: |
| 148 | ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr); | 149 | ret = put_user(current->thread.regs.regs.skas. |
| 150 | regs[FS_BASE / sizeof(unsigned long)], | ||
| 151 | (unsigned long __user *)addr); | ||
| 149 | break; | 152 | break; |
| 150 | case ARCH_GET_GS: | 153 | case ARCH_GET_GS: |
| 151 | ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \ | 154 | ret = put_user(current->thread.regs.regs.skas. |
| 152 | long)], &addr); | 155 | regs[GS_BASE / sizeof(unsigned long)], |
| 156 | (unsigned long __user *)addr); | ||
| 153 | break; | 157 | break; |
| 154 | default: | 158 | default: |
| 155 | ret = -EINVAL; | 159 | ret = -EINVAL; |
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c index ddf74691a610..d0a25af19a5b 100644 --- a/arch/um/sys-x86_64/sysrq.c +++ b/arch/um/sys-x86_64/sysrq.c | |||
| @@ -36,14 +36,5 @@ void __show_regs(struct pt_regs * regs) | |||
| 36 | void show_regs(struct pt_regs *regs) | 36 | void show_regs(struct pt_regs *regs) |
| 37 | { | 37 | { |
| 38 | __show_regs(regs); | 38 | __show_regs(regs); |
| 39 | show_trace((unsigned long *) ®s); | 39 | show_trace(current, (unsigned long *) ®s); |
| 40 | } | 40 | } |
| 41 | |||
| 42 | /* Emacs will notice this stuff at the end of the file and automatically | ||
| 43 | * adjust the settings for this buffer only. This must remain at the end | ||
| 44 | * of the file. | ||
| 45 | * --------------------------------------------------------------------------- | ||
| 46 | * Local variables: | ||
| 47 | * c-file-style: "linux" | ||
| 48 | * End: | ||
| 49 | */ | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 0f430d9d3632..289f448ac89c 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
| @@ -305,6 +305,7 @@ config HPET_TIMER | |||
| 305 | 305 | ||
| 306 | config X86_PM_TIMER | 306 | config X86_PM_TIMER |
| 307 | bool "PM timer" | 307 | bool "PM timer" |
| 308 | depends on ACPI | ||
| 308 | default y | 309 | default y |
| 309 | help | 310 | help |
| 310 | Support the ACPI PM timer for time keeping. This is slow, | 311 | Support the ACPI PM timer for time keeping. This is slow, |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 80e9b498c443..afd87e64d0a8 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | #include <asm/desc.h> | 37 | #include <asm/desc.h> |
| 38 | #include <asm/proto.h> | 38 | #include <asm/proto.h> |
| 39 | #include <asm/mach_apic.h> | 39 | #include <asm/mach_apic.h> |
| 40 | #include <asm/acpi.h> | ||
| 40 | 41 | ||
| 41 | #define __apicdebuginit __init | 42 | #define __apicdebuginit __init |
| 42 | 43 | ||
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index f86d9db94bfc..61a63be6b294 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <asm/pgalloc.h> | 30 | #include <asm/pgalloc.h> |
| 31 | #include <asm/io_apic.h> | 31 | #include <asm/io_apic.h> |
| 32 | #include <asm/proto.h> | 32 | #include <asm/proto.h> |
| 33 | #include <asm/acpi.h> | ||
| 33 | 34 | ||
| 34 | /* Have we found an MP table */ | 35 | /* Have we found an MP table */ |
| 35 | int smp_found_config; | 36 | int smp_found_config; |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 3fdcdba0fec5..429c0269dc4e 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
| 29 | #include <asm/i387.h> | 29 | #include <asm/i387.h> |
| 30 | #include <asm/proto.h> | 30 | #include <asm/proto.h> |
| 31 | #include <asm/ia32_unistd.h> | ||
| 31 | 32 | ||
| 32 | /* #define DEBUG_SIG 1 */ | 33 | /* #define DEBUG_SIG 1 */ |
| 33 | 34 | ||
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 735b6767c8ed..fb8c809b4cd9 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
| @@ -27,7 +27,9 @@ | |||
| 27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
| 28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
| 29 | #include <linux/acpi.h> | 29 | #include <linux/acpi.h> |
| 30 | #ifdef CONFIG_ACPI | ||
| 30 | #include <acpi/achware.h> /* for PM timer frequency */ | 31 | #include <acpi/achware.h> /* for PM timer frequency */ |
| 32 | #endif | ||
| 31 | #include <asm/8253pit.h> | 33 | #include <asm/8253pit.h> |
| 32 | #include <asm/pgtable.h> | 34 | #include <asm/pgtable.h> |
| 33 | #include <asm/vsyscall.h> | 35 | #include <asm/vsyscall.h> |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index fcca26c89bbc..38dd9ffbe8bc 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
| @@ -488,6 +488,20 @@ static int viocd_packet(struct cdrom_device_info *cdi, | |||
| 488 | & (CDC_DVD_RAM | CDC_RAM)) != 0; | 488 | & (CDC_DVD_RAM | CDC_RAM)) != 0; |
| 489 | } | 489 | } |
| 490 | break; | 490 | break; |
| 491 | case GPCMD_GET_CONFIGURATION: | ||
| 492 | if (cgc->cmd[3] == CDF_RWRT) { | ||
| 493 | struct rwrt_feature_desc *rfd = (struct rwrt_feature_desc *)(cgc->buffer + sizeof(struct feature_header)); | ||
| 494 | |||
| 495 | if ((buflen >= | ||
| 496 | (sizeof(struct feature_header) + sizeof(*rfd))) && | ||
| 497 | (cdi->ops->capability & ~cdi->mask | ||
| 498 | & (CDC_DVD_RAM | CDC_RAM))) { | ||
| 499 | rfd->feature_code = cpu_to_be16(CDF_RWRT); | ||
| 500 | rfd->curr = 1; | ||
| 501 | ret = 0; | ||
| 502 | } | ||
| 503 | } | ||
| 504 | break; | ||
| 491 | default: | 505 | default: |
| 492 | if (cgc->sense) { | 506 | if (cgc->sense) { |
| 493 | /* indicate Unknown code */ | 507 | /* indicate Unknown code */ |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 95882bb1950e..60c9be99c6d9 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
| @@ -46,6 +46,10 @@ config CPU_FREQ_STAT_DETAILS | |||
| 46 | This will show detail CPU frequency translation table in sysfs file | 46 | This will show detail CPU frequency translation table in sysfs file |
| 47 | system | 47 | system |
| 48 | 48 | ||
| 49 | # Note that it is not currently possible to set the other governors (such as ondemand) | ||
| 50 | # as the default, since if they fail to initialise, cpufreq will be | ||
| 51 | # left in an undefined state. | ||
| 52 | |||
| 49 | choice | 53 | choice |
| 50 | prompt "Default CPUFreq governor" | 54 | prompt "Default CPUFreq governor" |
| 51 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 | 55 | default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 |
| @@ -115,4 +119,24 @@ config CPU_FREQ_GOV_ONDEMAND | |||
| 115 | 119 | ||
| 116 | If in doubt, say N. | 120 | If in doubt, say N. |
| 117 | 121 | ||
| 122 | config CPU_FREQ_GOV_CONSERVATIVE | ||
| 123 | tristate "'conservative' cpufreq governor" | ||
| 124 | depends on CPU_FREQ | ||
| 125 | help | ||
| 126 | 'conservative' - this driver is rather similar to the 'ondemand' | ||
| 127 | governor both in its source code and its purpose, the difference is | ||
| 128 | its optimisation for better suitability in a battery powered | ||
| 129 | environment. The frequency is gracefully increased and decreased | ||
| 130 | rather than jumping to 100% when speed is required. | ||
| 131 | |||
| 132 | If you have a desktop machine then you should really be considering | ||
| 133 | the 'ondemand' governor instead, however if you are using a laptop, | ||
| 134 | PDA or even an AMD64 based computer (due to the unacceptable | ||
| 135 | step-by-step latency issues between the minimum and maximum frequency | ||
| 136 | transitions in the CPU) you will probably want to use this governor. | ||
| 137 | |||
| 138 | For details, take a look at linux/Documentation/cpu-freq. | ||
| 139 | |||
| 140 | If in doubt, say N. | ||
| 141 | |||
| 118 | endif # CPU_FREQ | 142 | endif # CPU_FREQ |
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 67b16e5a41a7..71fc3b4173f1 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile | |||
| @@ -8,6 +8,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o | |||
| 8 | obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o | 8 | obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o |
| 9 | obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o | 9 | obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o |
| 10 | obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o | 10 | obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o |
| 11 | obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o | ||
| 11 | 12 | ||
| 12 | # CPUfreq cross-arch helpers | 13 | # CPUfreq cross-arch helpers |
| 13 | obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o | 14 | obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8e561313d094..03b5fb2ddcf4 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -258,7 +258,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) | |||
| 258 | (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && | 258 | (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && |
| 259 | (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) | 259 | (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) |
| 260 | { | 260 | { |
| 261 | printk(KERN_WARNING "Warning: CPU frequency is %u, " | 261 | dprintk(KERN_WARNING "Warning: CPU frequency is %u, " |
| 262 | "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); | 262 | "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); |
| 263 | freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; | 263 | freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; |
| 264 | } | 264 | } |
| @@ -814,7 +814,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne | |||
| 814 | { | 814 | { |
| 815 | struct cpufreq_freqs freqs; | 815 | struct cpufreq_freqs freqs; |
| 816 | 816 | ||
| 817 | printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " | 817 | dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " |
| 818 | "core thinks of %u, is %u kHz.\n", old_freq, new_freq); | 818 | "core thinks of %u, is %u kHz.\n", old_freq, new_freq); |
| 819 | 819 | ||
| 820 | freqs.cpu = cpu; | 820 | freqs.cpu = cpu; |
| @@ -923,7 +923,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state) | |||
| 923 | struct cpufreq_freqs freqs; | 923 | struct cpufreq_freqs freqs; |
| 924 | 924 | ||
| 925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | 925 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
| 926 | printk(KERN_DEBUG "Warning: CPU frequency is %u, " | 926 | dprintk(KERN_DEBUG "Warning: CPU frequency is %u, " |
| 927 | "cpufreq assumed %u kHz.\n", | 927 | "cpufreq assumed %u kHz.\n", |
| 928 | cur_freq, cpu_policy->cur); | 928 | cur_freq, cpu_policy->cur); |
| 929 | 929 | ||
| @@ -1004,7 +1004,7 @@ static int cpufreq_resume(struct sys_device * sysdev) | |||
| 1004 | struct cpufreq_freqs freqs; | 1004 | struct cpufreq_freqs freqs; |
| 1005 | 1005 | ||
| 1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) | 1006 | if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) |
| 1007 | printk(KERN_WARNING "Warning: CPU frequency" | 1007 | dprintk(KERN_WARNING "Warning: CPU frequency" |
| 1008 | "is %u, cpufreq assumed %u kHz.\n", | 1008 | "is %u, cpufreq assumed %u kHz.\n", |
| 1009 | cur_freq, cpu_policy->cur); | 1009 | cur_freq, cpu_policy->cur); |
| 1010 | 1010 | ||
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c new file mode 100644 index 000000000000..e1df376e709e --- /dev/null +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
| @@ -0,0 +1,586 @@ | |||
| 1 | /* | ||
| 2 | * drivers/cpufreq/cpufreq_conservative.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001 Russell King | ||
| 5 | * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>. | ||
| 6 | * Jun Nakajima <jun.nakajima@intel.com> | ||
| 7 | * (C) 2004 Alexander Clouter <alex-kernel@digriz.org.uk> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/smp.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/ctype.h> | ||
| 20 | #include <linux/cpufreq.h> | ||
| 21 | #include <linux/sysctl.h> | ||
| 22 | #include <linux/types.h> | ||
| 23 | #include <linux/fs.h> | ||
| 24 | #include <linux/sysfs.h> | ||
| 25 | #include <linux/sched.h> | ||
| 26 | #include <linux/kmod.h> | ||
| 27 | #include <linux/workqueue.h> | ||
| 28 | #include <linux/jiffies.h> | ||
| 29 | #include <linux/kernel_stat.h> | ||
| 30 | #include <linux/percpu.h> | ||
| 31 | |||
| 32 | /* | ||
| 33 | * dbs is used in this file as a shortform for demandbased switching | ||
| 34 | * It helps to keep variable names smaller, simpler | ||
| 35 | */ | ||
| 36 | |||
| 37 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | ||
| 38 | #define MIN_FREQUENCY_UP_THRESHOLD (0) | ||
| 39 | #define MAX_FREQUENCY_UP_THRESHOLD (100) | ||
| 40 | |||
| 41 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) | ||
| 42 | #define MIN_FREQUENCY_DOWN_THRESHOLD (0) | ||
| 43 | #define MAX_FREQUENCY_DOWN_THRESHOLD (100) | ||
| 44 | |||
| 45 | /* | ||
| 46 | * The polling frequency of this governor depends on the capability of | ||
| 47 | * the processor. Default polling frequency is 1000 times the transition | ||
| 48 | * latency of the processor. The governor will work on any processor with | ||
| 49 | * transition latency <= 10mS, using appropriate sampling | ||
| 50 | * rate. | ||
| 51 | * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) | ||
| 52 | * this governor will not work. | ||
| 53 | * All times here are in uS. | ||
| 54 | */ | ||
| 55 | static unsigned int def_sampling_rate; | ||
| 56 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) | ||
| 57 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | ||
| 58 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (100000) | ||
| 59 | #define DEF_SAMPLING_DOWN_FACTOR (5) | ||
| 60 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | ||
| 61 | |||
| 62 | static void do_dbs_timer(void *data); | ||
| 63 | |||
| 64 | struct cpu_dbs_info_s { | ||
| 65 | struct cpufreq_policy *cur_policy; | ||
| 66 | unsigned int prev_cpu_idle_up; | ||
| 67 | unsigned int prev_cpu_idle_down; | ||
| 68 | unsigned int enable; | ||
| 69 | }; | ||
| 70 | static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); | ||
| 71 | |||
| 72 | static unsigned int dbs_enable; /* number of CPUs using this policy */ | ||
| 73 | |||
| 74 | static DECLARE_MUTEX (dbs_sem); | ||
| 75 | static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); | ||
| 76 | |||
| 77 | struct dbs_tuners { | ||
| 78 | unsigned int sampling_rate; | ||
| 79 | unsigned int sampling_down_factor; | ||
| 80 | unsigned int up_threshold; | ||
| 81 | unsigned int down_threshold; | ||
| 82 | unsigned int ignore_nice; | ||
| 83 | unsigned int freq_step; | ||
| 84 | }; | ||
| 85 | |||
| 86 | static struct dbs_tuners dbs_tuners_ins = { | ||
| 87 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | ||
| 88 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | ||
| 89 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | ||
| 93 | { | ||
| 94 | return kstat_cpu(cpu).cpustat.idle + | ||
| 95 | kstat_cpu(cpu).cpustat.iowait + | ||
| 96 | ( !dbs_tuners_ins.ignore_nice ? | ||
| 97 | kstat_cpu(cpu).cpustat.nice : | ||
| 98 | 0); | ||
| 99 | } | ||
| 100 | |||
| 101 | /************************** sysfs interface ************************/ | ||
| 102 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | ||
| 103 | { | ||
| 104 | return sprintf (buf, "%u\n", MAX_SAMPLING_RATE); | ||
| 105 | } | ||
| 106 | |||
| 107 | static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) | ||
| 108 | { | ||
| 109 | return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); | ||
| 110 | } | ||
| 111 | |||
| 112 | #define define_one_ro(_name) \ | ||
| 113 | static struct freq_attr _name = \ | ||
| 114 | __ATTR(_name, 0444, show_##_name, NULL) | ||
| 115 | |||
| 116 | define_one_ro(sampling_rate_max); | ||
| 117 | define_one_ro(sampling_rate_min); | ||
| 118 | |||
| 119 | /* cpufreq_conservative Governor Tunables */ | ||
| 120 | #define show_one(file_name, object) \ | ||
| 121 | static ssize_t show_##file_name \ | ||
| 122 | (struct cpufreq_policy *unused, char *buf) \ | ||
| 123 | { \ | ||
| 124 | return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ | ||
| 125 | } | ||
| 126 | show_one(sampling_rate, sampling_rate); | ||
| 127 | show_one(sampling_down_factor, sampling_down_factor); | ||
| 128 | show_one(up_threshold, up_threshold); | ||
| 129 | show_one(down_threshold, down_threshold); | ||
| 130 | show_one(ignore_nice, ignore_nice); | ||
| 131 | show_one(freq_step, freq_step); | ||
| 132 | |||
| 133 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | ||
| 134 | const char *buf, size_t count) | ||
| 135 | { | ||
| 136 | unsigned int input; | ||
| 137 | int ret; | ||
| 138 | ret = sscanf (buf, "%u", &input); | ||
| 139 | if (ret != 1 ) | ||
| 140 | return -EINVAL; | ||
| 141 | |||
| 142 | down(&dbs_sem); | ||
| 143 | dbs_tuners_ins.sampling_down_factor = input; | ||
| 144 | up(&dbs_sem); | ||
| 145 | |||
| 146 | return count; | ||
| 147 | } | ||
| 148 | |||
| 149 | static ssize_t store_sampling_rate(struct cpufreq_policy *unused, | ||
| 150 | const char *buf, size_t count) | ||
| 151 | { | ||
| 152 | unsigned int input; | ||
| 153 | int ret; | ||
| 154 | ret = sscanf (buf, "%u", &input); | ||
| 155 | |||
| 156 | down(&dbs_sem); | ||
| 157 | if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { | ||
| 158 | up(&dbs_sem); | ||
| 159 | return -EINVAL; | ||
| 160 | } | ||
| 161 | |||
| 162 | dbs_tuners_ins.sampling_rate = input; | ||
| 163 | up(&dbs_sem); | ||
| 164 | |||
| 165 | return count; | ||
| 166 | } | ||
| 167 | |||
| 168 | static ssize_t store_up_threshold(struct cpufreq_policy *unused, | ||
| 169 | const char *buf, size_t count) | ||
| 170 | { | ||
| 171 | unsigned int input; | ||
| 172 | int ret; | ||
| 173 | ret = sscanf (buf, "%u", &input); | ||
| 174 | |||
| 175 | down(&dbs_sem); | ||
| 176 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | ||
| 177 | input < MIN_FREQUENCY_UP_THRESHOLD || | ||
| 178 | input <= dbs_tuners_ins.down_threshold) { | ||
| 179 | up(&dbs_sem); | ||
| 180 | return -EINVAL; | ||
| 181 | } | ||
| 182 | |||
| 183 | dbs_tuners_ins.up_threshold = input; | ||
| 184 | up(&dbs_sem); | ||
| 185 | |||
| 186 | return count; | ||
| 187 | } | ||
| 188 | |||
| 189 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | ||
| 190 | const char *buf, size_t count) | ||
| 191 | { | ||
| 192 | unsigned int input; | ||
| 193 | int ret; | ||
| 194 | ret = sscanf (buf, "%u", &input); | ||
| 195 | |||
| 196 | down(&dbs_sem); | ||
| 197 | if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || | ||
| 198 | input < MIN_FREQUENCY_DOWN_THRESHOLD || | ||
| 199 | input >= dbs_tuners_ins.up_threshold) { | ||
| 200 | up(&dbs_sem); | ||
| 201 | return -EINVAL; | ||
| 202 | } | ||
| 203 | |||
| 204 | dbs_tuners_ins.down_threshold = input; | ||
| 205 | up(&dbs_sem); | ||
| 206 | |||
| 207 | return count; | ||
| 208 | } | ||
| 209 | |||
| 210 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, | ||
| 211 | const char *buf, size_t count) | ||
| 212 | { | ||
| 213 | unsigned int input; | ||
| 214 | int ret; | ||
| 215 | |||
| 216 | unsigned int j; | ||
| 217 | |||
| 218 | ret = sscanf (buf, "%u", &input); | ||
| 219 | if ( ret != 1 ) | ||
| 220 | return -EINVAL; | ||
| 221 | |||
| 222 | if ( input > 1 ) | ||
| 223 | input = 1; | ||
| 224 | |||
| 225 | down(&dbs_sem); | ||
| 226 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ | ||
| 227 | up(&dbs_sem); | ||
| 228 | return count; | ||
| 229 | } | ||
| 230 | dbs_tuners_ins.ignore_nice = input; | ||
| 231 | |||
| 232 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ | ||
| 233 | for_each_online_cpu(j) { | ||
| 234 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 235 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 236 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
| 237 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | ||
| 238 | } | ||
| 239 | up(&dbs_sem); | ||
| 240 | |||
| 241 | return count; | ||
| 242 | } | ||
| 243 | |||
| 244 | static ssize_t store_freq_step(struct cpufreq_policy *policy, | ||
| 245 | const char *buf, size_t count) | ||
| 246 | { | ||
| 247 | unsigned int input; | ||
| 248 | int ret; | ||
| 249 | |||
| 250 | ret = sscanf (buf, "%u", &input); | ||
| 251 | |||
| 252 | if ( ret != 1 ) | ||
| 253 | return -EINVAL; | ||
| 254 | |||
| 255 | if ( input > 100 ) | ||
| 256 | input = 100; | ||
| 257 | |||
| 258 | /* no need to test here if freq_step is zero as the user might actually | ||
| 259 | * want this, they would be crazy though :) */ | ||
| 260 | down(&dbs_sem); | ||
| 261 | dbs_tuners_ins.freq_step = input; | ||
| 262 | up(&dbs_sem); | ||
| 263 | |||
| 264 | return count; | ||
| 265 | } | ||
| 266 | |||
| 267 | #define define_one_rw(_name) \ | ||
| 268 | static struct freq_attr _name = \ | ||
| 269 | __ATTR(_name, 0644, show_##_name, store_##_name) | ||
| 270 | |||
| 271 | define_one_rw(sampling_rate); | ||
| 272 | define_one_rw(sampling_down_factor); | ||
| 273 | define_one_rw(up_threshold); | ||
| 274 | define_one_rw(down_threshold); | ||
| 275 | define_one_rw(ignore_nice); | ||
| 276 | define_one_rw(freq_step); | ||
| 277 | |||
| 278 | static struct attribute * dbs_attributes[] = { | ||
| 279 | &sampling_rate_max.attr, | ||
| 280 | &sampling_rate_min.attr, | ||
| 281 | &sampling_rate.attr, | ||
| 282 | &sampling_down_factor.attr, | ||
| 283 | &up_threshold.attr, | ||
| 284 | &down_threshold.attr, | ||
| 285 | &ignore_nice.attr, | ||
| 286 | &freq_step.attr, | ||
| 287 | NULL | ||
| 288 | }; | ||
| 289 | |||
| 290 | static struct attribute_group dbs_attr_group = { | ||
| 291 | .attrs = dbs_attributes, | ||
| 292 | .name = "conservative", | ||
| 293 | }; | ||
| 294 | |||
| 295 | /************************** sysfs end ************************/ | ||
| 296 | |||
| 297 | static void dbs_check_cpu(int cpu) | ||
| 298 | { | ||
| 299 | unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; | ||
| 300 | unsigned int freq_step; | ||
| 301 | unsigned int freq_down_sampling_rate; | ||
| 302 | static int down_skip[NR_CPUS]; | ||
| 303 | static int requested_freq[NR_CPUS]; | ||
| 304 | static unsigned short init_flag = 0; | ||
| 305 | struct cpu_dbs_info_s *this_dbs_info; | ||
| 306 | struct cpu_dbs_info_s *dbs_info; | ||
| 307 | |||
| 308 | struct cpufreq_policy *policy; | ||
| 309 | unsigned int j; | ||
| 310 | |||
| 311 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
| 312 | if (!this_dbs_info->enable) | ||
| 313 | return; | ||
| 314 | |||
| 315 | policy = this_dbs_info->cur_policy; | ||
| 316 | |||
| 317 | if ( init_flag == 0 ) { | ||
| 318 | for ( /* NULL */; init_flag < NR_CPUS; init_flag++ ) { | ||
| 319 | dbs_info = &per_cpu(cpu_dbs_info, init_flag); | ||
| 320 | requested_freq[cpu] = dbs_info->cur_policy->cur; | ||
| 321 | } | ||
| 322 | init_flag = 1; | ||
| 323 | } | ||
| 324 | |||
| 325 | /* | ||
| 326 | * The default safe range is 20% to 80% | ||
| 327 | * Every sampling_rate, we check | ||
| 328 | * - If current idle time is less than 20%, then we try to | ||
| 329 | * increase frequency | ||
| 330 | * Every sampling_rate*sampling_down_factor, we check | ||
| 331 | * - If current idle time is more than 80%, then we try to | ||
| 332 | * decrease frequency | ||
| 333 | * | ||
| 334 | * Any frequency increase takes it to the maximum frequency. | ||
| 335 | * Frequency reduction happens at minimum steps of | ||
| 336 | * 5% (default) of max_frequency | ||
| 337 | */ | ||
| 338 | |||
| 339 | /* Check for frequency increase */ | ||
| 340 | |||
| 341 | idle_ticks = UINT_MAX; | ||
| 342 | for_each_cpu_mask(j, policy->cpus) { | ||
| 343 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
| 344 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 345 | |||
| 346 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 347 | /* Check for frequency increase */ | ||
| 348 | total_idle_ticks = get_cpu_idle_time(j); | ||
| 349 | tmp_idle_ticks = total_idle_ticks - | ||
| 350 | j_dbs_info->prev_cpu_idle_up; | ||
| 351 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | ||
| 352 | |||
| 353 | if (tmp_idle_ticks < idle_ticks) | ||
| 354 | idle_ticks = tmp_idle_ticks; | ||
| 355 | } | ||
| 356 | |||
| 357 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
| 358 | idle_ticks *= 100; | ||
| 359 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | ||
| 360 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | ||
| 361 | |||
| 362 | if (idle_ticks < up_idle_ticks) { | ||
| 363 | down_skip[cpu] = 0; | ||
| 364 | for_each_cpu_mask(j, policy->cpus) { | ||
| 365 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 366 | |||
| 367 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 368 | j_dbs_info->prev_cpu_idle_down = | ||
| 369 | j_dbs_info->prev_cpu_idle_up; | ||
| 370 | } | ||
| 371 | /* if we are already at full speed then break out early */ | ||
| 372 | if (requested_freq[cpu] == policy->max) | ||
| 373 | return; | ||
| 374 | |||
| 375 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; | ||
| 376 | |||
| 377 | /* max freq cannot be less than 100. But who knows.... */ | ||
| 378 | if (unlikely(freq_step == 0)) | ||
| 379 | freq_step = 5; | ||
| 380 | |||
| 381 | requested_freq[cpu] += freq_step; | ||
| 382 | if (requested_freq[cpu] > policy->max) | ||
| 383 | requested_freq[cpu] = policy->max; | ||
| 384 | |||
| 385 | __cpufreq_driver_target(policy, requested_freq[cpu], | ||
| 386 | CPUFREQ_RELATION_H); | ||
| 387 | return; | ||
| 388 | } | ||
| 389 | |||
| 390 | /* Check for frequency decrease */ | ||
| 391 | down_skip[cpu]++; | ||
| 392 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) | ||
| 393 | return; | ||
| 394 | |||
| 395 | idle_ticks = UINT_MAX; | ||
| 396 | for_each_cpu_mask(j, policy->cpus) { | ||
| 397 | unsigned int tmp_idle_ticks, total_idle_ticks; | ||
| 398 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 399 | |||
| 400 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 401 | total_idle_ticks = j_dbs_info->prev_cpu_idle_up; | ||
| 402 | tmp_idle_ticks = total_idle_ticks - | ||
| 403 | j_dbs_info->prev_cpu_idle_down; | ||
| 404 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
| 405 | |||
| 406 | if (tmp_idle_ticks < idle_ticks) | ||
| 407 | idle_ticks = tmp_idle_ticks; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
| 411 | idle_ticks *= 100; | ||
| 412 | down_skip[cpu] = 0; | ||
| 413 | |||
| 414 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | ||
| 415 | dbs_tuners_ins.sampling_down_factor; | ||
| 416 | down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * | ||
| 417 | usecs_to_jiffies(freq_down_sampling_rate); | ||
| 418 | |||
| 419 | if (idle_ticks > down_idle_ticks) { | ||
| 420 | /* if we are already at the lowest speed then break out early | ||
| 421 | * or if we 'cannot' reduce the speed as the user might want | ||
| 422 | * freq_step to be zero */ | ||
| 423 | if (requested_freq[cpu] == policy->min | ||
| 424 | || dbs_tuners_ins.freq_step == 0) | ||
| 425 | return; | ||
| 426 | |||
| 427 | freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; | ||
| 428 | |||
| 429 | /* max freq cannot be less than 100. But who knows.... */ | ||
| 430 | if (unlikely(freq_step == 0)) | ||
| 431 | freq_step = 5; | ||
| 432 | |||
| 433 | requested_freq[cpu] -= freq_step; | ||
| 434 | if (requested_freq[cpu] < policy->min) | ||
| 435 | requested_freq[cpu] = policy->min; | ||
| 436 | |||
| 437 | __cpufreq_driver_target(policy, | ||
| 438 | requested_freq[cpu], | ||
| 439 | CPUFREQ_RELATION_H); | ||
| 440 | return; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | static void do_dbs_timer(void *data) | ||
| 445 | { | ||
| 446 | int i; | ||
| 447 | down(&dbs_sem); | ||
| 448 | for_each_online_cpu(i) | ||
| 449 | dbs_check_cpu(i); | ||
| 450 | schedule_delayed_work(&dbs_work, | ||
| 451 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
| 452 | up(&dbs_sem); | ||
| 453 | } | ||
| 454 | |||
| 455 | static inline void dbs_timer_init(void) | ||
| 456 | { | ||
| 457 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | ||
| 458 | schedule_delayed_work(&dbs_work, | ||
| 459 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | ||
| 460 | return; | ||
| 461 | } | ||
| 462 | |||
| 463 | static inline void dbs_timer_exit(void) | ||
| 464 | { | ||
| 465 | cancel_delayed_work(&dbs_work); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | |||
| 469 | static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | ||
| 470 | unsigned int event) | ||
| 471 | { | ||
| 472 | unsigned int cpu = policy->cpu; | ||
| 473 | struct cpu_dbs_info_s *this_dbs_info; | ||
| 474 | unsigned int j; | ||
| 475 | |||
| 476 | this_dbs_info = &per_cpu(cpu_dbs_info, cpu); | ||
| 477 | |||
| 478 | switch (event) { | ||
| 479 | case CPUFREQ_GOV_START: | ||
| 480 | if ((!cpu_online(cpu)) || | ||
| 481 | (!policy->cur)) | ||
| 482 | return -EINVAL; | ||
| 483 | |||
| 484 | if (policy->cpuinfo.transition_latency > | ||
| 485 | (TRANSITION_LATENCY_LIMIT * 1000)) | ||
| 486 | return -EINVAL; | ||
| 487 | if (this_dbs_info->enable) /* Already enabled */ | ||
| 488 | break; | ||
| 489 | |||
| 490 | down(&dbs_sem); | ||
| 491 | for_each_cpu_mask(j, policy->cpus) { | ||
| 492 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 493 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 494 | j_dbs_info->cur_policy = policy; | ||
| 495 | |||
| 496 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
| 497 | j_dbs_info->prev_cpu_idle_down | ||
| 498 | = j_dbs_info->prev_cpu_idle_up; | ||
| 499 | } | ||
| 500 | this_dbs_info->enable = 1; | ||
| 501 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | ||
| 502 | dbs_enable++; | ||
| 503 | /* | ||
| 504 | * Start the timerschedule work, when this governor | ||
| 505 | * is used for first time | ||
| 506 | */ | ||
| 507 | if (dbs_enable == 1) { | ||
| 508 | unsigned int latency; | ||
| 509 | /* policy latency is in nS. Convert it to uS first */ | ||
| 510 | |||
| 511 | latency = policy->cpuinfo.transition_latency; | ||
| 512 | if (latency < 1000) | ||
| 513 | latency = 1000; | ||
| 514 | |||
| 515 | def_sampling_rate = (latency / 1000) * | ||
| 516 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | ||
| 517 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | ||
| 518 | dbs_tuners_ins.ignore_nice = 0; | ||
| 519 | dbs_tuners_ins.freq_step = 5; | ||
| 520 | |||
| 521 | dbs_timer_init(); | ||
| 522 | } | ||
| 523 | |||
| 524 | up(&dbs_sem); | ||
| 525 | break; | ||
| 526 | |||
| 527 | case CPUFREQ_GOV_STOP: | ||
| 528 | down(&dbs_sem); | ||
| 529 | this_dbs_info->enable = 0; | ||
| 530 | sysfs_remove_group(&policy->kobj, &dbs_attr_group); | ||
| 531 | dbs_enable--; | ||
| 532 | /* | ||
| 533 | * Stop the timerschedule work, when this governor | ||
| 534 | * is used for first time | ||
| 535 | */ | ||
| 536 | if (dbs_enable == 0) | ||
| 537 | dbs_timer_exit(); | ||
| 538 | |||
| 539 | up(&dbs_sem); | ||
| 540 | |||
| 541 | break; | ||
| 542 | |||
| 543 | case CPUFREQ_GOV_LIMITS: | ||
| 544 | down(&dbs_sem); | ||
| 545 | if (policy->max < this_dbs_info->cur_policy->cur) | ||
| 546 | __cpufreq_driver_target( | ||
| 547 | this_dbs_info->cur_policy, | ||
| 548 | policy->max, CPUFREQ_RELATION_H); | ||
| 549 | else if (policy->min > this_dbs_info->cur_policy->cur) | ||
| 550 | __cpufreq_driver_target( | ||
| 551 | this_dbs_info->cur_policy, | ||
| 552 | policy->min, CPUFREQ_RELATION_L); | ||
| 553 | up(&dbs_sem); | ||
| 554 | break; | ||
| 555 | } | ||
| 556 | return 0; | ||
| 557 | } | ||
| 558 | |||
| 559 | static struct cpufreq_governor cpufreq_gov_dbs = { | ||
| 560 | .name = "conservative", | ||
| 561 | .governor = cpufreq_governor_dbs, | ||
| 562 | .owner = THIS_MODULE, | ||
| 563 | }; | ||
| 564 | |||
| 565 | static int __init cpufreq_gov_dbs_init(void) | ||
| 566 | { | ||
| 567 | return cpufreq_register_governor(&cpufreq_gov_dbs); | ||
| 568 | } | ||
| 569 | |||
| 570 | static void __exit cpufreq_gov_dbs_exit(void) | ||
| 571 | { | ||
| 572 | /* Make sure that the scheduled work is indeed not running */ | ||
| 573 | flush_scheduled_work(); | ||
| 574 | |||
| 575 | cpufreq_unregister_governor(&cpufreq_gov_dbs); | ||
| 576 | } | ||
| 577 | |||
| 578 | |||
| 579 | MODULE_AUTHOR ("Alexander Clouter <alex-kernel@digriz.org.uk>"); | ||
| 580 | MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " | ||
| 581 | "Low Latency Frequency Transition capable processors " | ||
| 582 | "optimised for use in a battery environment"); | ||
| 583 | MODULE_LICENSE ("GPL"); | ||
| 584 | |||
| 585 | module_init(cpufreq_gov_dbs_init); | ||
| 586 | module_exit(cpufreq_gov_dbs_exit); | ||
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8d83a21c6477..c1fc9c62bb51 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
| @@ -34,13 +34,9 @@ | |||
| 34 | */ | 34 | */ |
| 35 | 35 | ||
| 36 | #define DEF_FREQUENCY_UP_THRESHOLD (80) | 36 | #define DEF_FREQUENCY_UP_THRESHOLD (80) |
| 37 | #define MIN_FREQUENCY_UP_THRESHOLD (0) | 37 | #define MIN_FREQUENCY_UP_THRESHOLD (11) |
| 38 | #define MAX_FREQUENCY_UP_THRESHOLD (100) | 38 | #define MAX_FREQUENCY_UP_THRESHOLD (100) |
| 39 | 39 | ||
| 40 | #define DEF_FREQUENCY_DOWN_THRESHOLD (20) | ||
| 41 | #define MIN_FREQUENCY_DOWN_THRESHOLD (0) | ||
| 42 | #define MAX_FREQUENCY_DOWN_THRESHOLD (100) | ||
| 43 | |||
| 44 | /* | 40 | /* |
| 45 | * The polling frequency of this governor depends on the capability of | 41 | * The polling frequency of this governor depends on the capability of |
| 46 | * the processor. Default polling frequency is 1000 times the transition | 42 | * the processor. Default polling frequency is 1000 times the transition |
| @@ -55,9 +51,9 @@ static unsigned int def_sampling_rate; | |||
| 55 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) | 51 | #define MIN_SAMPLING_RATE (def_sampling_rate / 2) |
| 56 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) | 52 | #define MAX_SAMPLING_RATE (500 * def_sampling_rate) |
| 57 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 53 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
| 58 | #define DEF_SAMPLING_DOWN_FACTOR (10) | 54 | #define DEF_SAMPLING_DOWN_FACTOR (1) |
| 55 | #define MAX_SAMPLING_DOWN_FACTOR (10) | ||
| 59 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 56 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) |
| 60 | #define sampling_rate_in_HZ(x) (((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000))) | ||
| 61 | 57 | ||
| 62 | static void do_dbs_timer(void *data); | 58 | static void do_dbs_timer(void *data); |
| 63 | 59 | ||
| @@ -78,15 +74,23 @@ struct dbs_tuners { | |||
| 78 | unsigned int sampling_rate; | 74 | unsigned int sampling_rate; |
| 79 | unsigned int sampling_down_factor; | 75 | unsigned int sampling_down_factor; |
| 80 | unsigned int up_threshold; | 76 | unsigned int up_threshold; |
| 81 | unsigned int down_threshold; | 77 | unsigned int ignore_nice; |
| 82 | }; | 78 | }; |
| 83 | 79 | ||
| 84 | static struct dbs_tuners dbs_tuners_ins = { | 80 | static struct dbs_tuners dbs_tuners_ins = { |
| 85 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, | 81 | .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, |
| 86 | .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, | ||
| 87 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, | 82 | .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, |
| 88 | }; | 83 | }; |
| 89 | 84 | ||
| 85 | static inline unsigned int get_cpu_idle_time(unsigned int cpu) | ||
| 86 | { | ||
| 87 | return kstat_cpu(cpu).cpustat.idle + | ||
| 88 | kstat_cpu(cpu).cpustat.iowait + | ||
| 89 | ( !dbs_tuners_ins.ignore_nice ? | ||
| 90 | kstat_cpu(cpu).cpustat.nice : | ||
| 91 | 0); | ||
| 92 | } | ||
| 93 | |||
| 90 | /************************** sysfs interface ************************/ | 94 | /************************** sysfs interface ************************/ |
| 91 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) | 95 | static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) |
| 92 | { | 96 | { |
| @@ -115,7 +119,7 @@ static ssize_t show_##file_name \ | |||
| 115 | show_one(sampling_rate, sampling_rate); | 119 | show_one(sampling_rate, sampling_rate); |
| 116 | show_one(sampling_down_factor, sampling_down_factor); | 120 | show_one(sampling_down_factor, sampling_down_factor); |
| 117 | show_one(up_threshold, up_threshold); | 121 | show_one(up_threshold, up_threshold); |
| 118 | show_one(down_threshold, down_threshold); | 122 | show_one(ignore_nice, ignore_nice); |
| 119 | 123 | ||
| 120 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | 124 | static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, |
| 121 | const char *buf, size_t count) | 125 | const char *buf, size_t count) |
| @@ -126,6 +130,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, | |||
| 126 | if (ret != 1 ) | 130 | if (ret != 1 ) |
| 127 | return -EINVAL; | 131 | return -EINVAL; |
| 128 | 132 | ||
| 133 | if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) | ||
| 134 | return -EINVAL; | ||
| 135 | |||
| 129 | down(&dbs_sem); | 136 | down(&dbs_sem); |
| 130 | dbs_tuners_ins.sampling_down_factor = input; | 137 | dbs_tuners_ins.sampling_down_factor = input; |
| 131 | up(&dbs_sem); | 138 | up(&dbs_sem); |
| @@ -161,8 +168,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
| 161 | 168 | ||
| 162 | down(&dbs_sem); | 169 | down(&dbs_sem); |
| 163 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || | 170 | if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || |
| 164 | input < MIN_FREQUENCY_UP_THRESHOLD || | 171 | input < MIN_FREQUENCY_UP_THRESHOLD) { |
| 165 | input <= dbs_tuners_ins.down_threshold) { | ||
| 166 | up(&dbs_sem); | 172 | up(&dbs_sem); |
| 167 | return -EINVAL; | 173 | return -EINVAL; |
| 168 | } | 174 | } |
| @@ -173,22 +179,35 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
| 173 | return count; | 179 | return count; |
| 174 | } | 180 | } |
| 175 | 181 | ||
| 176 | static ssize_t store_down_threshold(struct cpufreq_policy *unused, | 182 | static ssize_t store_ignore_nice(struct cpufreq_policy *policy, |
| 177 | const char *buf, size_t count) | 183 | const char *buf, size_t count) |
| 178 | { | 184 | { |
| 179 | unsigned int input; | 185 | unsigned int input; |
| 180 | int ret; | 186 | int ret; |
| 187 | |||
| 188 | unsigned int j; | ||
| 189 | |||
| 181 | ret = sscanf (buf, "%u", &input); | 190 | ret = sscanf (buf, "%u", &input); |
| 191 | if ( ret != 1 ) | ||
| 192 | return -EINVAL; | ||
| 182 | 193 | ||
| 194 | if ( input > 1 ) | ||
| 195 | input = 1; | ||
| 196 | |||
| 183 | down(&dbs_sem); | 197 | down(&dbs_sem); |
| 184 | if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || | 198 | if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ |
| 185 | input < MIN_FREQUENCY_DOWN_THRESHOLD || | ||
| 186 | input >= dbs_tuners_ins.up_threshold) { | ||
| 187 | up(&dbs_sem); | 199 | up(&dbs_sem); |
| 188 | return -EINVAL; | 200 | return count; |
| 189 | } | 201 | } |
| 202 | dbs_tuners_ins.ignore_nice = input; | ||
| 190 | 203 | ||
| 191 | dbs_tuners_ins.down_threshold = input; | 204 | /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ |
| 205 | for_each_online_cpu(j) { | ||
| 206 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 207 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 208 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); | ||
| 209 | j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; | ||
| 210 | } | ||
| 192 | up(&dbs_sem); | 211 | up(&dbs_sem); |
| 193 | 212 | ||
| 194 | return count; | 213 | return count; |
| @@ -201,7 +220,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name) | |||
| 201 | define_one_rw(sampling_rate); | 220 | define_one_rw(sampling_rate); |
| 202 | define_one_rw(sampling_down_factor); | 221 | define_one_rw(sampling_down_factor); |
| 203 | define_one_rw(up_threshold); | 222 | define_one_rw(up_threshold); |
| 204 | define_one_rw(down_threshold); | 223 | define_one_rw(ignore_nice); |
| 205 | 224 | ||
| 206 | static struct attribute * dbs_attributes[] = { | 225 | static struct attribute * dbs_attributes[] = { |
| 207 | &sampling_rate_max.attr, | 226 | &sampling_rate_max.attr, |
| @@ -209,7 +228,7 @@ static struct attribute * dbs_attributes[] = { | |||
| 209 | &sampling_rate.attr, | 228 | &sampling_rate.attr, |
| 210 | &sampling_down_factor.attr, | 229 | &sampling_down_factor.attr, |
| 211 | &up_threshold.attr, | 230 | &up_threshold.attr, |
| 212 | &down_threshold.attr, | 231 | &ignore_nice.attr, |
| 213 | NULL | 232 | NULL |
| 214 | }; | 233 | }; |
| 215 | 234 | ||
| @@ -222,9 +241,8 @@ static struct attribute_group dbs_attr_group = { | |||
| 222 | 241 | ||
| 223 | static void dbs_check_cpu(int cpu) | 242 | static void dbs_check_cpu(int cpu) |
| 224 | { | 243 | { |
| 225 | unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; | 244 | unsigned int idle_ticks, up_idle_ticks, total_ticks; |
| 226 | unsigned int total_idle_ticks; | 245 | unsigned int freq_next; |
| 227 | unsigned int freq_down_step; | ||
| 228 | unsigned int freq_down_sampling_rate; | 246 | unsigned int freq_down_sampling_rate; |
| 229 | static int down_skip[NR_CPUS]; | 247 | static int down_skip[NR_CPUS]; |
| 230 | struct cpu_dbs_info_s *this_dbs_info; | 248 | struct cpu_dbs_info_s *this_dbs_info; |
| @@ -238,38 +256,25 @@ static void dbs_check_cpu(int cpu) | |||
| 238 | 256 | ||
| 239 | policy = this_dbs_info->cur_policy; | 257 | policy = this_dbs_info->cur_policy; |
| 240 | /* | 258 | /* |
| 241 | * The default safe range is 20% to 80% | 259 | * Every sampling_rate, we check, if current idle time is less |
| 242 | * Every sampling_rate, we check | 260 | * than 20% (default), then we try to increase frequency |
| 243 | * - If current idle time is less than 20%, then we try to | 261 | * Every sampling_rate*sampling_down_factor, we look for a the lowest |
| 244 | * increase frequency | 262 | * frequency which can sustain the load while keeping idle time over |
| 245 | * Every sampling_rate*sampling_down_factor, we check | 263 | * 30%. If such a frequency exist, we try to decrease to this frequency. |
| 246 | * - If current idle time is more than 80%, then we try to | ||
| 247 | * decrease frequency | ||
| 248 | * | 264 | * |
| 249 | * Any frequency increase takes it to the maximum frequency. | 265 | * Any frequency increase takes it to the maximum frequency. |
| 250 | * Frequency reduction happens at minimum steps of | 266 | * Frequency reduction happens at minimum steps of |
| 251 | * 5% of max_frequency | 267 | * 5% (default) of current frequency |
| 252 | */ | 268 | */ |
| 253 | 269 | ||
| 254 | /* Check for frequency increase */ | 270 | /* Check for frequency increase */ |
| 255 | total_idle_ticks = kstat_cpu(cpu).cpustat.idle + | 271 | idle_ticks = UINT_MAX; |
| 256 | kstat_cpu(cpu).cpustat.iowait; | ||
| 257 | idle_ticks = total_idle_ticks - | ||
| 258 | this_dbs_info->prev_cpu_idle_up; | ||
| 259 | this_dbs_info->prev_cpu_idle_up = total_idle_ticks; | ||
| 260 | |||
| 261 | |||
| 262 | for_each_cpu_mask(j, policy->cpus) { | 272 | for_each_cpu_mask(j, policy->cpus) { |
| 263 | unsigned int tmp_idle_ticks; | 273 | unsigned int tmp_idle_ticks, total_idle_ticks; |
| 264 | struct cpu_dbs_info_s *j_dbs_info; | 274 | struct cpu_dbs_info_s *j_dbs_info; |
| 265 | 275 | ||
| 266 | if (j == cpu) | ||
| 267 | continue; | ||
| 268 | |||
| 269 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 276 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
| 270 | /* Check for frequency increase */ | 277 | total_idle_ticks = get_cpu_idle_time(j); |
| 271 | total_idle_ticks = kstat_cpu(j).cpustat.idle + | ||
| 272 | kstat_cpu(j).cpustat.iowait; | ||
| 273 | tmp_idle_ticks = total_idle_ticks - | 278 | tmp_idle_ticks = total_idle_ticks - |
| 274 | j_dbs_info->prev_cpu_idle_up; | 279 | j_dbs_info->prev_cpu_idle_up; |
| 275 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; | 280 | j_dbs_info->prev_cpu_idle_up = total_idle_ticks; |
| @@ -281,13 +286,23 @@ static void dbs_check_cpu(int cpu) | |||
| 281 | /* Scale idle ticks by 100 and compare with up and down ticks */ | 286 | /* Scale idle ticks by 100 and compare with up and down ticks */ |
| 282 | idle_ticks *= 100; | 287 | idle_ticks *= 100; |
| 283 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * | 288 | up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * |
| 284 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate); | 289 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
| 285 | 290 | ||
| 286 | if (idle_ticks < up_idle_ticks) { | 291 | if (idle_ticks < up_idle_ticks) { |
| 292 | down_skip[cpu] = 0; | ||
| 293 | for_each_cpu_mask(j, policy->cpus) { | ||
| 294 | struct cpu_dbs_info_s *j_dbs_info; | ||
| 295 | |||
| 296 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | ||
| 297 | j_dbs_info->prev_cpu_idle_down = | ||
| 298 | j_dbs_info->prev_cpu_idle_up; | ||
| 299 | } | ||
| 300 | /* if we are already at full speed then break out early */ | ||
| 301 | if (policy->cur == policy->max) | ||
| 302 | return; | ||
| 303 | |||
| 287 | __cpufreq_driver_target(policy, policy->max, | 304 | __cpufreq_driver_target(policy, policy->max, |
| 288 | CPUFREQ_RELATION_H); | 305 | CPUFREQ_RELATION_H); |
| 289 | down_skip[cpu] = 0; | ||
| 290 | this_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
| 291 | return; | 306 | return; |
| 292 | } | 307 | } |
| 293 | 308 | ||
| @@ -296,23 +311,14 @@ static void dbs_check_cpu(int cpu) | |||
| 296 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) | 311 | if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) |
| 297 | return; | 312 | return; |
| 298 | 313 | ||
| 299 | total_idle_ticks = kstat_cpu(cpu).cpustat.idle + | 314 | idle_ticks = UINT_MAX; |
| 300 | kstat_cpu(cpu).cpustat.iowait; | ||
| 301 | idle_ticks = total_idle_ticks - | ||
| 302 | this_dbs_info->prev_cpu_idle_down; | ||
| 303 | this_dbs_info->prev_cpu_idle_down = total_idle_ticks; | ||
| 304 | |||
| 305 | for_each_cpu_mask(j, policy->cpus) { | 315 | for_each_cpu_mask(j, policy->cpus) { |
| 306 | unsigned int tmp_idle_ticks; | 316 | unsigned int tmp_idle_ticks, total_idle_ticks; |
| 307 | struct cpu_dbs_info_s *j_dbs_info; | 317 | struct cpu_dbs_info_s *j_dbs_info; |
| 308 | 318 | ||
| 309 | if (j == cpu) | ||
| 310 | continue; | ||
| 311 | |||
| 312 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 319 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
| 313 | /* Check for frequency increase */ | 320 | /* Check for frequency decrease */ |
| 314 | total_idle_ticks = kstat_cpu(j).cpustat.idle + | 321 | total_idle_ticks = j_dbs_info->prev_cpu_idle_up; |
| 315 | kstat_cpu(j).cpustat.iowait; | ||
| 316 | tmp_idle_ticks = total_idle_ticks - | 322 | tmp_idle_ticks = total_idle_ticks - |
| 317 | j_dbs_info->prev_cpu_idle_down; | 323 | j_dbs_info->prev_cpu_idle_down; |
| 318 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; | 324 | j_dbs_info->prev_cpu_idle_down = total_idle_ticks; |
| @@ -321,38 +327,37 @@ static void dbs_check_cpu(int cpu) | |||
| 321 | idle_ticks = tmp_idle_ticks; | 327 | idle_ticks = tmp_idle_ticks; |
| 322 | } | 328 | } |
| 323 | 329 | ||
| 324 | /* Scale idle ticks by 100 and compare with up and down ticks */ | ||
| 325 | idle_ticks *= 100; | ||
| 326 | down_skip[cpu] = 0; | 330 | down_skip[cpu] = 0; |
| 331 | /* if we cannot reduce the frequency anymore, break out early */ | ||
| 332 | if (policy->cur == policy->min) | ||
| 333 | return; | ||
| 327 | 334 | ||
| 335 | /* Compute how many ticks there are between two measurements */ | ||
| 328 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * | 336 | freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * |
| 329 | dbs_tuners_ins.sampling_down_factor; | 337 | dbs_tuners_ins.sampling_down_factor; |
| 330 | down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * | 338 | total_ticks = usecs_to_jiffies(freq_down_sampling_rate); |
| 331 | sampling_rate_in_HZ(freq_down_sampling_rate); | ||
| 332 | 339 | ||
| 333 | if (idle_ticks > down_idle_ticks ) { | 340 | /* |
| 334 | freq_down_step = (5 * policy->max) / 100; | 341 | * The optimal frequency is the frequency that is the lowest that |
| 335 | 342 | * can support the current CPU usage without triggering the up | |
| 336 | /* max freq cannot be less than 100. But who knows.... */ | 343 | * policy. To be safe, we focus 10 points under the threshold. |
| 337 | if (unlikely(freq_down_step == 0)) | 344 | */ |
| 338 | freq_down_step = 5; | 345 | freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks; |
| 346 | freq_next = (freq_next * policy->cur) / | ||
| 347 | (dbs_tuners_ins.up_threshold - 10); | ||
| 339 | 348 | ||
| 340 | __cpufreq_driver_target(policy, | 349 | if (freq_next <= ((policy->cur * 95) / 100)) |
| 341 | policy->cur - freq_down_step, | 350 | __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); |
| 342 | CPUFREQ_RELATION_H); | ||
| 343 | return; | ||
| 344 | } | ||
| 345 | } | 351 | } |
| 346 | 352 | ||
| 347 | static void do_dbs_timer(void *data) | 353 | static void do_dbs_timer(void *data) |
| 348 | { | 354 | { |
| 349 | int i; | 355 | int i; |
| 350 | down(&dbs_sem); | 356 | down(&dbs_sem); |
| 351 | for (i = 0; i < NR_CPUS; i++) | 357 | for_each_online_cpu(i) |
| 352 | if (cpu_online(i)) | 358 | dbs_check_cpu(i); |
| 353 | dbs_check_cpu(i); | ||
| 354 | schedule_delayed_work(&dbs_work, | 359 | schedule_delayed_work(&dbs_work, |
| 355 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); | 360 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
| 356 | up(&dbs_sem); | 361 | up(&dbs_sem); |
| 357 | } | 362 | } |
| 358 | 363 | ||
| @@ -360,7 +365,7 @@ static inline void dbs_timer_init(void) | |||
| 360 | { | 365 | { |
| 361 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | 366 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); |
| 362 | schedule_delayed_work(&dbs_work, | 367 | schedule_delayed_work(&dbs_work, |
| 363 | sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); | 368 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
| 364 | return; | 369 | return; |
| 365 | } | 370 | } |
| 366 | 371 | ||
| @@ -397,12 +402,9 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 397 | j_dbs_info = &per_cpu(cpu_dbs_info, j); | 402 | j_dbs_info = &per_cpu(cpu_dbs_info, j); |
| 398 | j_dbs_info->cur_policy = policy; | 403 | j_dbs_info->cur_policy = policy; |
| 399 | 404 | ||
| 400 | j_dbs_info->prev_cpu_idle_up = | 405 | j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); |
| 401 | kstat_cpu(j).cpustat.idle + | 406 | j_dbs_info->prev_cpu_idle_down |
| 402 | kstat_cpu(j).cpustat.iowait; | 407 | = j_dbs_info->prev_cpu_idle_up; |
| 403 | j_dbs_info->prev_cpu_idle_down = | ||
| 404 | kstat_cpu(j).cpustat.idle + | ||
| 405 | kstat_cpu(j).cpustat.iowait; | ||
| 406 | } | 408 | } |
| 407 | this_dbs_info->enable = 1; | 409 | this_dbs_info->enable = 1; |
| 408 | sysfs_create_group(&policy->kobj, &dbs_attr_group); | 410 | sysfs_create_group(&policy->kobj, &dbs_attr_group); |
| @@ -422,6 +424,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 422 | def_sampling_rate = (latency / 1000) * | 424 | def_sampling_rate = (latency / 1000) * |
| 423 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; | 425 | DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; |
| 424 | dbs_tuners_ins.sampling_rate = def_sampling_rate; | 426 | dbs_tuners_ins.sampling_rate = def_sampling_rate; |
| 427 | dbs_tuners_ins.ignore_nice = 0; | ||
| 425 | 428 | ||
| 426 | dbs_timer_init(); | 429 | dbs_timer_init(); |
| 427 | } | 430 | } |
| @@ -461,12 +464,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, | |||
| 461 | return 0; | 464 | return 0; |
| 462 | } | 465 | } |
| 463 | 466 | ||
| 464 | struct cpufreq_governor cpufreq_gov_dbs = { | 467 | static struct cpufreq_governor cpufreq_gov_dbs = { |
| 465 | .name = "ondemand", | 468 | .name = "ondemand", |
| 466 | .governor = cpufreq_governor_dbs, | 469 | .governor = cpufreq_governor_dbs, |
| 467 | .owner = THIS_MODULE, | 470 | .owner = THIS_MODULE, |
| 468 | }; | 471 | }; |
| 469 | EXPORT_SYMBOL(cpufreq_gov_dbs); | ||
| 470 | 472 | ||
| 471 | static int __init cpufreq_gov_dbs_init(void) | 473 | static int __init cpufreq_gov_dbs_init(void) |
| 472 | { | 474 | { |
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 2084593937c6..741b6b191e6a 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/percpu.h> | 19 | #include <linux/percpu.h> |
| 20 | #include <linux/kobject.h> | 20 | #include <linux/kobject.h> |
| 21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 22 | #include <asm/cputime.h> | ||
| 22 | 23 | ||
| 23 | static spinlock_t cpufreq_stats_lock; | 24 | static spinlock_t cpufreq_stats_lock; |
| 24 | 25 | ||
| @@ -29,20 +30,14 @@ static struct freq_attr _attr_##_name = {\ | |||
| 29 | .show = _show,\ | 30 | .show = _show,\ |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | static unsigned long | ||
| 33 | delta_time(unsigned long old, unsigned long new) | ||
| 34 | { | ||
| 35 | return (old > new) ? (old - new): (new + ~old + 1); | ||
| 36 | } | ||
| 37 | |||
| 38 | struct cpufreq_stats { | 33 | struct cpufreq_stats { |
| 39 | unsigned int cpu; | 34 | unsigned int cpu; |
| 40 | unsigned int total_trans; | 35 | unsigned int total_trans; |
| 41 | unsigned long long last_time; | 36 | unsigned long long last_time; |
| 42 | unsigned int max_state; | 37 | unsigned int max_state; |
| 43 | unsigned int state_num; | 38 | unsigned int state_num; |
| 44 | unsigned int last_index; | 39 | unsigned int last_index; |
| 45 | unsigned long long *time_in_state; | 40 | cputime64_t *time_in_state; |
| 46 | unsigned int *freq_table; | 41 | unsigned int *freq_table; |
| 47 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 42 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
| 48 | unsigned int *trans_table; | 43 | unsigned int *trans_table; |
| @@ -60,12 +55,16 @@ static int | |||
| 60 | cpufreq_stats_update (unsigned int cpu) | 55 | cpufreq_stats_update (unsigned int cpu) |
| 61 | { | 56 | { |
| 62 | struct cpufreq_stats *stat; | 57 | struct cpufreq_stats *stat; |
| 58 | unsigned long long cur_time; | ||
| 59 | |||
| 60 | cur_time = get_jiffies_64(); | ||
| 63 | spin_lock(&cpufreq_stats_lock); | 61 | spin_lock(&cpufreq_stats_lock); |
| 64 | stat = cpufreq_stats_table[cpu]; | 62 | stat = cpufreq_stats_table[cpu]; |
| 65 | if (stat->time_in_state) | 63 | if (stat->time_in_state) |
| 66 | stat->time_in_state[stat->last_index] += | 64 | stat->time_in_state[stat->last_index] = |
| 67 | delta_time(stat->last_time, jiffies); | 65 | cputime64_add(stat->time_in_state[stat->last_index], |
| 68 | stat->last_time = jiffies; | 66 | cputime_sub(cur_time, stat->last_time)); |
| 67 | stat->last_time = cur_time; | ||
| 69 | spin_unlock(&cpufreq_stats_lock); | 68 | spin_unlock(&cpufreq_stats_lock); |
| 70 | return 0; | 69 | return 0; |
| 71 | } | 70 | } |
| @@ -90,8 +89,8 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf) | |||
| 90 | return 0; | 89 | return 0; |
| 91 | cpufreq_stats_update(stat->cpu); | 90 | cpufreq_stats_update(stat->cpu); |
| 92 | for (i = 0; i < stat->state_num; i++) { | 91 | for (i = 0; i < stat->state_num; i++) { |
| 93 | len += sprintf(buf + len, "%u %llu\n", | 92 | len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], |
| 94 | stat->freq_table[i], stat->time_in_state[i]); | 93 | (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i])); |
| 95 | } | 94 | } |
| 96 | return len; | 95 | return len; |
| 97 | } | 96 | } |
| @@ -107,16 +106,30 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) | |||
| 107 | if(!stat) | 106 | if(!stat) |
| 108 | return 0; | 107 | return 0; |
| 109 | cpufreq_stats_update(stat->cpu); | 108 | cpufreq_stats_update(stat->cpu); |
| 109 | len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); | ||
| 110 | len += snprintf(buf + len, PAGE_SIZE - len, " : "); | ||
| 111 | for (i = 0; i < stat->state_num; i++) { | ||
| 112 | if (len >= PAGE_SIZE) | ||
| 113 | break; | ||
| 114 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", | ||
| 115 | stat->freq_table[i]); | ||
| 116 | } | ||
| 117 | if (len >= PAGE_SIZE) | ||
| 118 | return len; | ||
| 119 | |||
| 120 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | ||
| 121 | |||
| 110 | for (i = 0; i < stat->state_num; i++) { | 122 | for (i = 0; i < stat->state_num; i++) { |
| 111 | if (len >= PAGE_SIZE) | 123 | if (len >= PAGE_SIZE) |
| 112 | break; | 124 | break; |
| 113 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t", | 125 | |
| 126 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", | ||
| 114 | stat->freq_table[i]); | 127 | stat->freq_table[i]); |
| 115 | 128 | ||
| 116 | for (j = 0; j < stat->state_num; j++) { | 129 | for (j = 0; j < stat->state_num; j++) { |
| 117 | if (len >= PAGE_SIZE) | 130 | if (len >= PAGE_SIZE) |
| 118 | break; | 131 | break; |
| 119 | len += snprintf(buf + len, PAGE_SIZE - len, "%u\t", | 132 | len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", |
| 120 | stat->trans_table[i*stat->max_state+j]); | 133 | stat->trans_table[i*stat->max_state+j]); |
| 121 | } | 134 | } |
| 122 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 135 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
| @@ -197,7 +210,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
| 197 | count++; | 210 | count++; |
| 198 | } | 211 | } |
| 199 | 212 | ||
| 200 | alloc_size = count * sizeof(int) + count * sizeof(long long); | 213 | alloc_size = count * sizeof(int) + count * sizeof(cputime64_t); |
| 201 | 214 | ||
| 202 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS | 215 | #ifdef CONFIG_CPU_FREQ_STAT_DETAILS |
| 203 | alloc_size += count * count * sizeof(int); | 216 | alloc_size += count * count * sizeof(int); |
| @@ -224,7 +237,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, | |||
| 224 | } | 237 | } |
| 225 | stat->state_num = j; | 238 | stat->state_num = j; |
| 226 | spin_lock(&cpufreq_stats_lock); | 239 | spin_lock(&cpufreq_stats_lock); |
| 227 | stat->last_time = jiffies; | 240 | stat->last_time = get_jiffies_64(); |
| 228 | stat->last_index = freq_table_get_index(stat, policy->cur); | 241 | stat->last_index = freq_table_get_index(stat, policy->cur); |
| 229 | spin_unlock(&cpufreq_stats_lock); | 242 | spin_unlock(&cpufreq_stats_lock); |
| 230 | cpufreq_cpu_put(data); | 243 | cpufreq_cpu_put(data); |
diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 6d5df6c2efa2..df1b721154d2 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/config.h> | ||
| 14 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
| 15 | #include <linux/console.h> | 16 | #include <linux/console.h> |
| 16 | #include <linux/efi.h> | 17 | #include <linux/efi.h> |
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 35710818fe47..fdd881aee618 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge | 2 | * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004 Patrick Mochel | 4 | * Copyright (C) 2004 Patrick Mochel |
| 5 | * 2005 Rudolf Marek <r.marek@sh.cvut.cz> | ||
| 5 | * | 6 | * |
| 6 | * The 1563 southbridge is deceptively similar to the 1533, with a | 7 | * The 1563 southbridge is deceptively similar to the 1533, with a |
| 7 | * few notable exceptions. One of those happens to be the fact they | 8 | * few notable exceptions. One of those happens to be the fact they |
| @@ -57,10 +58,11 @@ | |||
| 57 | #define HST_CNTL2_BLOCK 0x05 | 58 | #define HST_CNTL2_BLOCK 0x05 |
| 58 | 59 | ||
| 59 | 60 | ||
| 61 | #define HST_CNTL2_SIZEMASK 0x38 | ||
| 60 | 62 | ||
| 61 | static unsigned short ali1563_smba; | 63 | static unsigned short ali1563_smba; |
| 62 | 64 | ||
| 63 | static int ali1563_transaction(struct i2c_adapter * a) | 65 | static int ali1563_transaction(struct i2c_adapter * a, int size) |
| 64 | { | 66 | { |
| 65 | u32 data; | 67 | u32 data; |
| 66 | int timeout; | 68 | int timeout; |
| @@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
| 73 | 75 | ||
| 74 | data = inb_p(SMB_HST_STS); | 76 | data = inb_p(SMB_HST_STS); |
| 75 | if (data & HST_STS_BAD) { | 77 | if (data & HST_STS_BAD) { |
| 76 | dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); | 78 | dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); |
| 77 | outb_p(data | HST_STS_BAD,SMB_HST_STS); | 79 | outb_p(data | HST_STS_BAD,SMB_HST_STS); |
| 78 | data = inb_p(SMB_HST_STS); | 80 | data = inb_p(SMB_HST_STS); |
| 79 | if (data & HST_STS_BAD) | 81 | if (data & HST_STS_BAD) |
| @@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a) | |||
| 94 | 96 | ||
| 95 | if (timeout && !(data & HST_STS_BAD)) | 97 | if (timeout && !(data & HST_STS_BAD)) |
| 96 | return 0; | 98 | return 0; |
| 97 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | ||
| 98 | timeout ? "Timeout " : "", | ||
| 99 | data & HST_STS_FAIL ? "Transaction Failed " : "", | ||
| 100 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | ||
| 101 | data & HST_STS_DEVERR ? "Device Error " : "", | ||
| 102 | !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); | ||
| 103 | 99 | ||
| 104 | if (!(data & HST_STS_DONE)) | 100 | if (!timeout) { |
| 101 | dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); | ||
| 105 | /* Issue 'kill' to host controller */ | 102 | /* Issue 'kill' to host controller */ |
| 106 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); | 103 | outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); |
| 107 | else | 104 | data = inb_p(SMB_HST_STS); |
| 108 | /* Issue timeout to reset all devices on bus */ | 105 | } |
| 106 | |||
| 107 | /* device error - no response, ignore the autodetection case */ | ||
| 108 | if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { | ||
| 109 | dev_err(&a->dev, "Device error!\n"); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* bus collision */ | ||
| 113 | if (data & HST_STS_BUSERR) { | ||
| 114 | dev_err(&a->dev, "Bus collision!\n"); | ||
| 115 | /* Issue timeout, hoping it helps */ | ||
| 109 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); | 116 | outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); |
| 117 | } | ||
| 118 | |||
| 119 | if (data & HST_STS_FAIL) { | ||
| 120 | dev_err(&a->dev, "Cleaning fail after KILL!\n"); | ||
| 121 | outb_p(0x0,SMB_HST_CNTL2); | ||
| 122 | } | ||
| 123 | |||
| 110 | return -1; | 124 | return -1; |
| 111 | } | 125 | } |
| 112 | 126 | ||
| @@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a) | |||
| 149 | 163 | ||
| 150 | if (timeout && !(data & HST_STS_BAD)) | 164 | if (timeout && !(data & HST_STS_BAD)) |
| 151 | return 0; | 165 | return 0; |
| 152 | dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", | 166 | dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", |
| 153 | timeout ? "Timeout " : "", | 167 | timeout ? "Timeout " : "", |
| 154 | data & HST_STS_FAIL ? "Transaction Failed " : "", | 168 | data & HST_STS_FAIL ? "Transaction Failed " : "", |
| 155 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", | 169 | data & HST_STS_BUSERR ? "No response or Bus Collision " : "", |
| @@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 242 | } | 256 | } |
| 243 | 257 | ||
| 244 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); | 258 | outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); |
| 245 | outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); | 259 | outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); |
| 246 | 260 | ||
| 247 | /* Write the command register */ | 261 | /* Write the command register */ |
| 262 | |||
| 248 | switch(size) { | 263 | switch(size) { |
| 249 | case HST_CNTL2_BYTE: | 264 | case HST_CNTL2_BYTE: |
| 250 | if (rw== I2C_SMBUS_WRITE) | 265 | if (rw== I2C_SMBUS_WRITE) |
| 251 | outb_p(cmd, SMB_HST_CMD); | 266 | /* Beware it uses DAT0 register and not CMD! */ |
| 267 | outb_p(cmd, SMB_HST_DAT0); | ||
| 252 | break; | 268 | break; |
| 253 | case HST_CNTL2_BYTE_DATA: | 269 | case HST_CNTL2_BYTE_DATA: |
| 254 | outb_p(cmd, SMB_HST_CMD); | 270 | outb_p(cmd, SMB_HST_CMD); |
| @@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, | |||
| 268 | goto Done; | 284 | goto Done; |
| 269 | } | 285 | } |
| 270 | 286 | ||
| 271 | if ((error = ali1563_transaction(a))) | 287 | if ((error = ali1563_transaction(a, size))) |
| 272 | goto Done; | 288 | goto Done; |
| 273 | 289 | ||
| 274 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) | 290 | if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 78e3e7b24d7d..39f3e9101ed4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -1936,7 +1936,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
| 1936 | * NOTE! The "len" and "addr" checks should possibly have | 1936 | * NOTE! The "len" and "addr" checks should possibly have |
| 1937 | * separate masks. | 1937 | * separate masks. |
| 1938 | */ | 1938 | */ |
| 1939 | if ((rq->data_len & mask) || (addr & mask)) | 1939 | if ((rq->data_len & 15) || (addr & mask)) |
| 1940 | info->dma = 0; | 1940 | info->dma = 0; |
| 1941 | } | 1941 | } |
| 1942 | 1942 | ||
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 47225e324356..4e0f13d1d060 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c | |||
| @@ -72,6 +72,7 @@ static struct amd_ide_chip { | |||
| 72 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, | 72 | { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, |
| 73 | { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, | 73 | { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, |
| 74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, | 74 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, |
| 75 | { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, | ||
| 75 | { 0 } | 76 | { 0 } |
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| @@ -487,6 +488,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { | |||
| 487 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), | 488 | /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), |
| 488 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), | 489 | /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), |
| 489 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), | 490 | /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), |
| 491 | /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), | ||
| 490 | }; | 492 | }; |
| 491 | 493 | ||
| 492 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) | 494 | static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| @@ -521,6 +523,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { | |||
| 521 | #endif | 523 | #endif |
| 522 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, | 524 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, |
| 523 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, | 525 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, |
| 526 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, | ||
| 524 | { 0, }, | 527 | { 0, }, |
| 525 | }; | 528 | }; |
| 526 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); | 529 | MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); |
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig index 6282f460aba0..1d93f5092904 100644 --- a/drivers/input/gameport/Kconfig +++ b/drivers/input/gameport/Kconfig | |||
| @@ -68,23 +68,3 @@ config GAMEPORT_CS461X | |||
| 68 | depends on PCI | 68 | depends on PCI |
| 69 | 69 | ||
| 70 | endif | 70 | endif |
| 71 | |||
| 72 | # Yes, SOUND_GAMEPORT looks a bit odd. Yes, it ends up being turned on | ||
| 73 | # in every .config. Please don't touch it. It is here to handle an | ||
| 74 | # unusual dependency between GAMEPORT and sound drivers. | ||
| 75 | # | ||
| 76 | # Some sound drivers call gameport functions. If GAMEPORT is | ||
| 77 | # not selected, empty stubs are provided for the functions and all is | ||
| 78 | # well. | ||
| 79 | # If GAMEPORT is built in, everything is fine. | ||
| 80 | # If GAMEPORT is a module, however, it would need to be loaded for the | ||
| 81 | # sound driver to be able to link properly. Therefore, the sound | ||
| 82 | # driver must be a module as well in that case. Since there's no way | ||
| 83 | # to express that directly in Kconfig, we use SOUND_GAMEPORT to | ||
| 84 | # express it. SOUND_GAMEPORT boils down to "if GAMEPORT is 'm', | ||
| 85 | # anything that depends on SOUND_GAMEPORT must be 'm' as well. if | ||
| 86 | # GAMEPORT is 'y' or 'n', it can be anything". | ||
| 87 | config SOUND_GAMEPORT | ||
| 88 | tristate | ||
| 89 | default m if GAMEPORT=m | ||
| 90 | default y | ||
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 7d7527f8b02d..627d343dfba1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -422,7 +422,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct | |||
| 422 | joydev->nkey++; | 422 | joydev->nkey++; |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | for (i = 0; i < BTN_JOYSTICK - BTN_MISC + 1; i++) | 425 | for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++) |
| 426 | if (test_bit(i + BTN_MISC, dev->keybit)) { | 426 | if (test_bit(i + BTN_MISC, dev->keybit)) { |
| 427 | joydev->keymap[i] = joydev->nkey; | 427 | joydev->keymap[i] = joydev->nkey; |
| 428 | joydev->keypam[joydev->nkey] = i + BTN_MISC; | 428 | joydev->keypam[joydev->nkey] = i + BTN_MISC; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 79c332f16fc7..af0446c6de82 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -171,9 +171,9 @@ static struct { | |||
| 171 | unsigned char set2; | 171 | unsigned char set2; |
| 172 | } atkbd_scroll_keys[] = { | 172 | } atkbd_scroll_keys[] = { |
| 173 | { ATKBD_SCR_1, 0xc5 }, | 173 | { ATKBD_SCR_1, 0xc5 }, |
| 174 | { ATKBD_SCR_2, 0xa9 }, | 174 | { ATKBD_SCR_2, 0x9d }, |
| 175 | { ATKBD_SCR_4, 0xb6 }, | 175 | { ATKBD_SCR_4, 0xa4 }, |
| 176 | { ATKBD_SCR_8, 0xa7 }, | 176 | { ATKBD_SCR_8, 0x9b }, |
| 177 | { ATKBD_SCR_CLICK, 0xe0 }, | 177 | { ATKBD_SCR_CLICK, 0xe0 }, |
| 178 | { ATKBD_SCR_LEFT, 0xcb }, | 178 | { ATKBD_SCR_LEFT, 0xcb }, |
| 179 | { ATKBD_SCR_RIGHT, 0xd2 }, | 179 | { ATKBD_SCR_RIGHT, 0xd2 }, |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cd8509549eac..019034b21a0b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -518,13 +518,16 @@ static int psmouse_probe(struct psmouse *psmouse) | |||
| 518 | /* | 518 | /* |
| 519 | * First, we check if it's a mouse. It should send 0x00 or 0x03 | 519 | * First, we check if it's a mouse. It should send 0x00 or 0x03 |
| 520 | * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. | 520 | * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. |
| 521 | * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent | ||
| 522 | * ID queries, probably due to a firmware bug. | ||
| 521 | */ | 523 | */ |
| 522 | 524 | ||
| 523 | param[0] = 0xa5; | 525 | param[0] = 0xa5; |
| 524 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) | 526 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) |
| 525 | return -1; | 527 | return -1; |
| 526 | 528 | ||
| 527 | if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) | 529 | if (param[0] != 0x00 && param[0] != 0x03 && |
| 530 | param[0] != 0x04 && param[0] != 0xff) | ||
| 528 | return -1; | 531 | return -1; |
| 529 | 532 | ||
| 530 | /* | 533 | /* |
| @@ -972,7 +975,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) | |||
| 972 | return -EINVAL; | 975 | return -EINVAL; |
| 973 | 976 | ||
| 974 | if (!strncmp(val, "any", 3)) { | 977 | if (!strncmp(val, "any", 3)) { |
| 975 | *((unsigned int *)kp->arg) = -1UL; | 978 | *((unsigned int *)kp->arg) = -1U; |
| 976 | return 0; | 979 | return 0; |
| 977 | } | 980 | } |
| 978 | 981 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 69832f8fb720..36c721227b68 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -143,39 +143,6 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
| 143 | return -1; | 143 | return -1; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static void print_ident(struct synaptics_data *priv) | ||
| 147 | { | ||
| 148 | printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity)); | ||
| 149 | printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity), | ||
| 150 | SYN_ID_MINOR(priv->identity)); | ||
| 151 | if (SYN_MODEL_ROT180(priv->model_id)) | ||
| 152 | printk(KERN_INFO " 180 degree mounted touchpad\n"); | ||
| 153 | if (SYN_MODEL_PORTRAIT(priv->model_id)) | ||
| 154 | printk(KERN_INFO " portrait touchpad\n"); | ||
| 155 | printk(KERN_INFO " Sensor: %ld\n", SYN_MODEL_SENSOR(priv->model_id)); | ||
| 156 | if (SYN_MODEL_NEWABS(priv->model_id)) | ||
| 157 | printk(KERN_INFO " new absolute packet format\n"); | ||
| 158 | if (SYN_MODEL_PEN(priv->model_id)) | ||
| 159 | printk(KERN_INFO " pen detection\n"); | ||
| 160 | |||
| 161 | if (SYN_CAP_EXTENDED(priv->capabilities)) { | ||
| 162 | printk(KERN_INFO " Touchpad has extended capability bits\n"); | ||
| 163 | if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | ||
| 164 | printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n", | ||
| 165 | (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))); | ||
| 166 | if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) | ||
| 167 | printk(KERN_INFO " -> middle button\n"); | ||
| 168 | if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) | ||
| 169 | printk(KERN_INFO " -> four buttons\n"); | ||
| 170 | if (SYN_CAP_MULTIFINGER(priv->capabilities)) | ||
| 171 | printk(KERN_INFO " -> multifinger detection\n"); | ||
| 172 | if (SYN_CAP_PALMDETECT(priv->capabilities)) | ||
| 173 | printk(KERN_INFO " -> palm detection\n"); | ||
| 174 | if (SYN_CAP_PASS_THROUGH(priv->capabilities)) | ||
| 175 | printk(KERN_INFO " -> pass-through port\n"); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | static int synaptics_query_hardware(struct psmouse *psmouse) | 146 | static int synaptics_query_hardware(struct psmouse *psmouse) |
| 180 | { | 147 | { |
| 181 | int retries = 0; | 148 | int retries = 0; |
| @@ -666,7 +633,11 @@ int synaptics_init(struct psmouse *psmouse) | |||
| 666 | 633 | ||
| 667 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 634 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
| 668 | 635 | ||
| 669 | print_ident(priv); | 636 | printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", |
| 637 | SYN_ID_MODEL(priv->identity), | ||
| 638 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | ||
| 639 | priv->model_id, priv->capabilities, priv->ext_cap); | ||
| 640 | |||
| 670 | set_input_params(&psmouse->dev, priv); | 641 | set_input_params(&psmouse->dev, priv); |
| 671 | 642 | ||
| 672 | psmouse->protocol_handler = synaptics_process_byte; | 643 | psmouse->protocol_handler = synaptics_process_byte; |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 564974ce5793..96fb9870834a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -101,6 +101,7 @@ struct mousedev_list { | |||
| 101 | unsigned char ready, buffer, bufsiz; | 101 | unsigned char ready, buffer, bufsiz; |
| 102 | unsigned char imexseq, impsseq; | 102 | unsigned char imexseq, impsseq; |
| 103 | enum mousedev_emul mode; | 103 | enum mousedev_emul mode; |
| 104 | unsigned long last_buttons; | ||
| 104 | }; | 105 | }; |
| 105 | 106 | ||
| 106 | #define MOUSEDEV_SEQ_LEN 6 | 107 | #define MOUSEDEV_SEQ_LEN 6 |
| @@ -224,7 +225,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h | |||
| 224 | spin_lock_irqsave(&list->packet_lock, flags); | 225 | spin_lock_irqsave(&list->packet_lock, flags); |
| 225 | 226 | ||
| 226 | p = &list->packets[list->head]; | 227 | p = &list->packets[list->head]; |
| 227 | if (list->ready && p->buttons != packet->buttons) { | 228 | if (list->ready && p->buttons != mousedev->packet.buttons) { |
| 228 | unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; | 229 | unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; |
| 229 | if (new_head != list->tail) { | 230 | if (new_head != list->tail) { |
| 230 | p = &list->packets[list->head = new_head]; | 231 | p = &list->packets[list->head = new_head]; |
| @@ -249,10 +250,13 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h | |||
| 249 | p->dz += packet->dz; | 250 | p->dz += packet->dz; |
| 250 | p->buttons = mousedev->packet.buttons; | 251 | p->buttons = mousedev->packet.buttons; |
| 251 | 252 | ||
| 252 | list->ready = 1; | 253 | if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) |
| 254 | list->ready = 1; | ||
| 253 | 255 | ||
| 254 | spin_unlock_irqrestore(&list->packet_lock, flags); | 256 | spin_unlock_irqrestore(&list->packet_lock, flags); |
| 255 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | 257 | |
| 258 | if (list->ready) | ||
| 259 | kill_fasync(&list->fasync, SIGIO, POLL_IN); | ||
| 256 | } | 260 | } |
| 257 | 261 | ||
| 258 | wake_up_interruptible(&mousedev->wait); | 262 | wake_up_interruptible(&mousedev->wait); |
| @@ -477,9 +481,10 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) | |||
| 477 | } | 481 | } |
| 478 | 482 | ||
| 479 | if (!p->dx && !p->dy && !p->dz) { | 483 | if (!p->dx && !p->dy && !p->dz) { |
| 480 | if (list->tail == list->head) | 484 | if (list->tail == list->head) { |
| 481 | list->ready = 0; | 485 | list->ready = 0; |
| 482 | else | 486 | list->last_buttons = p->buttons; |
| 487 | } else | ||
| 483 | list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; | 488 | list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; |
| 484 | } | 489 | } |
| 485 | 490 | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index f64867808fea..0487ecbb8a49 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -88,9 +88,11 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { | |||
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | /* | 90 | /* |
| 91 | * Some Fujitsu notebooks are ahving trouble with touhcpads if | 91 | * Some Fujitsu notebooks are having trouble with touchpads if |
| 92 | * active multiplexing mode is activated. Luckily they don't have | 92 | * active multiplexing mode is activated. Luckily they don't have |
| 93 | * external PS/2 ports so we can safely disable it. | 93 | * external PS/2 ports so we can safely disable it. |
| 94 | * ... apparently some Toshibas don't like MUX mode either and | ||
| 95 | * die horrible death on reboot. | ||
| 94 | */ | 96 | */ |
| 95 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | 97 | static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { |
| 96 | { | 98 | { |
| @@ -115,12 +117,26 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { | |||
| 115 | }, | 117 | }, |
| 116 | }, | 118 | }, |
| 117 | { | 119 | { |
| 120 | .ident = "Fujitsu Lifebook S6230", | ||
| 121 | .matches = { | ||
| 122 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
| 123 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), | ||
| 124 | }, | ||
| 125 | }, | ||
| 126 | { | ||
| 118 | .ident = "Fujitsu T70H", | 127 | .ident = "Fujitsu T70H", |
| 119 | .matches = { | 128 | .matches = { |
| 120 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | 129 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), |
| 121 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), | 130 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), |
| 122 | }, | 131 | }, |
| 123 | }, | 132 | }, |
| 133 | { | ||
| 134 | .ident = "Toshiba P10", | ||
| 135 | .matches = { | ||
| 136 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
| 137 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | ||
| 138 | }, | ||
| 139 | }, | ||
| 124 | { } | 140 | { } |
| 125 | }; | 141 | }; |
| 126 | 142 | ||
| @@ -215,11 +231,15 @@ static struct pnp_driver i8042_pnp_aux_driver = { | |||
| 215 | 231 | ||
| 216 | static void i8042_pnp_exit(void) | 232 | static void i8042_pnp_exit(void) |
| 217 | { | 233 | { |
| 218 | if (i8042_pnp_kbd_registered) | 234 | if (i8042_pnp_kbd_registered) { |
| 235 | i8042_pnp_kbd_registered = 0; | ||
| 219 | pnp_unregister_driver(&i8042_pnp_kbd_driver); | 236 | pnp_unregister_driver(&i8042_pnp_kbd_driver); |
| 237 | } | ||
| 220 | 238 | ||
| 221 | if (i8042_pnp_aux_registered) | 239 | if (i8042_pnp_aux_registered) { |
| 240 | i8042_pnp_aux_registered = 0; | ||
| 222 | pnp_unregister_driver(&i8042_pnp_aux_driver); | 241 | pnp_unregister_driver(&i8042_pnp_aux_driver); |
| 242 | } | ||
| 223 | } | 243 | } |
| 224 | 244 | ||
| 225 | static int i8042_pnp_init(void) | 245 | static int i8042_pnp_init(void) |
| @@ -227,7 +247,7 @@ static int i8042_pnp_init(void) | |||
| 227 | int result_kbd, result_aux; | 247 | int result_kbd, result_aux; |
| 228 | 248 | ||
| 229 | if (i8042_nopnp) { | 249 | if (i8042_nopnp) { |
| 230 | printk("i8042: PNP detection disabled\n"); | 250 | printk(KERN_INFO "i8042: PNP detection disabled\n"); |
| 231 | return 0; | 251 | return 0; |
| 232 | } | 252 | } |
| 233 | 253 | ||
| @@ -241,7 +261,7 @@ static int i8042_pnp_init(void) | |||
| 241 | #if defined(__ia64__) | 261 | #if defined(__ia64__) |
| 242 | return -ENODEV; | 262 | return -ENODEV; |
| 243 | #else | 263 | #else |
| 244 | printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n"); | 264 | printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); |
| 245 | return 0; | 265 | return 0; |
| 246 | #endif | 266 | #endif |
| 247 | } | 267 | } |
| @@ -265,7 +285,7 @@ static int i8042_pnp_init(void) | |||
| 265 | i8042_pnp_kbd_irq = i8042_kbd_irq; | 285 | i8042_pnp_kbd_irq = i8042_kbd_irq; |
| 266 | } | 286 | } |
| 267 | 287 | ||
| 268 | if (result_aux > 0 && !i8042_pnp_aux_irq) { | 288 | if (!i8042_pnp_aux_irq) { |
| 269 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); | 289 | printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); |
| 270 | i8042_pnp_aux_irq = i8042_aux_irq; | 290 | i8042_pnp_aux_irq = i8042_aux_irq; |
| 271 | } | 291 | } |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 8e63e464d361..5900de3c3f4f 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -698,6 +698,26 @@ static void i8042_timer_func(unsigned long data) | |||
| 698 | i8042_interrupt(0, NULL, NULL); | 698 | i8042_interrupt(0, NULL, NULL); |
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | static int i8042_ctl_test(void) | ||
| 702 | { | ||
| 703 | unsigned char param; | ||
| 704 | |||
| 705 | if (!i8042_reset) | ||
| 706 | return 0; | ||
| 707 | |||
| 708 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
| 709 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
| 710 | return -1; | ||
| 711 | } | ||
| 712 | |||
| 713 | if (param != I8042_RET_CTL_TEST) { | ||
| 714 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | ||
| 715 | param, I8042_RET_CTL_TEST); | ||
| 716 | return -1; | ||
| 717 | } | ||
| 718 | |||
| 719 | return 0; | ||
| 720 | } | ||
| 701 | 721 | ||
| 702 | /* | 722 | /* |
| 703 | * i8042_controller init initializes the i8042 controller, and, | 723 | * i8042_controller init initializes the i8042 controller, and, |
| @@ -719,21 +739,8 @@ static int i8042_controller_init(void) | |||
| 719 | return -1; | 739 | return -1; |
| 720 | } | 740 | } |
| 721 | 741 | ||
| 722 | if (i8042_reset) { | 742 | if (i8042_ctl_test()) |
| 723 | 743 | return -1; | |
| 724 | unsigned char param; | ||
| 725 | |||
| 726 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { | ||
| 727 | printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); | ||
| 728 | return -1; | ||
| 729 | } | ||
| 730 | |||
| 731 | if (param != I8042_RET_CTL_TEST) { | ||
| 732 | printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", | ||
| 733 | param, I8042_RET_CTL_TEST); | ||
| 734 | return -1; | ||
| 735 | } | ||
| 736 | } | ||
| 737 | 744 | ||
| 738 | /* | 745 | /* |
| 739 | * Save the CTR for restoral on unload / reboot. | 746 | * Save the CTR for restoral on unload / reboot. |
| @@ -802,15 +809,11 @@ static int i8042_controller_init(void) | |||
| 802 | */ | 809 | */ |
| 803 | static void i8042_controller_reset(void) | 810 | static void i8042_controller_reset(void) |
| 804 | { | 811 | { |
| 805 | unsigned char param; | ||
| 806 | |||
| 807 | /* | 812 | /* |
| 808 | * Reset the controller if requested. | 813 | * Reset the controller if requested. |
| 809 | */ | 814 | */ |
| 810 | 815 | ||
| 811 | if (i8042_reset) | 816 | i8042_ctl_test(); |
| 812 | if (i8042_command(¶m, I8042_CMD_CTL_TEST)) | ||
| 813 | printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n"); | ||
| 814 | 817 | ||
| 815 | /* | 818 | /* |
| 816 | * Disable MUX mode if present. | 819 | * Disable MUX mode if present. |
| @@ -922,8 +925,11 @@ static int i8042_resume(struct device *dev, u32 level) | |||
| 922 | if (level != RESUME_ENABLE) | 925 | if (level != RESUME_ENABLE) |
| 923 | return 0; | 926 | return 0; |
| 924 | 927 | ||
| 925 | if (i8042_controller_init()) { | 928 | if (i8042_ctl_test()) |
| 926 | printk(KERN_ERR "i8042: resume failed\n"); | 929 | return -1; |
| 930 | |||
| 931 | if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { | ||
| 932 | printk(KERN_ERR "i8042: Can't write CTR\n"); | ||
| 927 | return -1; | 933 | return -1; |
| 928 | } | 934 | } |
| 929 | 935 | ||
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index c9d0a153671c..53a27e43dd23 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
| @@ -68,8 +68,7 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) | |||
| 68 | 68 | ||
| 69 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || | 69 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || |
| 70 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { | 70 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { |
| 71 | gunze->data[10] = 0; | 71 | printk(KERN_WARNING "gunze.c: bad packet: >%.*s<\n", GUNZE_MAX_LENGTH, gunze->data); |
| 72 | printk(KERN_WARNING "gunze.c: bad packet: >%s<\n", gunze->data); | ||
| 73 | return; | 72 | return; |
| 74 | } | 73 | } |
| 75 | 74 | ||
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index e654aa5eecd4..bb9f4044c74d 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
| @@ -2421,7 +2421,7 @@ pmac_wakeup_devices(void) | |||
| 2421 | 2421 | ||
| 2422 | /* Re-enable local CPU interrupts */ | 2422 | /* Re-enable local CPU interrupts */ |
| 2423 | local_irq_enable(); | 2423 | local_irq_enable(); |
| 2424 | mdelay(100); | 2424 | mdelay(10); |
| 2425 | preempt_enable(); | 2425 | preempt_enable(); |
| 2426 | 2426 | ||
| 2427 | /* Re-enable clock spreading on some machines */ | 2427 | /* Re-enable clock spreading on some machines */ |
| @@ -2549,7 +2549,9 @@ powerbook_sleep_Core99(void) | |||
| 2549 | return ret; | 2549 | return ret; |
| 2550 | } | 2550 | } |
| 2551 | 2551 | ||
| 2552 | printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); | 2552 | /* Stop environment and ADB interrupts */ |
| 2553 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); | ||
| 2554 | pmu_wait_complete(&req); | ||
| 2553 | 2555 | ||
| 2554 | /* Tell PMU what events will wake us up */ | 2556 | /* Tell PMU what events will wake us up */ |
| 2555 | pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, | 2557 | pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, |
| @@ -2611,8 +2613,6 @@ powerbook_sleep_Core99(void) | |||
| 2611 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); | 2613 | pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); |
| 2612 | pmu_wait_complete(&req); | 2614 | pmu_wait_complete(&req); |
| 2613 | 2615 | ||
| 2614 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); | ||
| 2615 | |||
| 2616 | pmac_wakeup_devices(); | 2616 | pmac_wakeup_devices(); |
| 2617 | 2617 | ||
| 2618 | return 0; | 2618 | return 0; |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index d047e349d706..1339912c308b 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
| @@ -906,22 +906,12 @@ static int dst_tone_power_cmd(struct dst_state* state) | |||
| 906 | if (state->dst_type == DST_TYPE_IS_TERR) | 906 | if (state->dst_type == DST_TYPE_IS_TERR) |
| 907 | return 0; | 907 | return 0; |
| 908 | 908 | ||
| 909 | if (state->voltage == SEC_VOLTAGE_OFF) | 909 | paket[4] = state->tx_tuna[4]; |
| 910 | paket[4] = 0; | 910 | paket[2] = state->tx_tuna[2]; |
| 911 | else | 911 | paket[3] = state->tx_tuna[3]; |
| 912 | paket[4] = 1; | ||
| 913 | |||
| 914 | if (state->tone == SEC_TONE_ON) | ||
| 915 | paket[2] = 0x02; | ||
| 916 | else | ||
| 917 | paket[2] = 0; | ||
| 918 | if (state->minicmd == SEC_MINI_A) | ||
| 919 | paket[3] = 0x02; | ||
| 920 | else | ||
| 921 | paket[3] = 0; | ||
| 922 | |||
| 923 | paket[7] = dst_check_sum (paket, 7); | 912 | paket[7] = dst_check_sum (paket, 7); |
| 924 | dst_command(state, paket, 8); | 913 | dst_command(state, paket, 8); |
| 914 | |||
| 925 | return 0; | 915 | return 0; |
| 926 | } | 916 | } |
| 927 | 917 | ||
| @@ -980,7 +970,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | |||
| 980 | 970 | ||
| 981 | static int dst_write_tuna(struct dvb_frontend* fe) | 971 | static int dst_write_tuna(struct dvb_frontend* fe) |
| 982 | { | 972 | { |
| 983 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 973 | struct dst_state* state = fe->demodulator_priv; |
| 984 | int retval; | 974 | int retval; |
| 985 | u8 reply; | 975 | u8 reply; |
| 986 | 976 | ||
| @@ -1048,10 +1038,10 @@ static int dst_write_tuna(struct dvb_frontend* fe) | |||
| 1048 | 1038 | ||
| 1049 | static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | 1039 | static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) |
| 1050 | { | 1040 | { |
| 1051 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1041 | struct dst_state* state = fe->demodulator_priv; |
| 1052 | u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; | 1042 | u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; |
| 1053 | 1043 | ||
| 1054 | if (state->dst_type == DST_TYPE_IS_TERR) | 1044 | if (state->dst_type != DST_TYPE_IS_SAT) |
| 1055 | return 0; | 1045 | return 0; |
| 1056 | 1046 | ||
| 1057 | if (cmd->msg_len == 0 || cmd->msg_len > 4) | 1047 | if (cmd->msg_len == 0 || cmd->msg_len > 4) |
| @@ -1064,39 +1054,32 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* | |||
| 1064 | 1054 | ||
| 1065 | static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 1055 | static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
| 1066 | { | 1056 | { |
| 1067 | u8 *val; | ||
| 1068 | int need_cmd; | 1057 | int need_cmd; |
| 1069 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1058 | struct dst_state* state = fe->demodulator_priv; |
| 1070 | 1059 | ||
| 1071 | state->voltage = voltage; | 1060 | state->voltage = voltage; |
| 1072 | 1061 | ||
| 1073 | if (state->dst_type == DST_TYPE_IS_TERR) | 1062 | if (state->dst_type != DST_TYPE_IS_SAT) |
| 1074 | return 0; | 1063 | return 0; |
| 1075 | 1064 | ||
| 1076 | need_cmd = 0; | 1065 | need_cmd = 0; |
| 1077 | val = &state->tx_tuna[0]; | ||
| 1078 | val[8] &= ~0x40; | ||
| 1079 | switch (voltage) { | 1066 | switch (voltage) { |
| 1080 | case SEC_VOLTAGE_13: | 1067 | case SEC_VOLTAGE_13: |
| 1081 | if ((state->diseq_flags & HAS_POWER) == 0) | 1068 | case SEC_VOLTAGE_18: |
| 1082 | need_cmd = 1; | 1069 | if ((state->diseq_flags & HAS_POWER) == 0) |
| 1083 | state->diseq_flags |= HAS_POWER; | 1070 | need_cmd = 1; |
| 1084 | break; | 1071 | state->diseq_flags |= HAS_POWER; |
| 1072 | state->tx_tuna[4] = 0x01; | ||
| 1073 | break; | ||
| 1085 | 1074 | ||
| 1086 | case SEC_VOLTAGE_18: | 1075 | case SEC_VOLTAGE_OFF: |
| 1087 | if ((state->diseq_flags & HAS_POWER) == 0) | ||
| 1088 | need_cmd = 1; | 1076 | need_cmd = 1; |
| 1089 | state->diseq_flags |= HAS_POWER; | 1077 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); |
| 1090 | val[8] |= 0x40; | 1078 | state->tx_tuna[4] = 0x00; |
| 1091 | break; | 1079 | break; |
| 1092 | |||
| 1093 | case SEC_VOLTAGE_OFF: | ||
| 1094 | need_cmd = 1; | ||
| 1095 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); | ||
| 1096 | break; | ||
| 1097 | 1080 | ||
| 1098 | default: | 1081 | default: |
| 1099 | return -EINVAL; | 1082 | return -EINVAL; |
| 1100 | } | 1083 | } |
| 1101 | if (need_cmd) | 1084 | if (need_cmd) |
| 1102 | dst_tone_power_cmd(state); | 1085 | dst_tone_power_cmd(state); |
| @@ -1106,37 +1089,56 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | |||
| 1106 | 1089 | ||
| 1107 | static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 1090 | static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
| 1108 | { | 1091 | { |
| 1109 | u8 *val; | 1092 | struct dst_state* state = fe->demodulator_priv; |
| 1110 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | ||
| 1111 | 1093 | ||
| 1112 | state->tone = tone; | 1094 | state->tone = tone; |
| 1113 | 1095 | ||
| 1114 | if (state->dst_type == DST_TYPE_IS_TERR) | 1096 | if (state->dst_type != DST_TYPE_IS_SAT) |
| 1115 | return 0; | 1097 | return 0; |
| 1116 | 1098 | ||
| 1117 | val = &state->tx_tuna[0]; | 1099 | switch (tone) { |
| 1100 | case SEC_TONE_OFF: | ||
| 1101 | state->tx_tuna[2] = 0xff; | ||
| 1102 | break; | ||
| 1118 | 1103 | ||
| 1119 | val[8] &= ~0x1; | 1104 | case SEC_TONE_ON: |
| 1105 | state->tx_tuna[2] = 0x02; | ||
| 1106 | break; | ||
| 1120 | 1107 | ||
| 1121 | switch (tone) { | 1108 | default: |
| 1122 | case SEC_TONE_OFF: | 1109 | return -EINVAL; |
| 1123 | break; | 1110 | } |
| 1111 | dst_tone_power_cmd(state); | ||
| 1124 | 1112 | ||
| 1125 | case SEC_TONE_ON: | 1113 | return 0; |
| 1126 | val[8] |= 1; | 1114 | } |
| 1127 | break; | ||
| 1128 | 1115 | ||
| 1129 | default: | 1116 | static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) |
| 1130 | return -EINVAL; | 1117 | { |
| 1118 | struct dst_state *state = fe->demodulator_priv; | ||
| 1119 | |||
| 1120 | if (state->dst_type != DST_TYPE_IS_SAT) | ||
| 1121 | return 0; | ||
| 1122 | |||
| 1123 | state->minicmd = minicmd; | ||
| 1124 | |||
| 1125 | switch (minicmd) { | ||
| 1126 | case SEC_MINI_A: | ||
| 1127 | state->tx_tuna[3] = 0x02; | ||
| 1128 | break; | ||
| 1129 | case SEC_MINI_B: | ||
| 1130 | state->tx_tuna[3] = 0xff; | ||
| 1131 | break; | ||
| 1131 | } | 1132 | } |
| 1132 | dst_tone_power_cmd(state); | 1133 | dst_tone_power_cmd(state); |
| 1133 | 1134 | ||
| 1134 | return 0; | 1135 | return 0; |
| 1135 | } | 1136 | } |
| 1136 | 1137 | ||
| 1138 | |||
| 1137 | static int dst_init(struct dvb_frontend* fe) | 1139 | static int dst_init(struct dvb_frontend* fe) |
| 1138 | { | 1140 | { |
| 1139 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1141 | struct dst_state* state = fe->demodulator_priv; |
| 1140 | static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; | 1142 | static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; |
| 1141 | static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; | 1143 | static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; |
| 1142 | static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; | 1144 | static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; |
| @@ -1168,7 +1170,7 @@ static int dst_init(struct dvb_frontend* fe) | |||
| 1168 | 1170 | ||
| 1169 | static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) | 1171 | static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) |
| 1170 | { | 1172 | { |
| 1171 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1173 | struct dst_state* state = fe->demodulator_priv; |
| 1172 | 1174 | ||
| 1173 | *status = 0; | 1175 | *status = 0; |
| 1174 | if (state->diseq_flags & HAS_LOCK) { | 1176 | if (state->diseq_flags & HAS_LOCK) { |
| @@ -1182,7 +1184,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 1182 | 1184 | ||
| 1183 | static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 1185 | static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
| 1184 | { | 1186 | { |
| 1185 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1187 | struct dst_state* state = fe->demodulator_priv; |
| 1186 | 1188 | ||
| 1187 | dst_get_signal(state); | 1189 | dst_get_signal(state); |
| 1188 | *strength = state->decode_strength; | 1190 | *strength = state->decode_strength; |
| @@ -1192,7 +1194,7 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
| 1192 | 1194 | ||
| 1193 | static int dst_read_snr(struct dvb_frontend* fe, u16* snr) | 1195 | static int dst_read_snr(struct dvb_frontend* fe, u16* snr) |
| 1194 | { | 1196 | { |
| 1195 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1197 | struct dst_state* state = fe->demodulator_priv; |
| 1196 | 1198 | ||
| 1197 | dst_get_signal(state); | 1199 | dst_get_signal(state); |
| 1198 | *snr = state->decode_snr; | 1200 | *snr = state->decode_snr; |
| @@ -1202,7 +1204,7 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 1202 | 1204 | ||
| 1203 | static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 1205 | static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
| 1204 | { | 1206 | { |
| 1205 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1207 | struct dst_state* state = fe->demodulator_priv; |
| 1206 | 1208 | ||
| 1207 | dst_set_freq(state, p->frequency); | 1209 | dst_set_freq(state, p->frequency); |
| 1208 | if (verbose > 4) | 1210 | if (verbose > 4) |
| @@ -1228,7 +1230,7 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
| 1228 | 1230 | ||
| 1229 | static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 1231 | static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
| 1230 | { | 1232 | { |
| 1231 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1233 | struct dst_state* state = fe->demodulator_priv; |
| 1232 | 1234 | ||
| 1233 | p->frequency = state->decode_freq; | 1235 | p->frequency = state->decode_freq; |
| 1234 | p->inversion = state->inversion; | 1236 | p->inversion = state->inversion; |
| @@ -1248,7 +1250,7 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
| 1248 | 1250 | ||
| 1249 | static void dst_release(struct dvb_frontend* fe) | 1251 | static void dst_release(struct dvb_frontend* fe) |
| 1250 | { | 1252 | { |
| 1251 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1253 | struct dst_state* state = fe->demodulator_priv; |
| 1252 | kfree(state); | 1254 | kfree(state); |
| 1253 | } | 1255 | } |
| 1254 | 1256 | ||
| @@ -1346,7 +1348,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
| 1346 | .read_signal_strength = dst_read_signal_strength, | 1348 | .read_signal_strength = dst_read_signal_strength, |
| 1347 | .read_snr = dst_read_snr, | 1349 | .read_snr = dst_read_snr, |
| 1348 | 1350 | ||
| 1349 | .diseqc_send_burst = dst_set_tone, | 1351 | .diseqc_send_burst = dst_send_burst, |
| 1350 | .diseqc_send_master_cmd = dst_set_diseqc, | 1352 | .diseqc_send_master_cmd = dst_set_diseqc, |
| 1351 | .set_voltage = dst_set_voltage, | 1353 | .set_voltage = dst_set_voltage, |
| 1352 | .set_tone = dst_set_tone, | 1354 | .set_tone = dst_set_tone, |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f10dd74988c4..fc9b5cd957aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -133,6 +133,8 @@ | |||
| 133 | /* number of ETHTOOL_GSTATS u64's */ | 133 | /* number of ETHTOOL_GSTATS u64's */ |
| 134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) | 134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) |
| 135 | 135 | ||
| 136 | #define TG3_NUM_TEST 6 | ||
| 137 | |||
| 136 | static char version[] __devinitdata = | 138 | static char version[] __devinitdata = |
| 137 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 139 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
| 138 | 140 | ||
| @@ -316,6 +318,17 @@ static struct { | |||
| 316 | { "nic_tx_threshold_hit" } | 318 | { "nic_tx_threshold_hit" } |
| 317 | }; | 319 | }; |
| 318 | 320 | ||
| 321 | static struct { | ||
| 322 | const char string[ETH_GSTRING_LEN]; | ||
| 323 | } ethtool_test_keys[TG3_NUM_TEST] = { | ||
| 324 | { "nvram test (online) " }, | ||
| 325 | { "link test (online) " }, | ||
| 326 | { "register test (offline)" }, | ||
| 327 | { "memory test (offline)" }, | ||
| 328 | { "loopback test (offline)" }, | ||
| 329 | { "interrupt test (offline)" }, | ||
| 330 | }; | ||
| 331 | |||
| 319 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 332 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
| 320 | { | 333 | { |
| 321 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 334 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
| @@ -3070,7 +3083,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
| 3070 | } | 3083 | } |
| 3071 | 3084 | ||
| 3072 | static int tg3_init_hw(struct tg3 *); | 3085 | static int tg3_init_hw(struct tg3 *); |
| 3073 | static int tg3_halt(struct tg3 *, int); | 3086 | static int tg3_halt(struct tg3 *, int, int); |
| 3074 | 3087 | ||
| 3075 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3088 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 3076 | static void tg3_poll_controller(struct net_device *dev) | 3089 | static void tg3_poll_controller(struct net_device *dev) |
| @@ -3094,7 +3107,7 @@ static void tg3_reset_task(void *_data) | |||
| 3094 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3107 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
| 3095 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3108 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
| 3096 | 3109 | ||
| 3097 | tg3_halt(tp, 0); | 3110 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
| 3098 | tg3_init_hw(tp); | 3111 | tg3_init_hw(tp); |
| 3099 | 3112 | ||
| 3100 | tg3_netif_start(tp); | 3113 | tg3_netif_start(tp); |
| @@ -3440,7 +3453,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
| 3440 | spin_lock_irq(&tp->lock); | 3453 | spin_lock_irq(&tp->lock); |
| 3441 | spin_lock(&tp->tx_lock); | 3454 | spin_lock(&tp->tx_lock); |
| 3442 | 3455 | ||
| 3443 | tg3_halt(tp, 1); | 3456 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 3444 | 3457 | ||
| 3445 | tg3_set_mtu(dev, tp, new_mtu); | 3458 | tg3_set_mtu(dev, tp, new_mtu); |
| 3446 | 3459 | ||
| @@ -4131,19 +4144,19 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
| 4131 | } | 4144 | } |
| 4132 | 4145 | ||
| 4133 | /* tp->lock is held. */ | 4146 | /* tp->lock is held. */ |
| 4134 | static int tg3_halt(struct tg3 *tp, int silent) | 4147 | static int tg3_halt(struct tg3 *tp, int kind, int silent) |
| 4135 | { | 4148 | { |
| 4136 | int err; | 4149 | int err; |
| 4137 | 4150 | ||
| 4138 | tg3_stop_fw(tp); | 4151 | tg3_stop_fw(tp); |
| 4139 | 4152 | ||
| 4140 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); | 4153 | tg3_write_sig_pre_reset(tp, kind); |
| 4141 | 4154 | ||
| 4142 | tg3_abort_hw(tp, silent); | 4155 | tg3_abort_hw(tp, silent); |
| 4143 | err = tg3_chip_reset(tp); | 4156 | err = tg3_chip_reset(tp); |
| 4144 | 4157 | ||
| 4145 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); | 4158 | tg3_write_sig_legacy(tp, kind); |
| 4146 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | 4159 | tg3_write_sig_post_reset(tp, kind); |
| 4147 | 4160 | ||
| 4148 | if (err) | 4161 | if (err) |
| 4149 | return err; | 4162 | return err; |
| @@ -4357,7 +4370,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
| 4357 | */ | 4370 | */ |
| 4358 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | 4371 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; |
| 4359 | 4372 | ||
| 4373 | /* It is possible that bootcode is still loading at this point. | ||
| 4374 | * Get the nvram lock first before halting the cpu. | ||
| 4375 | */ | ||
| 4376 | tg3_nvram_lock(tp); | ||
| 4360 | err = tg3_halt_cpu(tp, cpu_base); | 4377 | err = tg3_halt_cpu(tp, cpu_base); |
| 4378 | tg3_nvram_unlock(tp); | ||
| 4361 | if (err) | 4379 | if (err) |
| 4362 | goto out; | 4380 | goto out; |
| 4363 | 4381 | ||
| @@ -5881,6 +5899,9 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
| 5881 | int err, i; | 5899 | int err, i; |
| 5882 | u32 int_mbox = 0; | 5900 | u32 int_mbox = 0; |
| 5883 | 5901 | ||
| 5902 | if (!netif_running(dev)) | ||
| 5903 | return -ENODEV; | ||
| 5904 | |||
| 5884 | tg3_disable_ints(tp); | 5905 | tg3_disable_ints(tp); |
| 5885 | 5906 | ||
| 5886 | free_irq(tp->pdev->irq, dev); | 5907 | free_irq(tp->pdev->irq, dev); |
| @@ -5984,7 +6005,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
| 5984 | spin_lock_irq(&tp->lock); | 6005 | spin_lock_irq(&tp->lock); |
| 5985 | spin_lock(&tp->tx_lock); | 6006 | spin_lock(&tp->tx_lock); |
| 5986 | 6007 | ||
| 5987 | tg3_halt(tp, 1); | 6008 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 5988 | err = tg3_init_hw(tp); | 6009 | err = tg3_init_hw(tp); |
| 5989 | 6010 | ||
| 5990 | spin_unlock(&tp->tx_lock); | 6011 | spin_unlock(&tp->tx_lock); |
| @@ -6060,7 +6081,7 @@ static int tg3_open(struct net_device *dev) | |||
| 6060 | 6081 | ||
| 6061 | err = tg3_init_hw(tp); | 6082 | err = tg3_init_hw(tp); |
| 6062 | if (err) { | 6083 | if (err) { |
| 6063 | tg3_halt(tp, 1); | 6084 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 6064 | tg3_free_rings(tp); | 6085 | tg3_free_rings(tp); |
| 6065 | } else { | 6086 | } else { |
| 6066 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 6087 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
| @@ -6104,7 +6125,7 @@ static int tg3_open(struct net_device *dev) | |||
| 6104 | pci_disable_msi(tp->pdev); | 6125 | pci_disable_msi(tp->pdev); |
| 6105 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 6126 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
| 6106 | } | 6127 | } |
| 6107 | tg3_halt(tp, 1); | 6128 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 6108 | tg3_free_rings(tp); | 6129 | tg3_free_rings(tp); |
| 6109 | tg3_free_consistent(tp); | 6130 | tg3_free_consistent(tp); |
| 6110 | 6131 | ||
| @@ -6377,7 +6398,7 @@ static int tg3_close(struct net_device *dev) | |||
| 6377 | 6398 | ||
| 6378 | tg3_disable_ints(tp); | 6399 | tg3_disable_ints(tp); |
| 6379 | 6400 | ||
| 6380 | tg3_halt(tp, 1); | 6401 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 6381 | tg3_free_rings(tp); | 6402 | tg3_free_rings(tp); |
| 6382 | tp->tg3_flags &= | 6403 | tp->tg3_flags &= |
| 6383 | ~(TG3_FLAG_INIT_COMPLETE | | 6404 | ~(TG3_FLAG_INIT_COMPLETE | |
| @@ -7097,7 +7118,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
| 7097 | tp->tx_pending = ering->tx_pending; | 7118 | tp->tx_pending = ering->tx_pending; |
| 7098 | 7119 | ||
| 7099 | if (netif_running(dev)) { | 7120 | if (netif_running(dev)) { |
| 7100 | tg3_halt(tp, 1); | 7121 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 7101 | tg3_init_hw(tp); | 7122 | tg3_init_hw(tp); |
| 7102 | tg3_netif_start(tp); | 7123 | tg3_netif_start(tp); |
| 7103 | } | 7124 | } |
| @@ -7140,7 +7161,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
| 7140 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; | 7161 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; |
| 7141 | 7162 | ||
| 7142 | if (netif_running(dev)) { | 7163 | if (netif_running(dev)) { |
| 7143 | tg3_halt(tp, 1); | 7164 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 7144 | tg3_init_hw(tp); | 7165 | tg3_init_hw(tp); |
| 7145 | tg3_netif_start(tp); | 7166 | tg3_netif_start(tp); |
| 7146 | } | 7167 | } |
| @@ -7199,12 +7220,20 @@ static int tg3_get_stats_count (struct net_device *dev) | |||
| 7199 | return TG3_NUM_STATS; | 7220 | return TG3_NUM_STATS; |
| 7200 | } | 7221 | } |
| 7201 | 7222 | ||
| 7223 | static int tg3_get_test_count (struct net_device *dev) | ||
| 7224 | { | ||
| 7225 | return TG3_NUM_TEST; | ||
| 7226 | } | ||
| 7227 | |||
| 7202 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) | 7228 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) |
| 7203 | { | 7229 | { |
| 7204 | switch (stringset) { | 7230 | switch (stringset) { |
| 7205 | case ETH_SS_STATS: | 7231 | case ETH_SS_STATS: |
| 7206 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); | 7232 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); |
| 7207 | break; | 7233 | break; |
| 7234 | case ETH_SS_TEST: | ||
| 7235 | memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); | ||
| 7236 | break; | ||
| 7208 | default: | 7237 | default: |
| 7209 | WARN_ON(1); /* we need a WARN() */ | 7238 | WARN_ON(1); /* we need a WARN() */ |
| 7210 | break; | 7239 | break; |
| @@ -7218,6 +7247,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev, | |||
| 7218 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); | 7247 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); |
| 7219 | } | 7248 | } |
| 7220 | 7249 | ||
| 7250 | #define NVRAM_TEST_SIZE 0x100 | ||
| 7251 | |||
| 7252 | static int tg3_test_nvram(struct tg3 *tp) | ||
| 7253 | { | ||
| 7254 | u32 *buf, csum; | ||
| 7255 | int i, j, err = 0; | ||
| 7256 | |||
| 7257 | buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); | ||
| 7258 | if (buf == NULL) | ||
| 7259 | return -ENOMEM; | ||
| 7260 | |||
| 7261 | for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { | ||
| 7262 | u32 val; | ||
| 7263 | |||
| 7264 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) | ||
| 7265 | break; | ||
| 7266 | buf[j] = cpu_to_le32(val); | ||
| 7267 | } | ||
| 7268 | if (i < NVRAM_TEST_SIZE) | ||
| 7269 | goto out; | ||
| 7270 | |||
| 7271 | err = -EIO; | ||
| 7272 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) | ||
| 7273 | goto out; | ||
| 7274 | |||
| 7275 | /* Bootstrap checksum at offset 0x10 */ | ||
| 7276 | csum = calc_crc((unsigned char *) buf, 0x10); | ||
| 7277 | if(csum != cpu_to_le32(buf[0x10/4])) | ||
| 7278 | goto out; | ||
| 7279 | |||
| 7280 | /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ | ||
| 7281 | csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); | ||
| 7282 | if (csum != cpu_to_le32(buf[0xfc/4])) | ||
| 7283 | goto out; | ||
| 7284 | |||
| 7285 | err = 0; | ||
| 7286 | |||
| 7287 | out: | ||
| 7288 | kfree(buf); | ||
| 7289 | return err; | ||
| 7290 | } | ||
| 7291 | |||
| 7292 | #define TG3_SERDES_TIMEOUT_SEC 2 | ||
| 7293 | #define TG3_COPPER_TIMEOUT_SEC 6 | ||
| 7294 | |||
| 7295 | static int tg3_test_link(struct tg3 *tp) | ||
| 7296 | { | ||
| 7297 | int i, max; | ||
| 7298 | |||
| 7299 | if (!netif_running(tp->dev)) | ||
| 7300 | return -ENODEV; | ||
| 7301 | |||
| 7302 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
| 7303 | max = TG3_SERDES_TIMEOUT_SEC; | ||
| 7304 | else | ||
| 7305 | max = TG3_COPPER_TIMEOUT_SEC; | ||
| 7306 | |||
| 7307 | for (i = 0; i < max; i++) { | ||
| 7308 | if (netif_carrier_ok(tp->dev)) | ||
| 7309 | return 0; | ||
| 7310 | |||
| 7311 | if (msleep_interruptible(1000)) | ||
| 7312 | break; | ||
| 7313 | } | ||
| 7314 | |||
| 7315 | return -EIO; | ||
| 7316 | } | ||
| 7317 | |||
| 7318 | /* Only test the commonly used registers */ | ||
| 7319 | static int tg3_test_registers(struct tg3 *tp) | ||
| 7320 | { | ||
| 7321 | int i, is_5705; | ||
| 7322 | u32 offset, read_mask, write_mask, val, save_val, read_val; | ||
| 7323 | static struct { | ||
| 7324 | u16 offset; | ||
| 7325 | u16 flags; | ||
| 7326 | #define TG3_FL_5705 0x1 | ||
| 7327 | #define TG3_FL_NOT_5705 0x2 | ||
| 7328 | #define TG3_FL_NOT_5788 0x4 | ||
| 7329 | u32 read_mask; | ||
| 7330 | u32 write_mask; | ||
| 7331 | } reg_tbl[] = { | ||
| 7332 | /* MAC Control Registers */ | ||
| 7333 | { MAC_MODE, TG3_FL_NOT_5705, | ||
| 7334 | 0x00000000, 0x00ef6f8c }, | ||
| 7335 | { MAC_MODE, TG3_FL_5705, | ||
| 7336 | 0x00000000, 0x01ef6b8c }, | ||
| 7337 | { MAC_STATUS, TG3_FL_NOT_5705, | ||
| 7338 | 0x03800107, 0x00000000 }, | ||
| 7339 | { MAC_STATUS, TG3_FL_5705, | ||
| 7340 | 0x03800100, 0x00000000 }, | ||
| 7341 | { MAC_ADDR_0_HIGH, 0x0000, | ||
| 7342 | 0x00000000, 0x0000ffff }, | ||
| 7343 | { MAC_ADDR_0_LOW, 0x0000, | ||
| 7344 | 0x00000000, 0xffffffff }, | ||
| 7345 | { MAC_RX_MTU_SIZE, 0x0000, | ||
| 7346 | 0x00000000, 0x0000ffff }, | ||
| 7347 | { MAC_TX_MODE, 0x0000, | ||
| 7348 | 0x00000000, 0x00000070 }, | ||
| 7349 | { MAC_TX_LENGTHS, 0x0000, | ||
| 7350 | 0x00000000, 0x00003fff }, | ||
| 7351 | { MAC_RX_MODE, TG3_FL_NOT_5705, | ||
| 7352 | 0x00000000, 0x000007fc }, | ||
| 7353 | { MAC_RX_MODE, TG3_FL_5705, | ||
| 7354 | 0x00000000, 0x000007dc }, | ||
| 7355 | { MAC_HASH_REG_0, 0x0000, | ||
| 7356 | 0x00000000, 0xffffffff }, | ||
| 7357 | { MAC_HASH_REG_1, 0x0000, | ||
| 7358 | 0x00000000, 0xffffffff }, | ||
| 7359 | { MAC_HASH_REG_2, 0x0000, | ||
| 7360 | 0x00000000, 0xffffffff }, | ||
| 7361 | { MAC_HASH_REG_3, 0x0000, | ||
| 7362 | 0x00000000, 0xffffffff }, | ||
| 7363 | |||
| 7364 | /* Receive Data and Receive BD Initiator Control Registers. */ | ||
| 7365 | { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, | ||
| 7366 | 0x00000000, 0xffffffff }, | ||
| 7367 | { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, | ||
| 7368 | 0x00000000, 0xffffffff }, | ||
| 7369 | { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, | ||
| 7370 | 0x00000000, 0x00000003 }, | ||
| 7371 | { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, | ||
| 7372 | 0x00000000, 0xffffffff }, | ||
| 7373 | { RCVDBDI_STD_BD+0, 0x0000, | ||
| 7374 | 0x00000000, 0xffffffff }, | ||
| 7375 | { RCVDBDI_STD_BD+4, 0x0000, | ||
| 7376 | 0x00000000, 0xffffffff }, | ||
| 7377 | { RCVDBDI_STD_BD+8, 0x0000, | ||
| 7378 | 0x00000000, 0xffff0002 }, | ||
| 7379 | { RCVDBDI_STD_BD+0xc, 0x0000, | ||
| 7380 | 0x00000000, 0xffffffff }, | ||
| 7381 | |||
| 7382 | /* Receive BD Initiator Control Registers. */ | ||
| 7383 | { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, | ||
| 7384 | 0x00000000, 0xffffffff }, | ||
| 7385 | { RCVBDI_STD_THRESH, TG3_FL_5705, | ||
| 7386 | 0x00000000, 0x000003ff }, | ||
| 7387 | { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, | ||
| 7388 | 0x00000000, 0xffffffff }, | ||
| 7389 | |||
| 7390 | /* Host Coalescing Control Registers. */ | ||
| 7391 | { HOSTCC_MODE, TG3_FL_NOT_5705, | ||
| 7392 | 0x00000000, 0x00000004 }, | ||
| 7393 | { HOSTCC_MODE, TG3_FL_5705, | ||
| 7394 | 0x00000000, 0x000000f6 }, | ||
| 7395 | { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, | ||
| 7396 | 0x00000000, 0xffffffff }, | ||
| 7397 | { HOSTCC_RXCOL_TICKS, TG3_FL_5705, | ||
| 7398 | 0x00000000, 0x000003ff }, | ||
| 7399 | { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, | ||
| 7400 | 0x00000000, 0xffffffff }, | ||
| 7401 | { HOSTCC_TXCOL_TICKS, TG3_FL_5705, | ||
| 7402 | 0x00000000, 0x000003ff }, | ||
| 7403 | { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, | ||
| 7404 | 0x00000000, 0xffffffff }, | ||
| 7405 | { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
| 7406 | 0x00000000, 0x000000ff }, | ||
| 7407 | { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, | ||
| 7408 | 0x00000000, 0xffffffff }, | ||
| 7409 | { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
| 7410 | 0x00000000, 0x000000ff }, | ||
| 7411 | { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
| 7412 | 0x00000000, 0xffffffff }, | ||
| 7413 | { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
| 7414 | 0x00000000, 0xffffffff }, | ||
| 7415 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
| 7416 | 0x00000000, 0xffffffff }, | ||
| 7417 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
| 7418 | 0x00000000, 0x000000ff }, | ||
| 7419 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
| 7420 | 0x00000000, 0xffffffff }, | ||
| 7421 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
| 7422 | 0x00000000, 0x000000ff }, | ||
| 7423 | { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, | ||
| 7424 | 0x00000000, 0xffffffff }, | ||
| 7425 | { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, | ||
| 7426 | 0x00000000, 0xffffffff }, | ||
| 7427 | { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, | ||
| 7428 | 0x00000000, 0xffffffff }, | ||
| 7429 | { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, | ||
| 7430 | 0x00000000, 0xffffffff }, | ||
| 7431 | { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, | ||
| 7432 | 0x00000000, 0xffffffff }, | ||
| 7433 | { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, | ||
| 7434 | 0xffffffff, 0x00000000 }, | ||
| 7435 | { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, | ||
| 7436 | 0xffffffff, 0x00000000 }, | ||
| 7437 | |||
| 7438 | /* Buffer Manager Control Registers. */ | ||
| 7439 | { BUFMGR_MB_POOL_ADDR, 0x0000, | ||
| 7440 | 0x00000000, 0x007fff80 }, | ||
| 7441 | { BUFMGR_MB_POOL_SIZE, 0x0000, | ||
| 7442 | 0x00000000, 0x007fffff }, | ||
| 7443 | { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, | ||
| 7444 | 0x00000000, 0x0000003f }, | ||
| 7445 | { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, | ||
| 7446 | 0x00000000, 0x000001ff }, | ||
| 7447 | { BUFMGR_MB_HIGH_WATER, 0x0000, | ||
| 7448 | 0x00000000, 0x000001ff }, | ||
| 7449 | { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, | ||
| 7450 | 0xffffffff, 0x00000000 }, | ||
| 7451 | { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, | ||
| 7452 | 0xffffffff, 0x00000000 }, | ||
| 7453 | |||
| 7454 | /* Mailbox Registers */ | ||
| 7455 | { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, | ||
| 7456 | 0x00000000, 0x000001ff }, | ||
| 7457 | { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, | ||
| 7458 | 0x00000000, 0x000001ff }, | ||
| 7459 | { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, | ||
| 7460 | 0x00000000, 0x000007ff }, | ||
| 7461 | { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, | ||
| 7462 | 0x00000000, 0x000001ff }, | ||
| 7463 | |||
| 7464 | { 0xffff, 0x0000, 0x00000000, 0x00000000 }, | ||
| 7465 | }; | ||
| 7466 | |||
| 7467 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
| 7468 | is_5705 = 1; | ||
| 7469 | else | ||
| 7470 | is_5705 = 0; | ||
| 7471 | |||
| 7472 | for (i = 0; reg_tbl[i].offset != 0xffff; i++) { | ||
| 7473 | if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) | ||
| 7474 | continue; | ||
| 7475 | |||
| 7476 | if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) | ||
| 7477 | continue; | ||
| 7478 | |||
| 7479 | if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
| 7480 | (reg_tbl[i].flags & TG3_FL_NOT_5788)) | ||
| 7481 | continue; | ||
| 7482 | |||
| 7483 | offset = (u32) reg_tbl[i].offset; | ||
| 7484 | read_mask = reg_tbl[i].read_mask; | ||
| 7485 | write_mask = reg_tbl[i].write_mask; | ||
| 7486 | |||
| 7487 | /* Save the original register content */ | ||
| 7488 | save_val = tr32(offset); | ||
| 7489 | |||
| 7490 | /* Determine the read-only value. */ | ||
| 7491 | read_val = save_val & read_mask; | ||
| 7492 | |||
| 7493 | /* Write zero to the register, then make sure the read-only bits | ||
| 7494 | * are not changed and the read/write bits are all zeros. | ||
| 7495 | */ | ||
| 7496 | tw32(offset, 0); | ||
| 7497 | |||
| 7498 | val = tr32(offset); | ||
| 7499 | |||
| 7500 | /* Test the read-only and read/write bits. */ | ||
| 7501 | if (((val & read_mask) != read_val) || (val & write_mask)) | ||
| 7502 | goto out; | ||
| 7503 | |||
| 7504 | /* Write ones to all the bits defined by RdMask and WrMask, then | ||
| 7505 | * make sure the read-only bits are not changed and the | ||
| 7506 | * read/write bits are all ones. | ||
| 7507 | */ | ||
| 7508 | tw32(offset, read_mask | write_mask); | ||
| 7509 | |||
| 7510 | val = tr32(offset); | ||
| 7511 | |||
| 7512 | /* Test the read-only bits. */ | ||
| 7513 | if ((val & read_mask) != read_val) | ||
| 7514 | goto out; | ||
| 7515 | |||
| 7516 | /* Test the read/write bits. */ | ||
| 7517 | if ((val & write_mask) != write_mask) | ||
| 7518 | goto out; | ||
| 7519 | |||
| 7520 | tw32(offset, save_val); | ||
| 7521 | } | ||
| 7522 | |||
| 7523 | return 0; | ||
| 7524 | |||
| 7525 | out: | ||
| 7526 | printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); | ||
| 7527 | tw32(offset, save_val); | ||
| 7528 | return -EIO; | ||
| 7529 | } | ||
| 7530 | |||
| 7531 | static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) | ||
| 7532 | { | ||
| 7533 | static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; | ||
| 7534 | int i; | ||
| 7535 | u32 j; | ||
| 7536 | |||
| 7537 | for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) { | ||
| 7538 | for (j = 0; j < len; j += 4) { | ||
| 7539 | u32 val; | ||
| 7540 | |||
| 7541 | tg3_write_mem(tp, offset + j, test_pattern[i]); | ||
| 7542 | tg3_read_mem(tp, offset + j, &val); | ||
| 7543 | if (val != test_pattern[i]) | ||
| 7544 | return -EIO; | ||
| 7545 | } | ||
| 7546 | } | ||
| 7547 | return 0; | ||
| 7548 | } | ||
| 7549 | |||
| 7550 | static int tg3_test_memory(struct tg3 *tp) | ||
| 7551 | { | ||
| 7552 | static struct mem_entry { | ||
| 7553 | u32 offset; | ||
| 7554 | u32 len; | ||
| 7555 | } mem_tbl_570x[] = { | ||
| 7556 | { 0x00000000, 0x01000}, | ||
| 7557 | { 0x00002000, 0x1c000}, | ||
| 7558 | { 0xffffffff, 0x00000} | ||
| 7559 | }, mem_tbl_5705[] = { | ||
| 7560 | { 0x00000100, 0x0000c}, | ||
| 7561 | { 0x00000200, 0x00008}, | ||
| 7562 | { 0x00000b50, 0x00400}, | ||
| 7563 | { 0x00004000, 0x00800}, | ||
| 7564 | { 0x00006000, 0x01000}, | ||
| 7565 | { 0x00008000, 0x02000}, | ||
| 7566 | { 0x00010000, 0x0e000}, | ||
| 7567 | { 0xffffffff, 0x00000} | ||
| 7568 | }; | ||
| 7569 | struct mem_entry *mem_tbl; | ||
| 7570 | int err = 0; | ||
| 7571 | int i; | ||
| 7572 | |||
| 7573 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
| 7574 | mem_tbl = mem_tbl_5705; | ||
| 7575 | else | ||
| 7576 | mem_tbl = mem_tbl_570x; | ||
| 7577 | |||
| 7578 | for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { | ||
| 7579 | if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, | ||
| 7580 | mem_tbl[i].len)) != 0) | ||
| 7581 | break; | ||
| 7582 | } | ||
| 7583 | |||
| 7584 | return err; | ||
| 7585 | } | ||
| 7586 | |||
| 7587 | static int tg3_test_loopback(struct tg3 *tp) | ||
| 7588 | { | ||
| 7589 | u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; | ||
| 7590 | u32 desc_idx; | ||
| 7591 | struct sk_buff *skb, *rx_skb; | ||
| 7592 | u8 *tx_data; | ||
| 7593 | dma_addr_t map; | ||
| 7594 | int num_pkts, tx_len, rx_len, i, err; | ||
| 7595 | struct tg3_rx_buffer_desc *desc; | ||
| 7596 | |||
| 7597 | if (!netif_running(tp->dev)) | ||
| 7598 | return -ENODEV; | ||
| 7599 | |||
| 7600 | err = -EIO; | ||
| 7601 | |||
| 7602 | tg3_abort_hw(tp, 1); | ||
| 7603 | |||
| 7604 | /* Clearing this flag to keep interrupts disabled */ | ||
| 7605 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
| 7606 | tg3_reset_hw(tp); | ||
| 7607 | |||
| 7608 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
| 7609 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
| 7610 | MAC_MODE_PORT_MODE_GMII; | ||
| 7611 | tw32(MAC_MODE, mac_mode); | ||
| 7612 | |||
| 7613 | tx_len = 1514; | ||
| 7614 | skb = dev_alloc_skb(tx_len); | ||
| 7615 | tx_data = skb_put(skb, tx_len); | ||
| 7616 | memcpy(tx_data, tp->dev->dev_addr, 6); | ||
| 7617 | memset(tx_data + 6, 0x0, 8); | ||
| 7618 | |||
| 7619 | tw32(MAC_RX_MTU_SIZE, tx_len + 4); | ||
| 7620 | |||
| 7621 | for (i = 14; i < tx_len; i++) | ||
| 7622 | tx_data[i] = (u8) (i & 0xff); | ||
| 7623 | |||
| 7624 | map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); | ||
| 7625 | |||
| 7626 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
| 7627 | HOSTCC_MODE_NOW); | ||
| 7628 | |||
| 7629 | udelay(10); | ||
| 7630 | |||
| 7631 | rx_start_idx = tp->hw_status->idx[0].rx_producer; | ||
| 7632 | |||
| 7633 | send_idx = 0; | ||
| 7634 | num_pkts = 0; | ||
| 7635 | |||
| 7636 | tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); | ||
| 7637 | |||
| 7638 | send_idx++; | ||
| 7639 | num_pkts++; | ||
| 7640 | |||
| 7641 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | ||
| 7642 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | ||
| 7643 | |||
| 7644 | udelay(10); | ||
| 7645 | |||
| 7646 | for (i = 0; i < 10; i++) { | ||
| 7647 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
| 7648 | HOSTCC_MODE_NOW); | ||
| 7649 | |||
| 7650 | udelay(10); | ||
| 7651 | |||
| 7652 | tx_idx = tp->hw_status->idx[0].tx_consumer; | ||
| 7653 | rx_idx = tp->hw_status->idx[0].rx_producer; | ||
| 7654 | if ((tx_idx == send_idx) && | ||
| 7655 | (rx_idx == (rx_start_idx + num_pkts))) | ||
| 7656 | break; | ||
| 7657 | } | ||
| 7658 | |||
| 7659 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | ||
| 7660 | dev_kfree_skb(skb); | ||
| 7661 | |||
| 7662 | if (tx_idx != send_idx) | ||
| 7663 | goto out; | ||
| 7664 | |||
| 7665 | if (rx_idx != rx_start_idx + num_pkts) | ||
| 7666 | goto out; | ||
| 7667 | |||
| 7668 | desc = &tp->rx_rcb[rx_start_idx]; | ||
| 7669 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | ||
| 7670 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | ||
| 7671 | if (opaque_key != RXD_OPAQUE_RING_STD) | ||
| 7672 | goto out; | ||
| 7673 | |||
| 7674 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | ||
| 7675 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) | ||
| 7676 | goto out; | ||
| 7677 | |||
| 7678 | rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; | ||
| 7679 | if (rx_len != tx_len) | ||
| 7680 | goto out; | ||
| 7681 | |||
| 7682 | rx_skb = tp->rx_std_buffers[desc_idx].skb; | ||
| 7683 | |||
| 7684 | map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping); | ||
| 7685 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); | ||
| 7686 | |||
| 7687 | for (i = 14; i < tx_len; i++) { | ||
| 7688 | if (*(rx_skb->data + i) != (u8) (i & 0xff)) | ||
| 7689 | goto out; | ||
| 7690 | } | ||
| 7691 | err = 0; | ||
| 7692 | |||
| 7693 | /* tg3_free_rings will unmap and free the rx_skb */ | ||
| 7694 | out: | ||
| 7695 | return err; | ||
| 7696 | } | ||
| 7697 | |||
| 7698 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | ||
| 7699 | u64 *data) | ||
| 7700 | { | ||
| 7701 | struct tg3 *tp = netdev_priv(dev); | ||
| 7702 | |||
| 7703 | memset(data, 0, sizeof(u64) * TG3_NUM_TEST); | ||
| 7704 | |||
| 7705 | if (tg3_test_nvram(tp) != 0) { | ||
| 7706 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7707 | data[0] = 1; | ||
| 7708 | } | ||
| 7709 | if (tg3_test_link(tp) != 0) { | ||
| 7710 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7711 | data[1] = 1; | ||
| 7712 | } | ||
| 7713 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | ||
| 7714 | if (netif_running(dev)) | ||
| 7715 | tg3_netif_stop(tp); | ||
| 7716 | |||
| 7717 | spin_lock_irq(&tp->lock); | ||
| 7718 | spin_lock(&tp->tx_lock); | ||
| 7719 | |||
| 7720 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | ||
| 7721 | tg3_nvram_lock(tp); | ||
| 7722 | tg3_halt_cpu(tp, RX_CPU_BASE); | ||
| 7723 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | ||
| 7724 | tg3_halt_cpu(tp, TX_CPU_BASE); | ||
| 7725 | tg3_nvram_unlock(tp); | ||
| 7726 | |||
| 7727 | if (tg3_test_registers(tp) != 0) { | ||
| 7728 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7729 | data[2] = 1; | ||
| 7730 | } | ||
| 7731 | if (tg3_test_memory(tp) != 0) { | ||
| 7732 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7733 | data[3] = 1; | ||
| 7734 | } | ||
| 7735 | if (tg3_test_loopback(tp) != 0) { | ||
| 7736 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7737 | data[4] = 1; | ||
| 7738 | } | ||
| 7739 | |||
| 7740 | spin_unlock(&tp->tx_lock); | ||
| 7741 | spin_unlock_irq(&tp->lock); | ||
| 7742 | if (tg3_test_interrupt(tp) != 0) { | ||
| 7743 | etest->flags |= ETH_TEST_FL_FAILED; | ||
| 7744 | data[5] = 1; | ||
| 7745 | } | ||
| 7746 | spin_lock_irq(&tp->lock); | ||
| 7747 | spin_lock(&tp->tx_lock); | ||
| 7748 | |||
| 7749 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
| 7750 | if (netif_running(dev)) { | ||
| 7751 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | ||
| 7752 | tg3_init_hw(tp); | ||
| 7753 | tg3_netif_start(tp); | ||
| 7754 | } | ||
| 7755 | spin_unlock(&tp->tx_lock); | ||
| 7756 | spin_unlock_irq(&tp->lock); | ||
| 7757 | } | ||
| 7758 | } | ||
| 7759 | |||
| 7221 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 7760 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 7222 | { | 7761 | { |
| 7223 | struct mii_ioctl_data *data = if_mii(ifr); | 7762 | struct mii_ioctl_data *data = if_mii(ifr); |
| @@ -7331,6 +7870,8 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
| 7331 | .get_tso = ethtool_op_get_tso, | 7870 | .get_tso = ethtool_op_get_tso, |
| 7332 | .set_tso = tg3_set_tso, | 7871 | .set_tso = tg3_set_tso, |
| 7333 | #endif | 7872 | #endif |
| 7873 | .self_test_count = tg3_get_test_count, | ||
| 7874 | .self_test = tg3_self_test, | ||
| 7334 | .get_strings = tg3_get_strings, | 7875 | .get_strings = tg3_get_strings, |
| 7335 | .get_stats_count = tg3_get_stats_count, | 7876 | .get_stats_count = tg3_get_stats_count, |
| 7336 | .get_ethtool_stats = tg3_get_ethtool_stats, | 7877 | .get_ethtool_stats = tg3_get_ethtool_stats, |
| @@ -9478,7 +10019,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 9478 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 10019 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
| 9479 | pci_save_state(tp->pdev); | 10020 | pci_save_state(tp->pdev); |
| 9480 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | 10021 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); |
| 9481 | tg3_halt(tp, 1); | 10022 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 9482 | } | 10023 | } |
| 9483 | 10024 | ||
| 9484 | err = tg3_test_dma(tp); | 10025 | err = tg3_test_dma(tp); |
| @@ -9605,7 +10146,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 9605 | 10146 | ||
| 9606 | spin_lock_irq(&tp->lock); | 10147 | spin_lock_irq(&tp->lock); |
| 9607 | spin_lock(&tp->tx_lock); | 10148 | spin_lock(&tp->tx_lock); |
| 9608 | tg3_halt(tp, 1); | 10149 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
| 9609 | spin_unlock(&tp->tx_lock); | 10150 | spin_unlock(&tp->tx_lock); |
| 9610 | spin_unlock_irq(&tp->lock); | 10151 | spin_unlock_irq(&tp->lock); |
| 9611 | 10152 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 9e9dab7fe86a..8132d946c384 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * CompactPCI Hot Plug Driver | 2 | * CompactPCI Hot Plug Driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2002 SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 SOMA Networks, Inc. |
| 5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) | 5 | * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) |
| 6 | * Copyright (C) 2001 IBM Corp. | 6 | * Copyright (C) 2001 IBM Corp. |
| 7 | * | 7 | * |
| @@ -45,10 +45,10 @@ | |||
| 45 | 45 | ||
| 46 | #define dbg(format, arg...) \ | 46 | #define dbg(format, arg...) \ |
| 47 | do { \ | 47 | do { \ |
| 48 | if(cpci_debug) \ | 48 | if (cpci_debug) \ |
| 49 | printk (KERN_DEBUG "%s: " format "\n", \ | 49 | printk (KERN_DEBUG "%s: " format "\n", \ |
| 50 | MY_NAME , ## arg); \ | 50 | MY_NAME , ## arg); \ |
| 51 | } while(0) | 51 | } while (0) |
| 52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 52 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
| 53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 53 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
| 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
| @@ -111,10 +111,8 @@ enable_slot(struct hotplug_slot *hotplug_slot) | |||
| 111 | 111 | ||
| 112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 112 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
| 113 | 113 | ||
| 114 | if(controller->ops->set_power) { | 114 | if (controller->ops->set_power) |
| 115 | retval = controller->ops->set_power(slot, 1); | 115 | retval = controller->ops->set_power(slot, 1); |
| 116 | } | ||
| 117 | |||
| 118 | return retval; | 116 | return retval; |
| 119 | } | 117 | } |
| 120 | 118 | ||
| @@ -126,37 +124,41 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
| 126 | 124 | ||
| 127 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); | 125 | dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); |
| 128 | 126 | ||
| 127 | down_write(&list_rwsem); | ||
| 128 | |||
| 129 | /* Unconfigure device */ | 129 | /* Unconfigure device */ |
| 130 | dbg("%s - unconfiguring slot %s", | 130 | dbg("%s - unconfiguring slot %s", |
| 131 | __FUNCTION__, slot->hotplug_slot->name); | 131 | __FUNCTION__, slot->hotplug_slot->name); |
| 132 | if((retval = cpci_unconfigure_slot(slot))) { | 132 | if ((retval = cpci_unconfigure_slot(slot))) { |
| 133 | err("%s - could not unconfigure slot %s", | 133 | err("%s - could not unconfigure slot %s", |
| 134 | __FUNCTION__, slot->hotplug_slot->name); | 134 | __FUNCTION__, slot->hotplug_slot->name); |
| 135 | return retval; | 135 | goto disable_error; |
| 136 | } | 136 | } |
| 137 | dbg("%s - finished unconfiguring slot %s", | 137 | dbg("%s - finished unconfiguring slot %s", |
| 138 | __FUNCTION__, slot->hotplug_slot->name); | 138 | __FUNCTION__, slot->hotplug_slot->name); |
| 139 | 139 | ||
| 140 | /* Clear EXT (by setting it) */ | 140 | /* Clear EXT (by setting it) */ |
| 141 | if(cpci_clear_ext(slot)) { | 141 | if (cpci_clear_ext(slot)) { |
| 142 | err("%s - could not clear EXT for slot %s", | 142 | err("%s - could not clear EXT for slot %s", |
| 143 | __FUNCTION__, slot->hotplug_slot->name); | 143 | __FUNCTION__, slot->hotplug_slot->name); |
| 144 | retval = -ENODEV; | 144 | retval = -ENODEV; |
| 145 | goto disable_error; | ||
| 145 | } | 146 | } |
| 146 | cpci_led_on(slot); | 147 | cpci_led_on(slot); |
| 147 | 148 | ||
| 148 | if(controller->ops->set_power) { | 149 | if (controller->ops->set_power) |
| 149 | retval = controller->ops->set_power(slot, 0); | 150 | if ((retval = controller->ops->set_power(slot, 0))) |
| 150 | } | 151 | goto disable_error; |
| 151 | 152 | ||
| 152 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 153 | if (update_adapter_status(slot->hotplug_slot, 0)) |
| 153 | warn("failure to update adapter file"); | 154 | warn("failure to update adapter file"); |
| 154 | } | ||
| 155 | 155 | ||
| 156 | if(slot->extracting) { | 156 | if (slot->extracting) { |
| 157 | slot->extracting = 0; | 157 | slot->extracting = 0; |
| 158 | atomic_dec(&extracting); | 158 | atomic_dec(&extracting); |
| 159 | } | 159 | } |
| 160 | disable_error: | ||
| 161 | up_write(&list_rwsem); | ||
| 160 | return retval; | 162 | return retval; |
| 161 | } | 163 | } |
| 162 | 164 | ||
| @@ -165,9 +167,8 @@ cpci_get_power_status(struct slot *slot) | |||
| 165 | { | 167 | { |
| 166 | u8 power = 1; | 168 | u8 power = 1; |
| 167 | 169 | ||
| 168 | if(controller->ops->get_power) { | 170 | if (controller->ops->get_power) |
| 169 | power = controller->ops->get_power(slot); | 171 | power = controller->ops->get_power(slot); |
| 170 | } | ||
| 171 | return power; | 172 | return power; |
| 172 | } | 173 | } |
| 173 | 174 | ||
| @@ -237,9 +238,8 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) | |||
| 237 | int status = -ENOMEM; | 238 | int status = -ENOMEM; |
| 238 | int i; | 239 | int i; |
| 239 | 240 | ||
| 240 | if(!(controller && bus)) { | 241 | if (!(controller && bus)) |
| 241 | return -ENODEV; | 242 | return -ENODEV; |
| 242 | } | ||
| 243 | 243 | ||
| 244 | /* | 244 | /* |
| 245 | * Create a structure for each slot, and register that slot | 245 | * Create a structure for each slot, and register that slot |
| @@ -316,32 +316,30 @@ int | |||
| 316 | cpci_hp_unregister_bus(struct pci_bus *bus) | 316 | cpci_hp_unregister_bus(struct pci_bus *bus) |
| 317 | { | 317 | { |
| 318 | struct slot *slot; | 318 | struct slot *slot; |
| 319 | struct list_head *tmp; | 319 | struct slot *tmp; |
| 320 | struct list_head *next; | 320 | int status = 0; |
| 321 | int status; | ||
| 322 | 321 | ||
| 323 | down_write(&list_rwsem); | 322 | down_write(&list_rwsem); |
| 324 | if(!slots) { | 323 | if (!slots) { |
| 325 | up_write(&list_rwsem); | 324 | up_write(&list_rwsem); |
| 326 | return -1; | 325 | return -1; |
| 327 | } | 326 | } |
| 328 | list_for_each_safe(tmp, next, &slot_list) { | 327 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { |
| 329 | slot = list_entry(tmp, struct slot, slot_list); | 328 | if (slot->bus == bus) { |
| 330 | if(slot->bus == bus) { | 329 | list_del(&slot->slot_list); |
| 330 | slots--; | ||
| 331 | |||
| 331 | dbg("deregistering slot %s", slot->hotplug_slot->name); | 332 | dbg("deregistering slot %s", slot->hotplug_slot->name); |
| 332 | status = pci_hp_deregister(slot->hotplug_slot); | 333 | status = pci_hp_deregister(slot->hotplug_slot); |
| 333 | if(status) { | 334 | if (status) { |
| 334 | err("pci_hp_deregister failed with error %d", | 335 | err("pci_hp_deregister failed with error %d", |
| 335 | status); | 336 | status); |
| 336 | return status; | 337 | break; |
| 337 | } | 338 | } |
| 338 | |||
| 339 | list_del(&slot->slot_list); | ||
| 340 | slots--; | ||
| 341 | } | 339 | } |
| 342 | } | 340 | } |
| 343 | up_write(&list_rwsem); | 341 | up_write(&list_rwsem); |
| 344 | return 0; | 342 | return status; |
| 345 | } | 343 | } |
| 346 | 344 | ||
| 347 | /* This is the interrupt mode interrupt handler */ | 345 | /* This is the interrupt mode interrupt handler */ |
| @@ -351,7 +349,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
| 351 | dbg("entered cpci_hp_intr"); | 349 | dbg("entered cpci_hp_intr"); |
| 352 | 350 | ||
| 353 | /* Check to see if it was our interrupt */ | 351 | /* Check to see if it was our interrupt */ |
| 354 | if((controller->irq_flags & SA_SHIRQ) && | 352 | if ((controller->irq_flags & SA_SHIRQ) && |
| 355 | !controller->ops->check_irq(controller->dev_id)) { | 353 | !controller->ops->check_irq(controller->dev_id)) { |
| 356 | dbg("exited cpci_hp_intr, not our interrupt"); | 354 | dbg("exited cpci_hp_intr, not our interrupt"); |
| 357 | return IRQ_NONE; | 355 | return IRQ_NONE; |
| @@ -373,38 +371,30 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
| 373 | * INS bits of the cold-inserted devices. | 371 | * INS bits of the cold-inserted devices. |
| 374 | */ | 372 | */ |
| 375 | static int | 373 | static int |
| 376 | init_slots(void) | 374 | init_slots(int clear_ins) |
| 377 | { | 375 | { |
| 378 | struct slot *slot; | 376 | struct slot *slot; |
| 379 | struct list_head *tmp; | ||
| 380 | struct pci_dev* dev; | 377 | struct pci_dev* dev; |
| 381 | 378 | ||
| 382 | dbg("%s - enter", __FUNCTION__); | 379 | dbg("%s - enter", __FUNCTION__); |
| 383 | down_read(&list_rwsem); | 380 | down_read(&list_rwsem); |
| 384 | if(!slots) { | 381 | if (!slots) { |
| 385 | up_read(&list_rwsem); | 382 | up_read(&list_rwsem); |
| 386 | return -1; | 383 | return -1; |
| 387 | } | 384 | } |
| 388 | list_for_each(tmp, &slot_list) { | 385 | list_for_each_entry(slot, &slot_list, slot_list) { |
| 389 | slot = list_entry(tmp, struct slot, slot_list); | ||
| 390 | dbg("%s - looking at slot %s", | 386 | dbg("%s - looking at slot %s", |
| 391 | __FUNCTION__, slot->hotplug_slot->name); | 387 | __FUNCTION__, slot->hotplug_slot->name); |
| 392 | if(cpci_check_and_clear_ins(slot)) { | 388 | if (clear_ins && cpci_check_and_clear_ins(slot)) |
| 393 | dbg("%s - cleared INS for slot %s", | 389 | dbg("%s - cleared INS for slot %s", |
| 394 | __FUNCTION__, slot->hotplug_slot->name); | 390 | __FUNCTION__, slot->hotplug_slot->name); |
| 395 | dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0)); | 391 | dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); |
| 396 | if(dev) { | 392 | if (dev) { |
| 397 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 393 | if (update_adapter_status(slot->hotplug_slot, 1)) |
| 398 | warn("failure to update adapter file"); | 394 | warn("failure to update adapter file"); |
| 399 | } | 395 | if (update_latch_status(slot->hotplug_slot, 1)) |
| 400 | if(update_latch_status(slot->hotplug_slot, 1)) { | 396 | warn("failure to update latch file"); |
| 401 | warn("failure to update latch file"); | 397 | slot->dev = dev; |
| 402 | } | ||
| 403 | slot->dev = dev; | ||
| 404 | } else { | ||
| 405 | err("%s - no driver attached to device in slot %s", | ||
| 406 | __FUNCTION__, slot->hotplug_slot->name); | ||
| 407 | } | ||
| 408 | } | 398 | } |
| 409 | } | 399 | } |
| 410 | up_read(&list_rwsem); | 400 | up_read(&list_rwsem); |
| @@ -416,26 +406,28 @@ static int | |||
| 416 | check_slots(void) | 406 | check_slots(void) |
| 417 | { | 407 | { |
| 418 | struct slot *slot; | 408 | struct slot *slot; |
| 419 | struct list_head *tmp; | ||
| 420 | int extracted; | 409 | int extracted; |
| 421 | int inserted; | 410 | int inserted; |
| 422 | u16 hs_csr; | 411 | u16 hs_csr; |
| 423 | 412 | ||
| 424 | down_read(&list_rwsem); | 413 | down_read(&list_rwsem); |
| 425 | if(!slots) { | 414 | if (!slots) { |
| 426 | up_read(&list_rwsem); | 415 | up_read(&list_rwsem); |
| 427 | err("no slots registered, shutting down"); | 416 | err("no slots registered, shutting down"); |
| 428 | return -1; | 417 | return -1; |
| 429 | } | 418 | } |
| 430 | extracted = inserted = 0; | 419 | extracted = inserted = 0; |
| 431 | list_for_each(tmp, &slot_list) { | 420 | list_for_each_entry(slot, &slot_list, slot_list) { |
| 432 | slot = list_entry(tmp, struct slot, slot_list); | ||
| 433 | dbg("%s - looking at slot %s", | 421 | dbg("%s - looking at slot %s", |
| 434 | __FUNCTION__, slot->hotplug_slot->name); | 422 | __FUNCTION__, slot->hotplug_slot->name); |
| 435 | if(cpci_check_and_clear_ins(slot)) { | 423 | if (cpci_check_and_clear_ins(slot)) { |
| 436 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ | 424 | /* |
| 437 | if(slot->dev) { | 425 | * Some broken hardware (e.g. PLX 9054AB) asserts |
| 438 | warn("slot %s already inserted", slot->hotplug_slot->name); | 426 | * ENUM# twice... |
| 427 | */ | ||
| 428 | if (slot->dev) { | ||
| 429 | warn("slot %s already inserted", | ||
| 430 | slot->hotplug_slot->name); | ||
| 439 | inserted++; | 431 | inserted++; |
| 440 | continue; | 432 | continue; |
| 441 | } | 433 | } |
| @@ -452,7 +444,7 @@ check_slots(void) | |||
| 452 | /* Configure device */ | 444 | /* Configure device */ |
| 453 | dbg("%s - configuring slot %s", | 445 | dbg("%s - configuring slot %s", |
| 454 | __FUNCTION__, slot->hotplug_slot->name); | 446 | __FUNCTION__, slot->hotplug_slot->name); |
| 455 | if(cpci_configure_slot(slot)) { | 447 | if (cpci_configure_slot(slot)) { |
| 456 | err("%s - could not configure slot %s", | 448 | err("%s - could not configure slot %s", |
| 457 | __FUNCTION__, slot->hotplug_slot->name); | 449 | __FUNCTION__, slot->hotplug_slot->name); |
| 458 | continue; | 450 | continue; |
| @@ -465,13 +457,11 @@ check_slots(void) | |||
| 465 | dbg("%s - slot %s HS_CSR (2) = %04x", | 457 | dbg("%s - slot %s HS_CSR (2) = %04x", |
| 466 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 458 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
| 467 | 459 | ||
| 468 | if(update_latch_status(slot->hotplug_slot, 1)) { | 460 | if (update_latch_status(slot->hotplug_slot, 1)) |
| 469 | warn("failure to update latch file"); | 461 | warn("failure to update latch file"); |
| 470 | } | ||
| 471 | 462 | ||
| 472 | if(update_adapter_status(slot->hotplug_slot, 1)) { | 463 | if (update_adapter_status(slot->hotplug_slot, 1)) |
| 473 | warn("failure to update adapter file"); | 464 | warn("failure to update adapter file"); |
| 474 | } | ||
| 475 | 465 | ||
| 476 | cpci_led_off(slot); | 466 | cpci_led_off(slot); |
| 477 | 467 | ||
| @@ -481,7 +471,7 @@ check_slots(void) | |||
| 481 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 471 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
| 482 | 472 | ||
| 483 | inserted++; | 473 | inserted++; |
| 484 | } else if(cpci_check_ext(slot)) { | 474 | } else if (cpci_check_ext(slot)) { |
| 485 | /* Process extraction request */ | 475 | /* Process extraction request */ |
| 486 | dbg("%s - slot %s extracted", | 476 | dbg("%s - slot %s extracted", |
| 487 | __FUNCTION__, slot->hotplug_slot->name); | 477 | __FUNCTION__, slot->hotplug_slot->name); |
| @@ -491,27 +481,25 @@ check_slots(void) | |||
| 491 | dbg("%s - slot %s HS_CSR = %04x", | 481 | dbg("%s - slot %s HS_CSR = %04x", |
| 492 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); | 482 | __FUNCTION__, slot->hotplug_slot->name, hs_csr); |
| 493 | 483 | ||
| 494 | if(!slot->extracting) { | 484 | if (!slot->extracting) { |
| 495 | if(update_latch_status(slot->hotplug_slot, 0)) { | 485 | if (update_latch_status(slot->hotplug_slot, 0)) { |
| 496 | warn("failure to update latch file"); | 486 | warn("failure to update latch file"); |
| 497 | |||
| 498 | } | 487 | } |
| 499 | atomic_inc(&extracting); | ||
| 500 | slot->extracting = 1; | 488 | slot->extracting = 1; |
| 489 | atomic_inc(&extracting); | ||
| 501 | } | 490 | } |
| 502 | extracted++; | 491 | extracted++; |
| 503 | } else if(slot->extracting) { | 492 | } else if (slot->extracting) { |
| 504 | hs_csr = cpci_get_hs_csr(slot); | 493 | hs_csr = cpci_get_hs_csr(slot); |
| 505 | if(hs_csr == 0xffff) { | 494 | if (hs_csr == 0xffff) { |
| 506 | /* | 495 | /* |
| 507 | * Hmmm, we're likely hosed at this point, should we | 496 | * Hmmm, we're likely hosed at this point, should we |
| 508 | * bother trying to tell the driver or not? | 497 | * bother trying to tell the driver or not? |
| 509 | */ | 498 | */ |
| 510 | err("card in slot %s was improperly removed", | 499 | err("card in slot %s was improperly removed", |
| 511 | slot->hotplug_slot->name); | 500 | slot->hotplug_slot->name); |
| 512 | if(update_adapter_status(slot->hotplug_slot, 0)) { | 501 | if (update_adapter_status(slot->hotplug_slot, 0)) |
| 513 | warn("failure to update adapter file"); | 502 | warn("failure to update adapter file"); |
| 514 | } | ||
| 515 | slot->extracting = 0; | 503 | slot->extracting = 0; |
| 516 | atomic_dec(&extracting); | 504 | atomic_dec(&extracting); |
| 517 | } | 505 | } |
| @@ -520,10 +508,9 @@ check_slots(void) | |||
| 520 | up_read(&list_rwsem); | 508 | up_read(&list_rwsem); |
| 521 | dbg("inserted=%d, extracted=%d, extracting=%d", | 509 | dbg("inserted=%d, extracted=%d, extracting=%d", |
| 522 | inserted, extracted, atomic_read(&extracting)); | 510 | inserted, extracted, atomic_read(&extracting)); |
| 523 | if(inserted || extracted) { | 511 | if (inserted || extracted) |
| 524 | return extracted; | 512 | return extracted; |
| 525 | } | 513 | else if (!atomic_read(&extracting)) { |
| 526 | else if(!atomic_read(&extracting)) { | ||
| 527 | err("cannot find ENUM# source, shutting down"); | 514 | err("cannot find ENUM# source, shutting down"); |
| 528 | return -1; | 515 | return -1; |
| 529 | } | 516 | } |
| @@ -541,12 +528,12 @@ event_thread(void *data) | |||
| 541 | unlock_kernel(); | 528 | unlock_kernel(); |
| 542 | 529 | ||
| 543 | dbg("%s - event thread started", __FUNCTION__); | 530 | dbg("%s - event thread started", __FUNCTION__); |
| 544 | while(1) { | 531 | while (1) { |
| 545 | dbg("event thread sleeping"); | 532 | dbg("event thread sleeping"); |
| 546 | down_interruptible(&event_semaphore); | 533 | down_interruptible(&event_semaphore); |
| 547 | dbg("event thread woken, thread_finished = %d", | 534 | dbg("event thread woken, thread_finished = %d", |
| 548 | thread_finished); | 535 | thread_finished); |
| 549 | if(thread_finished || signal_pending(current)) | 536 | if (thread_finished || signal_pending(current)) |
| 550 | break; | 537 | break; |
| 551 | do { | 538 | do { |
| 552 | rc = check_slots(); | 539 | rc = check_slots(); |
| @@ -558,7 +545,9 @@ event_thread(void *data) | |||
| 558 | thread_finished = 1; | 545 | thread_finished = 1; |
| 559 | break; | 546 | break; |
| 560 | } | 547 | } |
| 561 | } while(atomic_read(&extracting) != 0); | 548 | } while (atomic_read(&extracting) && !thread_finished); |
| 549 | if (thread_finished) | ||
| 550 | break; | ||
| 562 | 551 | ||
| 563 | /* Re-enable ENUM# interrupt */ | 552 | /* Re-enable ENUM# interrupt */ |
| 564 | dbg("%s - re-enabling irq", __FUNCTION__); | 553 | dbg("%s - re-enabling irq", __FUNCTION__); |
| @@ -579,21 +568,21 @@ poll_thread(void *data) | |||
| 579 | daemonize("cpci_hp_polld"); | 568 | daemonize("cpci_hp_polld"); |
| 580 | unlock_kernel(); | 569 | unlock_kernel(); |
| 581 | 570 | ||
| 582 | while(1) { | 571 | while (1) { |
| 583 | if(thread_finished || signal_pending(current)) | 572 | if (thread_finished || signal_pending(current)) |
| 584 | break; | 573 | break; |
| 585 | if(controller->ops->query_enum()) { | 574 | if (controller->ops->query_enum()) { |
| 586 | do { | 575 | do { |
| 587 | rc = check_slots(); | 576 | rc = check_slots(); |
| 588 | if(rc > 0) { | 577 | if (rc > 0) { |
| 589 | /* Give userspace a chance to handle extraction */ | 578 | /* Give userspace a chance to handle extraction */ |
| 590 | msleep(500); | 579 | msleep(500); |
| 591 | } else if(rc < 0) { | 580 | } else if (rc < 0) { |
| 592 | dbg("%s - error checking slots", __FUNCTION__); | 581 | dbg("%s - error checking slots", __FUNCTION__); |
| 593 | thread_finished = 1; | 582 | thread_finished = 1; |
| 594 | break; | 583 | break; |
| 595 | } | 584 | } |
| 596 | } while(atomic_read(&extracting) != 0); | 585 | } while (atomic_read(&extracting) && !thread_finished); |
| 597 | } | 586 | } |
| 598 | msleep(100); | 587 | msleep(100); |
| 599 | } | 588 | } |
| @@ -612,12 +601,11 @@ cpci_start_thread(void) | |||
| 612 | init_MUTEX_LOCKED(&thread_exit); | 601 | init_MUTEX_LOCKED(&thread_exit); |
| 613 | thread_finished = 0; | 602 | thread_finished = 0; |
| 614 | 603 | ||
| 615 | if(controller->irq) { | 604 | if (controller->irq) |
| 616 | pid = kernel_thread(event_thread, NULL, 0); | 605 | pid = kernel_thread(event_thread, NULL, 0); |
| 617 | } else { | 606 | else |
| 618 | pid = kernel_thread(poll_thread, NULL, 0); | 607 | pid = kernel_thread(poll_thread, NULL, 0); |
| 619 | } | 608 | if (pid < 0) { |
| 620 | if(pid < 0) { | ||
| 621 | err("Can't start up our thread"); | 609 | err("Can't start up our thread"); |
| 622 | return -1; | 610 | return -1; |
| 623 | } | 611 | } |
| @@ -630,9 +618,8 @@ cpci_stop_thread(void) | |||
| 630 | { | 618 | { |
| 631 | thread_finished = 1; | 619 | thread_finished = 1; |
| 632 | dbg("thread finish command given"); | 620 | dbg("thread finish command given"); |
| 633 | if(controller->irq) { | 621 | if (controller->irq) |
| 634 | up(&event_semaphore); | 622 | up(&event_semaphore); |
| 635 | } | ||
| 636 | dbg("wait for thread to exit"); | 623 | dbg("wait for thread to exit"); |
| 637 | down(&thread_exit); | 624 | down(&thread_exit); |
| 638 | } | 625 | } |
| @@ -642,45 +629,67 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller) | |||
| 642 | { | 629 | { |
| 643 | int status = 0; | 630 | int status = 0; |
| 644 | 631 | ||
| 645 | if(!controller) { | 632 | if (controller) |
| 646 | controller = new_controller; | 633 | return -1; |
| 647 | if(controller->irq) { | 634 | if (!(new_controller && new_controller->ops)) |
| 648 | if(request_irq(controller->irq, | 635 | return -EINVAL; |
| 649 | cpci_hp_intr, | 636 | if (new_controller->irq) { |
| 650 | controller->irq_flags, | 637 | if (!(new_controller->ops->enable_irq && |
| 651 | MY_NAME, controller->dev_id)) { | 638 | new_controller->ops->disable_irq)) |
| 652 | err("Can't get irq %d for the hotplug cPCI controller", controller->irq); | 639 | status = -EINVAL; |
| 653 | status = -ENODEV; | 640 | if (request_irq(new_controller->irq, |
| 654 | } | 641 | cpci_hp_intr, |
| 655 | dbg("%s - acquired controller irq %d", __FUNCTION__, | 642 | new_controller->irq_flags, |
| 656 | controller->irq); | 643 | MY_NAME, |
| 644 | new_controller->dev_id)) { | ||
| 645 | err("Can't get irq %d for the hotplug cPCI controller", | ||
| 646 | new_controller->irq); | ||
| 647 | status = -ENODEV; | ||
| 657 | } | 648 | } |
| 658 | } else { | 649 | dbg("%s - acquired controller irq %d", |
| 659 | err("cPCI hotplug controller already registered"); | 650 | __FUNCTION__, new_controller->irq); |
| 660 | status = -1; | ||
| 661 | } | 651 | } |
| 652 | if (!status) | ||
| 653 | controller = new_controller; | ||
| 662 | return status; | 654 | return status; |
| 663 | } | 655 | } |
| 664 | 656 | ||
| 657 | static void | ||
| 658 | cleanup_slots(void) | ||
| 659 | { | ||
| 660 | struct slot *slot; | ||
| 661 | struct slot *tmp; | ||
| 662 | |||
| 663 | /* | ||
| 664 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
| 665 | * and free up all memory that we had allocated. | ||
| 666 | */ | ||
| 667 | down_write(&list_rwsem); | ||
| 668 | if (!slots) | ||
| 669 | goto cleanup_null; | ||
| 670 | list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { | ||
| 671 | list_del(&slot->slot_list); | ||
| 672 | pci_hp_deregister(slot->hotplug_slot); | ||
| 673 | } | ||
| 674 | cleanup_null: | ||
| 675 | up_write(&list_rwsem); | ||
| 676 | return; | ||
| 677 | } | ||
| 678 | |||
| 665 | int | 679 | int |
| 666 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) | 680 | cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) |
| 667 | { | 681 | { |
| 668 | int status = 0; | 682 | int status = 0; |
| 669 | 683 | ||
| 670 | if(controller) { | 684 | if (controller) { |
| 671 | if(atomic_read(&extracting) != 0) { | 685 | if (!thread_finished) |
| 672 | return -EBUSY; | ||
| 673 | } | ||
| 674 | if(!thread_finished) { | ||
| 675 | cpci_stop_thread(); | 686 | cpci_stop_thread(); |
| 676 | } | 687 | if (controller->irq) |
| 677 | if(controller->irq) { | ||
| 678 | free_irq(controller->irq, controller->dev_id); | 688 | free_irq(controller->irq, controller->dev_id); |
| 679 | } | ||
| 680 | controller = NULL; | 689 | controller = NULL; |
| 681 | } else { | 690 | cleanup_slots(); |
| 691 | } else | ||
| 682 | status = -ENODEV; | 692 | status = -ENODEV; |
| 683 | } | ||
| 684 | return status; | 693 | return status; |
| 685 | } | 694 | } |
| 686 | 695 | ||
| @@ -691,32 +700,28 @@ cpci_hp_start(void) | |||
| 691 | int status; | 700 | int status; |
| 692 | 701 | ||
| 693 | dbg("%s - enter", __FUNCTION__); | 702 | dbg("%s - enter", __FUNCTION__); |
| 694 | if(!controller) { | 703 | if (!controller) |
| 695 | return -ENODEV; | 704 | return -ENODEV; |
| 696 | } | ||
| 697 | 705 | ||
| 698 | down_read(&list_rwsem); | 706 | down_read(&list_rwsem); |
| 699 | if(list_empty(&slot_list)) { | 707 | if (list_empty(&slot_list)) { |
| 700 | up_read(&list_rwsem); | 708 | up_read(&list_rwsem); |
| 701 | return -ENODEV; | 709 | return -ENODEV; |
| 702 | } | 710 | } |
| 703 | up_read(&list_rwsem); | 711 | up_read(&list_rwsem); |
| 704 | 712 | ||
| 705 | if(first) { | 713 | status = init_slots(first); |
| 706 | status = init_slots(); | 714 | if (first) |
| 707 | if(status) { | ||
| 708 | return status; | ||
| 709 | } | ||
| 710 | first = 0; | 715 | first = 0; |
| 711 | } | 716 | if (status) |
| 717 | return status; | ||
| 712 | 718 | ||
| 713 | status = cpci_start_thread(); | 719 | status = cpci_start_thread(); |
| 714 | if(status) { | 720 | if (status) |
| 715 | return status; | 721 | return status; |
| 716 | } | ||
| 717 | dbg("%s - thread started", __FUNCTION__); | 722 | dbg("%s - thread started", __FUNCTION__); |
| 718 | 723 | ||
| 719 | if(controller->irq) { | 724 | if (controller->irq) { |
| 720 | /* Start enum interrupt processing */ | 725 | /* Start enum interrupt processing */ |
| 721 | dbg("%s - enabling irq", __FUNCTION__); | 726 | dbg("%s - enabling irq", __FUNCTION__); |
| 722 | controller->ops->enable_irq(); | 727 | controller->ops->enable_irq(); |
| @@ -728,13 +733,9 @@ cpci_hp_start(void) | |||
| 728 | int | 733 | int |
| 729 | cpci_hp_stop(void) | 734 | cpci_hp_stop(void) |
| 730 | { | 735 | { |
| 731 | if(!controller) { | 736 | if (!controller) |
| 732 | return -ENODEV; | 737 | return -ENODEV; |
| 733 | } | 738 | if (controller->irq) { |
| 734 | if(atomic_read(&extracting) != 0) { | ||
| 735 | return -EBUSY; | ||
| 736 | } | ||
| 737 | if(controller->irq) { | ||
| 738 | /* Stop enum interrupt processing */ | 739 | /* Stop enum interrupt processing */ |
| 739 | dbg("%s - disabling irq", __FUNCTION__); | 740 | dbg("%s - disabling irq", __FUNCTION__); |
| 740 | controller->ops->disable_irq(); | 741 | controller->ops->disable_irq(); |
| @@ -743,34 +744,6 @@ cpci_hp_stop(void) | |||
| 743 | return 0; | 744 | return 0; |
| 744 | } | 745 | } |
| 745 | 746 | ||
| 746 | static void __exit | ||
| 747 | cleanup_slots(void) | ||
| 748 | { | ||
| 749 | struct list_head *tmp; | ||
| 750 | struct slot *slot; | ||
| 751 | |||
| 752 | /* | ||
| 753 | * Unregister all of our slots with the pci_hotplug subsystem, | ||
| 754 | * and free up all memory that we had allocated. | ||
| 755 | */ | ||
| 756 | down_write(&list_rwsem); | ||
| 757 | if(!slots) { | ||
| 758 | goto null_cleanup; | ||
| 759 | } | ||
| 760 | list_for_each(tmp, &slot_list) { | ||
| 761 | slot = list_entry(tmp, struct slot, slot_list); | ||
| 762 | list_del(&slot->slot_list); | ||
| 763 | pci_hp_deregister(slot->hotplug_slot); | ||
| 764 | kfree(slot->hotplug_slot->info); | ||
| 765 | kfree(slot->hotplug_slot->name); | ||
| 766 | kfree(slot->hotplug_slot); | ||
| 767 | kfree(slot); | ||
| 768 | } | ||
| 769 | null_cleanup: | ||
| 770 | up_write(&list_rwsem); | ||
| 771 | return; | ||
| 772 | } | ||
| 773 | |||
| 774 | int __init | 747 | int __init |
| 775 | cpci_hotplug_init(int debug) | 748 | cpci_hotplug_init(int debug) |
| 776 | { | 749 | { |
| @@ -784,7 +757,8 @@ cpci_hotplug_exit(void) | |||
| 784 | /* | 757 | /* |
| 785 | * Clean everything up. | 758 | * Clean everything up. |
| 786 | */ | 759 | */ |
| 787 | cleanup_slots(); | 760 | cpci_hp_stop(); |
| 761 | cpci_hp_unregister_controller(controller); | ||
| 788 | } | 762 | } |
| 789 | 763 | ||
| 790 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); | 764 | EXPORT_SYMBOL_GPL(cpci_hp_register_controller); |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 69eb4fc54f2f..c878028ad215 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * CompactPCI Hot Plug Driver PCI functions | 2 | * CompactPCI Hot Plug Driver PCI functions |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2002 by SOMA Networks, Inc. | 4 | * Copyright (C) 2002,2005 by SOMA Networks, Inc. |
| 5 | * | 5 | * |
| 6 | * All rights reserved. | 6 | * All rights reserved. |
| 7 | * | 7 | * |
| @@ -38,10 +38,10 @@ extern int cpci_debug; | |||
| 38 | 38 | ||
| 39 | #define dbg(format, arg...) \ | 39 | #define dbg(format, arg...) \ |
| 40 | do { \ | 40 | do { \ |
| 41 | if(cpci_debug) \ | 41 | if (cpci_debug) \ |
| 42 | printk (KERN_DEBUG "%s: " format "\n", \ | 42 | printk (KERN_DEBUG "%s: " format "\n", \ |
| 43 | MY_NAME , ## arg); \ | 43 | MY_NAME , ## arg); \ |
| 44 | } while(0) | 44 | } while (0) |
| 45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) | 45 | #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) |
| 46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 46 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
| 47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 47 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
| @@ -57,16 +57,15 @@ u8 cpci_get_attention_status(struct slot* slot) | |||
| 57 | hs_cap = pci_bus_find_capability(slot->bus, | 57 | hs_cap = pci_bus_find_capability(slot->bus, |
| 58 | slot->devfn, | 58 | slot->devfn, |
| 59 | PCI_CAP_ID_CHSWP); | 59 | PCI_CAP_ID_CHSWP); |
| 60 | if(!hs_cap) { | 60 | if (!hs_cap) |
| 61 | return 0; | 61 | return 0; |
| 62 | } | ||
| 63 | 62 | ||
| 64 | if(pci_bus_read_config_word(slot->bus, | 63 | if (pci_bus_read_config_word(slot->bus, |
| 65 | slot->devfn, | 64 | slot->devfn, |
| 66 | hs_cap + 2, | 65 | hs_cap + 2, |
| 67 | &hs_csr)) { | 66 | &hs_csr)) |
| 68 | return 0; | 67 | return 0; |
| 69 | } | 68 | |
| 70 | return hs_csr & 0x0008 ? 1 : 0; | 69 | return hs_csr & 0x0008 ? 1 : 0; |
| 71 | } | 70 | } |
| 72 | 71 | ||
| @@ -78,27 +77,22 @@ int cpci_set_attention_status(struct slot* slot, int status) | |||
| 78 | hs_cap = pci_bus_find_capability(slot->bus, | 77 | hs_cap = pci_bus_find_capability(slot->bus, |
| 79 | slot->devfn, | 78 | slot->devfn, |
| 80 | PCI_CAP_ID_CHSWP); | 79 | PCI_CAP_ID_CHSWP); |
| 81 | if(!hs_cap) { | 80 | if (!hs_cap) |
| 82 | return 0; | 81 | return 0; |
| 83 | } | 82 | if (pci_bus_read_config_word(slot->bus, |
| 84 | |||
| 85 | if(pci_bus_read_config_word(slot->bus, | ||
| 86 | slot->devfn, | 83 | slot->devfn, |
| 87 | hs_cap + 2, | 84 | hs_cap + 2, |
| 88 | &hs_csr)) { | 85 | &hs_csr)) |
| 89 | return 0; | 86 | return 0; |
| 90 | } | 87 | if (status) |
| 91 | if(status) { | ||
| 92 | hs_csr |= HS_CSR_LOO; | 88 | hs_csr |= HS_CSR_LOO; |
| 93 | } else { | 89 | else |
| 94 | hs_csr &= ~HS_CSR_LOO; | 90 | hs_csr &= ~HS_CSR_LOO; |
| 95 | } | 91 | if (pci_bus_write_config_word(slot->bus, |
| 96 | if(pci_bus_write_config_word(slot->bus, | ||
| 97 | slot->devfn, | 92 | slot->devfn, |
| 98 | hs_cap + 2, | 93 | hs_cap + 2, |
| 99 | hs_csr)) { | 94 | hs_csr)) |
| 100 | return 0; | 95 | return 0; |
| 101 | } | ||
| 102 | return 1; | 96 | return 1; |
| 103 | } | 97 | } |
| 104 | 98 | ||
| @@ -110,16 +104,13 @@ u16 cpci_get_hs_csr(struct slot* slot) | |||
| 110 | hs_cap = pci_bus_find_capability(slot->bus, | 104 | hs_cap = pci_bus_find_capability(slot->bus, |
| 111 | slot->devfn, | 105 | slot->devfn, |
| 112 | PCI_CAP_ID_CHSWP); | 106 | PCI_CAP_ID_CHSWP); |
| 113 | if(!hs_cap) { | 107 | if (!hs_cap) |
| 114 | return 0xFFFF; | 108 | return 0xFFFF; |
| 115 | } | 109 | if (pci_bus_read_config_word(slot->bus, |
| 116 | |||
| 117 | if(pci_bus_read_config_word(slot->bus, | ||
| 118 | slot->devfn, | 110 | slot->devfn, |
| 119 | hs_cap + 2, | 111 | hs_cap + 2, |
| 120 | &hs_csr)) { | 112 | &hs_csr)) |
| 121 | return 0xFFFF; | 113 | return 0xFFFF; |
| 122 | } | ||
| 123 | return hs_csr; | 114 | return hs_csr; |
| 124 | } | 115 | } |
| 125 | 116 | ||
| @@ -132,24 +123,22 @@ int cpci_check_and_clear_ins(struct slot* slot) | |||
| 132 | hs_cap = pci_bus_find_capability(slot->bus, | 123 | hs_cap = pci_bus_find_capability(slot->bus, |
| 133 | slot->devfn, | 124 | slot->devfn, |
| 134 | PCI_CAP_ID_CHSWP); | 125 | PCI_CAP_ID_CHSWP); |
| 135 | if(!hs_cap) { | 126 | if (!hs_cap) |
| 136 | return 0; | 127 | return 0; |
| 137 | } | 128 | if (pci_bus_read_config_word(slot->bus, |
| 138 | if(pci_bus_read_config_word(slot->bus, | ||
| 139 | slot->devfn, | 129 | slot->devfn, |
| 140 | hs_cap + 2, | 130 | hs_cap + 2, |
| 141 | &hs_csr)) { | 131 | &hs_csr)) |
| 142 | return 0; | 132 | return 0; |
| 143 | } | 133 | if (hs_csr & HS_CSR_INS) { |
| 144 | if(hs_csr & HS_CSR_INS) { | ||
| 145 | /* Clear INS (by setting it) */ | 134 | /* Clear INS (by setting it) */ |
| 146 | if(pci_bus_write_config_word(slot->bus, | 135 | if (pci_bus_write_config_word(slot->bus, |
| 147 | slot->devfn, | 136 | slot->devfn, |
| 148 | hs_cap + 2, | 137 | hs_cap + 2, |
| 149 | hs_csr)) { | 138 | hs_csr)) |
| 150 | ins = 0; | 139 | ins = 0; |
| 151 | } | 140 | else |
| 152 | ins = 1; | 141 | ins = 1; |
| 153 | } | 142 | } |
| 154 | return ins; | 143 | return ins; |
| 155 | } | 144 | } |
| @@ -163,18 +152,15 @@ int cpci_check_ext(struct slot* slot) | |||
| 163 | hs_cap = pci_bus_find_capability(slot->bus, | 152 | hs_cap = pci_bus_find_capability(slot->bus, |
| 164 | slot->devfn, | 153 | slot->devfn, |
| 165 | PCI_CAP_ID_CHSWP); | 154 | PCI_CAP_ID_CHSWP); |
| 166 | if(!hs_cap) { | 155 | if (!hs_cap) |
| 167 | return 0; | 156 | return 0; |
| 168 | } | 157 | if (pci_bus_read_config_word(slot->bus, |
| 169 | if(pci_bus_read_config_word(slot->bus, | ||
| 170 | slot->devfn, | 158 | slot->devfn, |
| 171 | hs_cap + 2, | 159 | hs_cap + 2, |
| 172 | &hs_csr)) { | 160 | &hs_csr)) |
| 173 | return 0; | 161 | return 0; |
| 174 | } | 162 | if (hs_csr & HS_CSR_EXT) |
| 175 | if(hs_csr & HS_CSR_EXT) { | ||
| 176 | ext = 1; | 163 | ext = 1; |
| 177 | } | ||
| 178 | return ext; | 164 | return ext; |
| 179 | } | 165 | } |
| 180 | 166 | ||
| @@ -186,23 +172,20 @@ int cpci_clear_ext(struct slot* slot) | |||
| 186 | hs_cap = pci_bus_find_capability(slot->bus, | 172 | hs_cap = pci_bus_find_capability(slot->bus, |
| 187 | slot->devfn, | 173 | slot->devfn, |
| 188 | PCI_CAP_ID_CHSWP); | 174 | PCI_CAP_ID_CHSWP); |
| 189 | if(!hs_cap) { | 175 | if (!hs_cap) |
| 190 | return -ENODEV; | 176 | return -ENODEV; |
| 191 | } | 177 | if (pci_bus_read_config_word(slot->bus, |
| 192 | if(pci_bus_read_config_word(slot->bus, | ||
| 193 | slot->devfn, | 178 | slot->devfn, |
| 194 | hs_cap + 2, | 179 | hs_cap + 2, |
| 195 | &hs_csr)) { | 180 | &hs_csr)) |
| 196 | return -ENODEV; | 181 | return -ENODEV; |
| 197 | } | 182 | if (hs_csr & HS_CSR_EXT) { |
| 198 | if(hs_csr & HS_CSR_EXT) { | ||
| 199 | /* Clear EXT (by setting it) */ | 183 | /* Clear EXT (by setting it) */ |
| 200 | if(pci_bus_write_config_word(slot->bus, | 184 | if (pci_bus_write_config_word(slot->bus, |
| 201 | slot->devfn, | 185 | slot->devfn, |
| 202 | hs_cap + 2, | 186 | hs_cap + 2, |
| 203 | hs_csr)) { | 187 | hs_csr)) |
| 204 | return -ENODEV; | 188 | return -ENODEV; |
| 205 | } | ||
| 206 | } | 189 | } |
| 207 | return 0; | 190 | return 0; |
| 208 | } | 191 | } |
| @@ -215,18 +198,16 @@ int cpci_led_on(struct slot* slot) | |||
| 215 | hs_cap = pci_bus_find_capability(slot->bus, | 198 | hs_cap = pci_bus_find_capability(slot->bus, |
| 216 | slot->devfn, | 199 | slot->devfn, |
| 217 | PCI_CAP_ID_CHSWP); | 200 | PCI_CAP_ID_CHSWP); |
| 218 | if(!hs_cap) { | 201 | if (!hs_cap) |
| 219 | return -ENODEV; | 202 | return -ENODEV; |
| 220 | } | 203 | if (pci_bus_read_config_word(slot->bus, |
| 221 | if(pci_bus_read_config_word(slot->bus, | ||
| 222 | slot->devfn, | 204 | slot->devfn, |
| 223 | hs_cap + 2, | 205 | hs_cap + 2, |
| 224 | &hs_csr)) { | 206 | &hs_csr)) |
| 225 | return -ENODEV; | 207 | return -ENODEV; |
| 226 | } | 208 | if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { |
| 227 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { | ||
| 228 | hs_csr |= HS_CSR_LOO; | 209 | hs_csr |= HS_CSR_LOO; |
| 229 | if(pci_bus_write_config_word(slot->bus, | 210 | if (pci_bus_write_config_word(slot->bus, |
| 230 | slot->devfn, | 211 | slot->devfn, |
| 231 | hs_cap + 2, | 212 | hs_cap + 2, |
| 232 | hs_csr)) { | 213 | hs_csr)) { |
| @@ -246,18 +227,16 @@ int cpci_led_off(struct slot* slot) | |||
| 246 | hs_cap = pci_bus_find_capability(slot->bus, | 227 | hs_cap = pci_bus_find_capability(slot->bus, |
| 247 | slot->devfn, | 228 | slot->devfn, |
| 248 | PCI_CAP_ID_CHSWP); | 229 | PCI_CAP_ID_CHSWP); |
| 249 | if(!hs_cap) { | 230 | if (!hs_cap) |
| 250 | return -ENODEV; | 231 | return -ENODEV; |
| 251 | } | 232 | if (pci_bus_read_config_word(slot->bus, |
| 252 | if(pci_bus_read_config_word(slot->bus, | ||
| 253 | slot->devfn, | 233 | slot->devfn, |
| 254 | hs_cap + 2, | 234 | hs_cap + 2, |
| 255 | &hs_csr)) { | 235 | &hs_csr)) |
| 256 | return -ENODEV; | 236 | return -ENODEV; |
| 257 | } | 237 | if (hs_csr & HS_CSR_LOO) { |
| 258 | if(hs_csr & HS_CSR_LOO) { | ||
| 259 | hs_csr &= ~HS_CSR_LOO; | 238 | hs_csr &= ~HS_CSR_LOO; |
| 260 | if(pci_bus_write_config_word(slot->bus, | 239 | if (pci_bus_write_config_word(slot->bus, |
| 261 | slot->devfn, | 240 | slot->devfn, |
| 262 | hs_cap + 2, | 241 | hs_cap + 2, |
| 263 | hs_csr)) { | 242 | hs_csr)) { |
| @@ -274,19 +253,6 @@ int cpci_led_off(struct slot* slot) | |||
| 274 | * Device configuration functions | 253 | * Device configuration functions |
| 275 | */ | 254 | */ |
| 276 | 255 | ||
| 277 | static void cpci_enable_device(struct pci_dev *dev) | ||
| 278 | { | ||
| 279 | struct pci_bus *bus; | ||
| 280 | |||
| 281 | pci_enable_device(dev); | ||
| 282 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
| 283 | bus = dev->subordinate; | ||
| 284 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
| 285 | cpci_enable_device(dev); | ||
| 286 | } | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 290 | int cpci_configure_slot(struct slot* slot) | 256 | int cpci_configure_slot(struct slot* slot) |
| 291 | { | 257 | { |
| 292 | unsigned char busnr; | 258 | unsigned char busnr; |
| @@ -294,14 +260,14 @@ int cpci_configure_slot(struct slot* slot) | |||
| 294 | 260 | ||
| 295 | dbg("%s - enter", __FUNCTION__); | 261 | dbg("%s - enter", __FUNCTION__); |
| 296 | 262 | ||
| 297 | if(slot->dev == NULL) { | 263 | if (slot->dev == NULL) { |
| 298 | dbg("pci_dev null, finding %02x:%02x:%x", | 264 | dbg("pci_dev null, finding %02x:%02x:%x", |
| 299 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); | 265 | slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); |
| 300 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 266 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
| 301 | } | 267 | } |
| 302 | 268 | ||
| 303 | /* Still NULL? Well then scan for it! */ | 269 | /* Still NULL? Well then scan for it! */ |
| 304 | if(slot->dev == NULL) { | 270 | if (slot->dev == NULL) { |
| 305 | int n; | 271 | int n; |
| 306 | dbg("pci_dev still null"); | 272 | dbg("pci_dev still null"); |
| 307 | 273 | ||
| @@ -311,10 +277,10 @@ int cpci_configure_slot(struct slot* slot) | |||
| 311 | */ | 277 | */ |
| 312 | n = pci_scan_slot(slot->bus, slot->devfn); | 278 | n = pci_scan_slot(slot->bus, slot->devfn); |
| 313 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); | 279 | dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); |
| 314 | if(n > 0) | 280 | if (n > 0) |
| 315 | pci_bus_add_devices(slot->bus); | 281 | pci_bus_add_devices(slot->bus); |
| 316 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 282 | slot->dev = pci_get_slot(slot->bus, slot->devfn); |
| 317 | if(slot->dev == NULL) { | 283 | if (slot->dev == NULL) { |
| 318 | err("Could not find PCI device for slot %02x", slot->number); | 284 | err("Could not find PCI device for slot %02x", slot->number); |
| 319 | return 1; | 285 | return 1; |
| 320 | } | 286 | } |
| @@ -329,8 +295,6 @@ int cpci_configure_slot(struct slot* slot) | |||
| 329 | 295 | ||
| 330 | pci_bus_assign_resources(slot->dev->bus); | 296 | pci_bus_assign_resources(slot->dev->bus); |
| 331 | 297 | ||
| 332 | cpci_enable_device(slot->dev); | ||
| 333 | |||
| 334 | dbg("%s - exit", __FUNCTION__); | 298 | dbg("%s - exit", __FUNCTION__); |
| 335 | return 0; | 299 | return 0; |
| 336 | } | 300 | } |
| @@ -341,15 +305,15 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
| 341 | struct pci_dev *dev; | 305 | struct pci_dev *dev; |
| 342 | 306 | ||
| 343 | dbg("%s - enter", __FUNCTION__); | 307 | dbg("%s - enter", __FUNCTION__); |
| 344 | if(!slot->dev) { | 308 | if (!slot->dev) { |
| 345 | err("No device for slot %02x\n", slot->number); | 309 | err("No device for slot %02x\n", slot->number); |
| 346 | return -ENODEV; | 310 | return -ENODEV; |
| 347 | } | 311 | } |
| 348 | 312 | ||
| 349 | for (i = 0; i < 8; i++) { | 313 | for (i = 0; i < 8; i++) { |
| 350 | dev = pci_find_slot(slot->bus->number, | 314 | dev = pci_get_slot(slot->bus, |
| 351 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 315 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
| 352 | if(dev) { | 316 | if (dev) { |
| 353 | pci_remove_bus_device(dev); | 317 | pci_remove_bus_device(dev); |
| 354 | slot->dev = NULL; | 318 | slot->dev = NULL; |
| 355 | } | 319 | } |
diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 243a51d88b86..7957cdc72cd0 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c | |||
| @@ -1626,7 +1626,7 @@ int shpchprm_set_hpp( | |||
| 1626 | pci_bus->number = func->bus; | 1626 | pci_bus->number = func->bus; |
| 1627 | devfn = PCI_DEVFN(func->device, func->function); | 1627 | devfn = PCI_DEVFN(func->device, func->function); |
| 1628 | 1628 | ||
| 1629 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); | 1629 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); |
| 1630 | 1630 | ||
| 1631 | if (ab) { | 1631 | if (ab) { |
| 1632 | if (ab->_hpp) { | 1632 | if (ab->_hpp) { |
| @@ -1681,7 +1681,7 @@ void shpchprm_enable_card( | |||
| 1681 | | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; | 1681 | | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; |
| 1682 | bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; | 1682 | bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; |
| 1683 | 1683 | ||
| 1684 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); | 1684 | ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); |
| 1685 | if (ab) { | 1685 | if (ab) { |
| 1686 | if (ab->_hpp) { | 1686 | if (ab->_hpp) { |
| 1687 | if (ab->_hpp->enable_perr) { | 1687 | if (ab->_hpp->enable_perr) { |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index da5bd33d982d..fc5263c6b102 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
| 33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
| 34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
| 35 | #include <linux/dma-mapping.h> | ||
| 35 | #include "scsi.h" | 36 | #include "scsi.h" |
| 36 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
| 37 | #include <linux/libata.h> | 38 | #include <linux/libata.h> |
| @@ -289,6 +290,8 @@ static void ahci_host_stop(struct ata_host_set *host_set) | |||
| 289 | { | 290 | { |
| 290 | struct ahci_host_priv *hpriv = host_set->private_data; | 291 | struct ahci_host_priv *hpriv = host_set->private_data; |
| 291 | kfree(hpriv); | 292 | kfree(hpriv); |
| 293 | |||
| 294 | ata_host_stop(host_set); | ||
| 292 | } | 295 | } |
| 293 | 296 | ||
| 294 | static int ahci_port_start(struct ata_port *ap) | 297 | static int ahci_port_start(struct ata_port *ap) |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 550c9921691a..7c02b7dc7098 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
| @@ -2488,7 +2488,7 @@ ahd_linux_dv_thread(void *data) | |||
| 2488 | sprintf(current->comm, "ahd_dv_%d", ahd->unit); | 2488 | sprintf(current->comm, "ahd_dv_%d", ahd->unit); |
| 2489 | #else | 2489 | #else |
| 2490 | daemonize("ahd_dv_%d", ahd->unit); | 2490 | daemonize("ahd_dv_%d", ahd->unit); |
| 2491 | current->flags |= PF_FREEZE; | 2491 | current->flags |= PF_NOFREEZE; |
| 2492 | #endif | 2492 | #endif |
| 2493 | unlock_kernel(); | 2493 | unlock_kernel(); |
| 2494 | 2494 | ||
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index c2b00c9d40a8..3be546439252 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
| @@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = { | |||
| 153 | 153 | ||
| 154 | .port_start = ata_port_start, | 154 | .port_start = ata_port_start, |
| 155 | .port_stop = ata_port_stop, | 155 | .port_stop = ata_port_stop, |
| 156 | .host_stop = ata_host_stop, | ||
| 156 | }; | 157 | }; |
| 157 | 158 | ||
| 158 | static struct ata_port_operations piix_sata_ops = { | 159 | static struct ata_port_operations piix_sata_ops = { |
| @@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = { | |||
| 180 | 181 | ||
| 181 | .port_start = ata_port_start, | 182 | .port_start = ata_port_start, |
| 182 | .port_stop = ata_port_stop, | 183 | .port_stop = ata_port_stop, |
| 184 | .host_stop = ata_host_stop, | ||
| 183 | }; | 185 | }; |
| 184 | 186 | ||
| 185 | static struct ata_port_info piix_port_info[] = { | 187 | static struct ata_port_info piix_port_info[] = { |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index a5d7c33a434d..21d194c6ace3 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
| @@ -3666,6 +3666,13 @@ void ata_port_stop (struct ata_port *ap) | |||
| 3666 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | 3666 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); |
| 3667 | } | 3667 | } |
| 3668 | 3668 | ||
| 3669 | void ata_host_stop (struct ata_host_set *host_set) | ||
| 3670 | { | ||
| 3671 | if (host_set->mmio_base) | ||
| 3672 | iounmap(host_set->mmio_base); | ||
| 3673 | } | ||
| 3674 | |||
| 3675 | |||
| 3669 | /** | 3676 | /** |
| 3670 | * ata_host_remove - Unregister SCSI host structure with upper layers | 3677 | * ata_host_remove - Unregister SCSI host structure with upper layers |
| 3671 | * @ap: Port to unregister | 3678 | * @ap: Port to unregister |
| @@ -4271,10 +4278,6 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
| 4271 | } | 4278 | } |
| 4272 | 4279 | ||
| 4273 | free_irq(host_set->irq, host_set); | 4280 | free_irq(host_set->irq, host_set); |
| 4274 | if (host_set->ops->host_stop) | ||
| 4275 | host_set->ops->host_stop(host_set); | ||
| 4276 | if (host_set->mmio_base) | ||
| 4277 | iounmap(host_set->mmio_base); | ||
| 4278 | 4281 | ||
| 4279 | for (i = 0; i < host_set->n_ports; i++) { | 4282 | for (i = 0; i < host_set->n_ports; i++) { |
| 4280 | ap = host_set->ports[i]; | 4283 | ap = host_set->ports[i]; |
| @@ -4293,6 +4296,9 @@ void ata_pci_remove_one (struct pci_dev *pdev) | |||
| 4293 | scsi_host_put(ap->host); | 4296 | scsi_host_put(ap->host); |
| 4294 | } | 4297 | } |
| 4295 | 4298 | ||
| 4299 | if (host_set->ops->host_stop) | ||
| 4300 | host_set->ops->host_stop(host_set); | ||
| 4301 | |||
| 4296 | kfree(host_set); | 4302 | kfree(host_set); |
| 4297 | 4303 | ||
| 4298 | pci_release_regions(pdev); | 4304 | pci_release_regions(pdev); |
| @@ -4381,6 +4387,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err); | |||
| 4381 | EXPORT_SYMBOL_GPL(ata_exec_command); | 4387 | EXPORT_SYMBOL_GPL(ata_exec_command); |
| 4382 | EXPORT_SYMBOL_GPL(ata_port_start); | 4388 | EXPORT_SYMBOL_GPL(ata_port_start); |
| 4383 | EXPORT_SYMBOL_GPL(ata_port_stop); | 4389 | EXPORT_SYMBOL_GPL(ata_port_stop); |
| 4390 | EXPORT_SYMBOL_GPL(ata_host_stop); | ||
| 4384 | EXPORT_SYMBOL_GPL(ata_interrupt); | 4391 | EXPORT_SYMBOL_GPL(ata_interrupt); |
| 4385 | EXPORT_SYMBOL_GPL(ata_qc_prep); | 4392 | EXPORT_SYMBOL_GPL(ata_qc_prep); |
| 4386 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); | 4393 | EXPORT_SYMBOL_GPL(ata_bmdma_setup); |
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 6518226b8f87..d90430bbb0de 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #define __LIBATA_H__ | 26 | #define __LIBATA_H__ |
| 27 | 27 | ||
| 28 | #define DRV_NAME "libata" | 28 | #define DRV_NAME "libata" |
| 29 | #define DRV_VERSION "1.10" /* must be exactly four chars */ | 29 | #define DRV_VERSION "1.11" /* must be exactly four chars */ |
| 30 | 30 | ||
| 31 | struct ata_scsi_args { | 31 | struct ata_scsi_args { |
| 32 | u16 *id; | 32 | u16 *id; |
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 69009f853a49..b0403ccd8a25 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
| @@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set) | |||
| 329 | host->host_desc->disable_hotplug(host_set); | 329 | host->host_desc->disable_hotplug(host_set); |
| 330 | 330 | ||
| 331 | kfree(host); | 331 | kfree(host); |
| 332 | |||
| 333 | ata_host_stop(host_set); | ||
| 332 | } | 334 | } |
| 333 | 335 | ||
| 334 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | 336 | static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index c4e9e0298122..b18c90582e67 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
| @@ -122,6 +122,7 @@ static struct ata_port_operations pdc_ata_ops = { | |||
| 122 | .scr_write = pdc_sata_scr_write, | 122 | .scr_write = pdc_sata_scr_write, |
| 123 | .port_start = pdc_port_start, | 123 | .port_start = pdc_port_start, |
| 124 | .port_stop = pdc_port_stop, | 124 | .port_stop = pdc_port_stop, |
| 125 | .host_stop = ata_host_stop, | ||
| 125 | }; | 126 | }; |
| 126 | 127 | ||
| 127 | static struct ata_port_info pdc_port_info[] = { | 128 | static struct ata_port_info pdc_port_info[] = { |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index dfd362104717..1383e8a28d72 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
| @@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set) | |||
| 536 | 536 | ||
| 537 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ | 537 | writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ |
| 538 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ | 538 | writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ |
| 539 | |||
| 540 | ata_host_stop(host_set); | ||
| 539 | } | 541 | } |
| 540 | 542 | ||
| 541 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) | 543 | static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 2b2ff48be396..238580d244e6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
| @@ -161,6 +161,7 @@ static struct ata_port_operations sil_ops = { | |||
| 161 | .scr_write = sil_scr_write, | 161 | .scr_write = sil_scr_write, |
| 162 | .port_start = ata_port_start, | 162 | .port_start = ata_port_start, |
| 163 | .port_stop = ata_port_stop, | 163 | .port_stop = ata_port_stop, |
| 164 | .host_stop = ata_host_stop, | ||
| 164 | }; | 165 | }; |
| 165 | 166 | ||
| 166 | static struct ata_port_info sil_port_info[] = { | 167 | static struct ata_port_info sil_port_info[] = { |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 5105ddd08447..e418b89c6b9d 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
| @@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = { | |||
| 114 | .scr_write = sis_scr_write, | 114 | .scr_write = sis_scr_write, |
| 115 | .port_start = ata_port_start, | 115 | .port_start = ata_port_start, |
| 116 | .port_stop = ata_port_stop, | 116 | .port_stop = ata_port_stop, |
| 117 | .host_stop = ata_host_stop, | ||
| 117 | }; | 118 | }; |
| 118 | 119 | ||
| 119 | static struct ata_port_info sis_port_info = { | 120 | static struct ata_port_info sis_port_info = { |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 05075bd3a893..edef1fa969fc 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
| @@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = { | |||
| 313 | .scr_write = k2_sata_scr_write, | 313 | .scr_write = k2_sata_scr_write, |
| 314 | .port_start = ata_port_start, | 314 | .port_start = ata_port_start, |
| 315 | .port_stop = ata_port_stop, | 315 | .port_stop = ata_port_stop, |
| 316 | .host_stop = ata_host_stop, | ||
| 316 | }; | 317 | }; |
| 317 | 318 | ||
| 318 | static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) | 319 | static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 70118650c461..140cea05de3f 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
| @@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set) | |||
| 245 | 245 | ||
| 246 | iounmap(dimm_mmio); | 246 | iounmap(dimm_mmio); |
| 247 | kfree(hpriv); | 247 | kfree(hpriv); |
| 248 | |||
| 249 | ata_host_stop(host_set); | ||
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | static int pdc_port_start(struct ata_port *ap) | 252 | static int pdc_port_start(struct ata_port *ap) |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 0bff4f475f26..a71fb54eebd3 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
| @@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = { | |||
| 113 | 113 | ||
| 114 | .port_start = ata_port_start, | 114 | .port_start = ata_port_start, |
| 115 | .port_stop = ata_port_stop, | 115 | .port_stop = ata_port_stop, |
| 116 | .host_stop = ata_host_stop, | ||
| 116 | }; | 117 | }; |
| 117 | 118 | ||
| 118 | static struct ata_port_info uli_port_info = { | 119 | static struct ata_port_info uli_port_info = { |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 3a7830667277..f43183c19a12 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
| @@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = { | |||
| 134 | 134 | ||
| 135 | .port_start = ata_port_start, | 135 | .port_start = ata_port_start, |
| 136 | .port_stop = ata_port_stop, | 136 | .port_stop = ata_port_stop, |
| 137 | .host_stop = ata_host_stop, | ||
| 137 | }; | 138 | }; |
| 138 | 139 | ||
| 139 | static struct ata_port_info svia_port_info = { | 140 | static struct ata_port_info svia_port_info = { |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2c28f0ad73c2..c5e09dc6f3de 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/blkdev.h> | 21 | #include <linux/blkdev.h> |
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/dma-mapping.h> | ||
| 24 | #include "scsi.h" | 25 | #include "scsi.h" |
| 25 | #include <scsi/scsi_host.h> | 26 | #include <scsi/scsi_host.h> |
| 26 | #include <linux/libata.h> | 27 | #include <linux/libata.h> |
| @@ -230,6 +231,7 @@ static struct ata_port_operations vsc_sata_ops = { | |||
| 230 | .scr_write = vsc_sata_scr_write, | 231 | .scr_write = vsc_sata_scr_write, |
| 231 | .port_start = ata_port_start, | 232 | .port_start = ata_port_start, |
| 232 | .port_stop = ata_port_stop, | 233 | .port_stop = ata_port_stop, |
| 234 | .host_stop = ata_host_stop, | ||
| 233 | }; | 235 | }; |
| 234 | 236 | ||
| 235 | static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) | 237 | static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3196c3265ff5..19e598c9641f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -124,3 +124,14 @@ config USB_SL811_HCD | |||
| 124 | To compile this driver as a module, choose M here: the | 124 | To compile this driver as a module, choose M here: the |
| 125 | module will be called sl811-hcd. | 125 | module will be called sl811-hcd. |
| 126 | 126 | ||
| 127 | config USB_SL811_CS | ||
| 128 | tristate "CF/PCMCIA support for SL811HS HCD" | ||
| 129 | depends on USB_SL811_HCD && PCMCIA | ||
| 130 | default N | ||
| 131 | help | ||
| 132 | Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC | ||
| 133 | REX-CFU1U CF card (often used with PDAs). If unsure, say N. | ||
| 134 | |||
| 135 | To compile this driver as a module, choose M here: the | ||
| 136 | module will be called "sl811_cs". | ||
| 137 | |||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a574ca06cf6b..5dbd3e7a27c7 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
| @@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | |||
| 7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
| 8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
| 9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
| 10 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | ||
| 10 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o | 11 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a374b7692073..99d43f758ad0 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | * SL811HS HCD (Host Controller Driver) for USB. | 2 | * SL811HS HCD (Host Controller Driver) for USB. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) | 4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) |
| 5 | * Copyright (C) 2004 David Brownell | 5 | * Copyright (C) 2004-2005 David Brownell |
| 6 | * | 6 | * |
| 7 | * Periodic scheduling is based on Roman's OHCI code | 7 | * Periodic scheduling is based on Roman's OHCI code |
| 8 | * Copyright (C) 1999 Roman Weissgaerber | 8 | * Copyright (C) 1999 Roman Weissgaerber |
| 9 | * | 9 | * |
| @@ -15,7 +15,7 @@ | |||
| 15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" | 15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" |
| 16 | * document (providing significant pieces missing from that spec); plus | 16 | * document (providing significant pieces missing from that spec); plus |
| 17 | * the SL811S spec if you want peripheral side info. | 17 | * the SL811S spec if you want peripheral side info. |
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | /* | 20 | /* |
| 21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, | 21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, |
| @@ -67,7 +67,7 @@ | |||
| 67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); | 67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); |
| 68 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
| 69 | 69 | ||
| 70 | #define DRIVER_VERSION "15 Dec 2004" | 70 | #define DRIVER_VERSION "19 May 2005" |
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | #ifndef DEBUG | 73 | #ifndef DEBUG |
| @@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) | |||
| 121 | /* reset as thoroughly as we can */ | 121 | /* reset as thoroughly as we can */ |
| 122 | if (sl811->board && sl811->board->reset) | 122 | if (sl811->board && sl811->board->reset) |
| 123 | sl811->board->reset(hcd->self.controller); | 123 | sl811->board->reset(hcd->self.controller); |
| 124 | else { | ||
| 125 | sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); | ||
| 126 | mdelay(20); | ||
| 127 | } | ||
| 124 | 128 | ||
| 125 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); | 129 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); |
| 126 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); | 130 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); |
| @@ -443,6 +447,7 @@ static void finish_request( | |||
| 443 | spin_lock(&urb->lock); | 447 | spin_lock(&urb->lock); |
| 444 | if (urb->status == -EINPROGRESS) | 448 | if (urb->status == -EINPROGRESS) |
| 445 | urb->status = status; | 449 | urb->status = status; |
| 450 | urb->hcpriv = NULL; | ||
| 446 | spin_unlock(&urb->lock); | 451 | spin_unlock(&urb->lock); |
| 447 | 452 | ||
| 448 | spin_unlock(&sl811->lock); | 453 | spin_unlock(&sl811->lock); |
| @@ -472,7 +477,7 @@ static void finish_request( | |||
| 472 | if (*prev) | 477 | if (*prev) |
| 473 | *prev = ep->next; | 478 | *prev = ep->next; |
| 474 | sl811->load[i] -= ep->load; | 479 | sl811->load[i] -= ep->load; |
| 475 | } | 480 | } |
| 476 | ep->branch = PERIODIC_SIZE; | 481 | ep->branch = PERIODIC_SIZE; |
| 477 | sl811->periodic_count--; | 482 | sl811->periodic_count--; |
| 478 | sl811_to_hcd(sl811)->self.bandwidth_allocated | 483 | sl811_to_hcd(sl811)->self.bandwidth_allocated |
| @@ -661,9 +666,9 @@ retry: | |||
| 661 | 666 | ||
| 662 | #ifdef QUIRK2 | 667 | #ifdef QUIRK2 |
| 663 | /* this may no longer be necessary ... */ | 668 | /* this may no longer be necessary ... */ |
| 664 | if (irqstat == 0 && ret == IRQ_NONE) { | 669 | if (irqstat == 0) { |
| 665 | irqstat = checkdone(sl811); | 670 | irqstat = checkdone(sl811); |
| 666 | if (irqstat /* && irq != ~0 */ ) | 671 | if (irqstat) |
| 667 | sl811->stat_lost++; | 672 | sl811->stat_lost++; |
| 668 | } | 673 | } |
| 669 | #endif | 674 | #endif |
| @@ -722,7 +727,8 @@ retry: | |||
| 722 | if (sl811->active_a) { | 727 | if (sl811->active_a) { |
| 723 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); | 728 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); |
| 724 | finish_request(sl811, sl811->active_a, | 729 | finish_request(sl811, sl811->active_a, |
| 725 | container_of(sl811->active_a->hep->urb_list.next, | 730 | container_of(sl811->active_a |
| 731 | ->hep->urb_list.next, | ||
| 726 | struct urb, urb_list), | 732 | struct urb, urb_list), |
| 727 | NULL, -ESHUTDOWN); | 733 | NULL, -ESHUTDOWN); |
| 728 | sl811->active_a = NULL; | 734 | sl811->active_a = NULL; |
| @@ -731,7 +737,8 @@ retry: | |||
| 731 | if (sl811->active_b) { | 737 | if (sl811->active_b) { |
| 732 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); | 738 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); |
| 733 | finish_request(sl811, sl811->active_b, | 739 | finish_request(sl811, sl811->active_b, |
| 734 | container_of(sl811->active_b->hep->urb_list.next, | 740 | container_of(sl811->active_b |
| 741 | ->hep->urb_list.next, | ||
| 735 | struct urb, urb_list), | 742 | struct urb, urb_list), |
| 736 | NULL, -ESHUTDOWN); | 743 | NULL, -ESHUTDOWN); |
| 737 | sl811->active_b = NULL; | 744 | sl811->active_b = NULL; |
| @@ -761,7 +768,7 @@ retry: | |||
| 761 | goto retry; | 768 | goto retry; |
| 762 | } | 769 | } |
| 763 | 770 | ||
| 764 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) | 771 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) |
| 765 | sofirq_off(sl811); | 772 | sofirq_off(sl811); |
| 766 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); | 773 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); |
| 767 | 774 | ||
| @@ -796,7 +803,7 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) | |||
| 796 | } | 803 | } |
| 797 | if (j < PERIODIC_SIZE) | 804 | if (j < PERIODIC_SIZE) |
| 798 | continue; | 805 | continue; |
| 799 | branch = i; | 806 | branch = i; |
| 800 | } | 807 | } |
| 801 | } | 808 | } |
| 802 | return branch; | 809 | return branch; |
| @@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( | |||
| 890 | break; | 897 | break; |
| 891 | } | 898 | } |
| 892 | 899 | ||
| 900 | ep->hep = hep; | ||
| 893 | hep->hcpriv = ep; | 901 | hep->hcpriv = ep; |
| 894 | } | 902 | } |
| 895 | 903 | ||
| @@ -961,15 +969,16 @@ fail: | |||
| 961 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 969 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) |
| 962 | { | 970 | { |
| 963 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 971 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
| 964 | struct usb_host_endpoint *hep = urb->hcpriv; | 972 | struct usb_host_endpoint *hep; |
| 965 | unsigned long flags; | 973 | unsigned long flags; |
| 966 | struct sl811h_ep *ep; | 974 | struct sl811h_ep *ep; |
| 967 | int retval = 0; | 975 | int retval = 0; |
| 968 | 976 | ||
| 977 | spin_lock_irqsave(&sl811->lock, flags); | ||
| 978 | hep = urb->hcpriv; | ||
| 969 | if (!hep) | 979 | if (!hep) |
| 970 | return -EINVAL; | 980 | goto fail; |
| 971 | 981 | ||
| 972 | spin_lock_irqsave(&sl811->lock, flags); | ||
| 973 | ep = hep->hcpriv; | 982 | ep = hep->hcpriv; |
| 974 | if (ep) { | 983 | if (ep) { |
| 975 | /* finish right away if this urb can't be active ... | 984 | /* finish right away if this urb can't be active ... |
| @@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
| 1017 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, | 1026 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, |
| 1018 | (sl811->active_a == ep) ? "A" : "B"); | 1027 | (sl811->active_a == ep) ? "A" : "B"); |
| 1019 | } else | 1028 | } else |
| 1029 | fail: | ||
| 1020 | retval = -EINVAL; | 1030 | retval = -EINVAL; |
| 1021 | spin_unlock_irqrestore(&sl811->lock, flags); | 1031 | spin_unlock_irqrestore(&sl811->lock, flags); |
| 1022 | return retval; | 1032 | return retval; |
| @@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
| 1576 | if (sl811->board && sl811->board->power) | 1586 | if (sl811->board && sl811->board->power) |
| 1577 | hub_set_power_budget(udev, sl811->board->power * 2); | 1587 | hub_set_power_budget(udev, sl811->board->power * 2); |
| 1578 | 1588 | ||
| 1589 | /* enable power and interupts */ | ||
| 1590 | port_power(sl811, 1); | ||
| 1591 | |||
| 1579 | return 0; | 1592 | return 0; |
| 1580 | } | 1593 | } |
| 1581 | 1594 | ||
| @@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { | |||
| 1618 | 1631 | ||
| 1619 | /*-------------------------------------------------------------------------*/ | 1632 | /*-------------------------------------------------------------------------*/ |
| 1620 | 1633 | ||
| 1621 | static int __init_or_module | 1634 | static int __devexit |
| 1622 | sl811h_remove(struct device *dev) | 1635 | sl811h_remove(struct device *dev) |
| 1623 | { | 1636 | { |
| 1624 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1637 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
| @@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) | |||
| 1631 | remove_debug_file(sl811); | 1644 | remove_debug_file(sl811); |
| 1632 | usb_remove_hcd(hcd); | 1645 | usb_remove_hcd(hcd); |
| 1633 | 1646 | ||
| 1634 | iounmap(sl811->data_reg); | 1647 | /* some platforms may use IORESOURCE_IO */ |
| 1635 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1648 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 1636 | release_mem_region(res->start, 1); | 1649 | if (res) |
| 1650 | iounmap(sl811->data_reg); | ||
| 1637 | 1651 | ||
| 1638 | iounmap(sl811->addr_reg); | ||
| 1639 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1640 | release_mem_region(res->start, 1); | 1653 | if (res) |
| 1654 | iounmap(sl811->addr_reg); | ||
| 1641 | 1655 | ||
| 1642 | usb_put_hcd(hcd); | 1656 | usb_put_hcd(hcd); |
| 1643 | return 0; | 1657 | return 0; |
| 1644 | } | 1658 | } |
| 1645 | 1659 | ||
| 1646 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1660 | static int __devinit |
| 1647 | |||
| 1648 | static int __init | ||
| 1649 | sl811h_probe(struct device *dev) | 1661 | sl811h_probe(struct device *dev) |
| 1650 | { | 1662 | { |
| 1651 | struct usb_hcd *hcd; | 1663 | struct usb_hcd *hcd; |
| @@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) | |||
| 1656 | void __iomem *addr_reg; | 1668 | void __iomem *addr_reg; |
| 1657 | void __iomem *data_reg; | 1669 | void __iomem *data_reg; |
| 1658 | int retval; | 1670 | int retval; |
| 1659 | u8 tmp; | 1671 | u8 tmp, ioaddr = 0; |
| 1660 | 1672 | ||
| 1661 | /* basic sanity checks first. board-specific init logic should | 1673 | /* basic sanity checks first. board-specific init logic should |
| 1662 | * have initialized these three resources and probably board | 1674 | * have initialized these three resources and probably board |
| @@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) | |||
| 1664 | * minimal sanity checking. | 1676 | * minimal sanity checking. |
| 1665 | */ | 1677 | */ |
| 1666 | pdev = container_of(dev, struct platform_device, dev); | 1678 | pdev = container_of(dev, struct platform_device, dev); |
| 1667 | if (pdev->num_resources < 3) | ||
| 1668 | return -ENODEV; | ||
| 1669 | |||
| 1670 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 1671 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 1672 | irq = platform_get_irq(pdev, 0); | 1679 | irq = platform_get_irq(pdev, 0); |
| 1673 | if (!addr || !data || irq < 0) | 1680 | if (pdev->num_resources < 3 || irq < 0) |
| 1674 | return -ENODEV; | 1681 | return -ENODEV; |
| 1675 | 1682 | ||
| 1676 | /* refuse to confuse usbcore */ | 1683 | /* refuse to confuse usbcore */ |
| @@ -1679,24 +1686,31 @@ sl811h_probe(struct device *dev) | |||
| 1679 | return -EINVAL; | 1686 | return -EINVAL; |
| 1680 | } | 1687 | } |
| 1681 | 1688 | ||
| 1682 | if (!request_mem_region(addr->start, 1, hcd_name)) { | 1689 | /* the chip may be wired for either kind of addressing */ |
| 1683 | retval = -EBUSY; | 1690 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1684 | goto err1; | 1691 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 1685 | } | 1692 | retval = -EBUSY; |
| 1686 | addr_reg = ioremap(addr->start, resource_len(addr)); | 1693 | if (!addr || !data) { |
| 1687 | if (addr_reg == NULL) { | 1694 | addr = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 1688 | retval = -ENOMEM; | 1695 | data = platform_get_resource(pdev, IORESOURCE_IO, 1); |
| 1689 | goto err2; | 1696 | if (!addr || !data) |
| 1690 | } | 1697 | return -ENODEV; |
| 1698 | ioaddr = 1; | ||
| 1699 | |||
| 1700 | addr_reg = (void __iomem *) addr->start; | ||
| 1701 | data_reg = (void __iomem *) data->start; | ||
| 1702 | } else { | ||
| 1703 | addr_reg = ioremap(addr->start, 1); | ||
| 1704 | if (addr_reg == NULL) { | ||
| 1705 | retval = -ENOMEM; | ||
| 1706 | goto err2; | ||
| 1707 | } | ||
| 1691 | 1708 | ||
| 1692 | if (!request_mem_region(data->start, 1, hcd_name)) { | 1709 | data_reg = ioremap(data->start, 1); |
| 1693 | retval = -EBUSY; | 1710 | if (data_reg == NULL) { |
| 1694 | goto err3; | 1711 | retval = -ENOMEM; |
| 1695 | } | 1712 | goto err4; |
| 1696 | data_reg = ioremap(data->start, resource_len(addr)); | 1713 | } |
| 1697 | if (data_reg == NULL) { | ||
| 1698 | retval = -ENOMEM; | ||
| 1699 | goto err4; | ||
| 1700 | } | 1714 | } |
| 1701 | 1715 | ||
| 1702 | /* allocate and initialize hcd */ | 1716 | /* allocate and initialize hcd */ |
| @@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) | |||
| 1737 | goto err6; | 1751 | goto err6; |
| 1738 | } | 1752 | } |
| 1739 | 1753 | ||
| 1740 | /* sl811s would need a different handler for this irq */ | 1754 | /* The chip's IRQ is level triggered, active high. A requirement |
| 1741 | #ifdef CONFIG_ARM | 1755 | * for platform device setup is to cope with things like signal |
| 1742 | /* Cypress docs say the IRQ is IRQT_HIGH ... */ | 1756 | * inverters (e.g. CF is active low) or working only with edge |
| 1743 | set_irq_type(irq, IRQT_RISING); | 1757 | * triggers (e.g. most ARM CPUs). Initial driver stress testing |
| 1744 | #endif | 1758 | * was on a system with single edge triggering, so most sorts of |
| 1745 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1759 | * triggering arrangement should work. |
| 1760 | */ | ||
| 1761 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); | ||
| 1746 | if (retval != 0) | 1762 | if (retval != 0) |
| 1747 | goto err6; | 1763 | goto err6; |
| 1748 | 1764 | ||
| @@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) | |||
| 1752 | err6: | 1768 | err6: |
| 1753 | usb_put_hcd(hcd); | 1769 | usb_put_hcd(hcd); |
| 1754 | err5: | 1770 | err5: |
| 1755 | iounmap(data_reg); | 1771 | if (!ioaddr) |
| 1772 | iounmap(data_reg); | ||
| 1756 | err4: | 1773 | err4: |
| 1757 | release_mem_region(data->start, 1); | 1774 | if (!ioaddr) |
| 1758 | err3: | 1775 | iounmap(addr_reg); |
| 1759 | iounmap(addr_reg); | ||
| 1760 | err2: | 1776 | err2: |
| 1761 | release_mem_region(addr->start, 1); | ||
| 1762 | err1: | ||
| 1763 | DBG("init error, %d\n", retval); | 1777 | DBG("init error, %d\n", retval); |
| 1764 | return retval; | 1778 | return retval; |
| 1765 | } | 1779 | } |
| @@ -1767,7 +1781,7 @@ sl811h_probe(struct device *dev) | |||
| 1767 | #ifdef CONFIG_PM | 1781 | #ifdef CONFIG_PM |
| 1768 | 1782 | ||
| 1769 | /* for this device there's no useful distinction between the controller | 1783 | /* for this device there's no useful distinction between the controller |
| 1770 | * and its root hub, except that the root hub only gets direct PM calls | 1784 | * and its root hub, except that the root hub only gets direct PM calls |
| 1771 | * when CONFIG_USB_SUSPEND is enabled. | 1785 | * when CONFIG_USB_SUSPEND is enabled. |
| 1772 | */ | 1786 | */ |
| 1773 | 1787 | ||
| @@ -1821,20 +1835,22 @@ sl811h_resume(struct device *dev, u32 phase) | |||
| 1821 | #endif | 1835 | #endif |
| 1822 | 1836 | ||
| 1823 | 1837 | ||
| 1824 | static struct device_driver sl811h_driver = { | 1838 | /* this driver is exported so sl811_cs can depend on it */ |
| 1839 | struct device_driver sl811h_driver = { | ||
| 1825 | .name = (char *) hcd_name, | 1840 | .name = (char *) hcd_name, |
| 1826 | .bus = &platform_bus_type, | 1841 | .bus = &platform_bus_type, |
| 1827 | 1842 | ||
| 1828 | .probe = sl811h_probe, | 1843 | .probe = sl811h_probe, |
| 1829 | .remove = sl811h_remove, | 1844 | .remove = __devexit_p(sl811h_remove), |
| 1830 | 1845 | ||
| 1831 | .suspend = sl811h_suspend, | 1846 | .suspend = sl811h_suspend, |
| 1832 | .resume = sl811h_resume, | 1847 | .resume = sl811h_resume, |
| 1833 | }; | 1848 | }; |
| 1849 | EXPORT_SYMBOL(sl811h_driver); | ||
| 1834 | 1850 | ||
| 1835 | /*-------------------------------------------------------------------------*/ | 1851 | /*-------------------------------------------------------------------------*/ |
| 1836 | 1852 | ||
| 1837 | static int __init sl811h_init(void) | 1853 | static int __init sl811h_init(void) |
| 1838 | { | 1854 | { |
| 1839 | if (usb_disabled()) | 1855 | if (usb_disabled()) |
| 1840 | return -ENODEV; | 1856 | return -ENODEV; |
| @@ -1844,8 +1860,8 @@ static int __init sl811h_init(void) | |||
| 1844 | } | 1860 | } |
| 1845 | module_init(sl811h_init); | 1861 | module_init(sl811h_init); |
| 1846 | 1862 | ||
| 1847 | static void __exit sl811h_cleanup(void) | 1863 | static void __exit sl811h_cleanup(void) |
| 1848 | { | 1864 | { |
| 1849 | driver_unregister(&sl811h_driver); | 1865 | driver_unregister(&sl811h_driver); |
| 1850 | } | 1866 | } |
| 1851 | module_exit(sl811h_cleanup); | 1867 | module_exit(sl811h_cleanup); |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c new file mode 100644 index 000000000000..6e173265095c --- /dev/null +++ b/drivers/usb/host/sl811_cs.c | |||
| @@ -0,0 +1,442 @@ | |||
| 1 | /* | ||
| 2 | * PCMCIA driver for SL811HS (as found in REX-CFU1U) | ||
| 3 | * Filename: sl811_cs.c | ||
| 4 | * Author: Yukio Yamamoto | ||
| 5 | * | ||
| 6 | * Port to sl811-hcd and 2.6.x by | ||
| 7 | * Botond Botyanszki <boti@rocketmail.com> | ||
| 8 | * Simon Pickering | ||
| 9 | * | ||
| 10 | * Last update: 2005-05-12 | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/ptrace.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/string.h> | ||
| 20 | #include <linux/timer.h> | ||
| 21 | #include <linux/ioport.h> | ||
| 22 | |||
| 23 | #include <pcmcia/version.h> | ||
| 24 | #include <pcmcia/cs_types.h> | ||
| 25 | #include <pcmcia/cs.h> | ||
| 26 | #include <pcmcia/cistpl.h> | ||
| 27 | #include <pcmcia/cisreg.h> | ||
| 28 | #include <pcmcia/ds.h> | ||
| 29 | |||
| 30 | #include <linux/usb_sl811.h> | ||
| 31 | |||
| 32 | MODULE_AUTHOR("Botond Botyanszki"); | ||
| 33 | MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); | ||
| 34 | MODULE_LICENSE("GPL"); | ||
| 35 | |||
| 36 | |||
| 37 | /*====================================================================*/ | ||
| 38 | /* MACROS */ | ||
| 39 | /*====================================================================*/ | ||
| 40 | |||
| 41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | ||
| 42 | |||
| 43 | static int pc_debug = 0; | ||
| 44 | module_param(pc_debug, int, 0644); | ||
| 45 | |||
| 46 | #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) | ||
| 47 | |||
| 48 | #else | ||
| 49 | #define DBG(n, args...) do{}while(0) | ||
| 50 | #endif /* no debugging */ | ||
| 51 | |||
| 52 | #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) | ||
| 53 | |||
| 54 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) | ||
| 55 | |||
| 56 | #define CS_CHECK(fn, ret) \ | ||
| 57 | do { \ | ||
| 58 | last_fn = (fn); \ | ||
| 59 | if ((last_ret = (ret)) != 0) \ | ||
| 60 | goto cs_failed; \ | ||
| 61 | } while (0) | ||
| 62 | |||
| 63 | /*====================================================================*/ | ||
| 64 | /* VARIABLES */ | ||
| 65 | /*====================================================================*/ | ||
| 66 | |||
| 67 | static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; | ||
| 68 | |||
| 69 | static dev_link_t *dev_list = NULL; | ||
| 70 | |||
| 71 | static int irq_list[4] = { -1 }; | ||
| 72 | static int irq_list_count; | ||
| 73 | |||
| 74 | module_param_array(irq_list, int, &irq_list_count, 0444); | ||
| 75 | |||
| 76 | INT_MODULE_PARM(irq_mask, 0xdeb8); | ||
| 77 | |||
| 78 | typedef struct local_info_t { | ||
| 79 | dev_link_t link; | ||
| 80 | dev_node_t node; | ||
| 81 | } local_info_t; | ||
| 82 | |||
| 83 | /*====================================================================*/ | ||
| 84 | |||
| 85 | static void release_platform_dev(struct device * dev) | ||
| 86 | { | ||
| 87 | DBG(0, "sl811_cs platform_dev release\n"); | ||
| 88 | dev->parent = NULL; | ||
| 89 | } | ||
| 90 | |||
| 91 | static struct sl811_platform_data platform_data = { | ||
| 92 | .potpg = 100, | ||
| 93 | .power = 50, /* == 100mA */ | ||
| 94 | // .reset = ... FIXME: invoke CF reset on the card | ||
| 95 | }; | ||
| 96 | |||
| 97 | static struct resource resources[] = { | ||
| 98 | [0] = { | ||
| 99 | .flags = IORESOURCE_IRQ, | ||
| 100 | }, | ||
| 101 | [1] = { | ||
| 102 | // .name = "address", | ||
| 103 | .flags = IORESOURCE_IO, | ||
| 104 | }, | ||
| 105 | [2] = { | ||
| 106 | // .name = "data", | ||
| 107 | .flags = IORESOURCE_IO, | ||
| 108 | }, | ||
| 109 | }; | ||
| 110 | |||
| 111 | extern struct device_driver sl811h_driver; | ||
| 112 | |||
| 113 | static struct platform_device platform_dev = { | ||
| 114 | .id = -1, | ||
| 115 | .dev = { | ||
| 116 | .platform_data = &platform_data, | ||
| 117 | .release = release_platform_dev, | ||
| 118 | }, | ||
| 119 | .resource = resources, | ||
| 120 | .num_resources = ARRAY_SIZE(resources), | ||
| 121 | }; | ||
| 122 | |||
| 123 | static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | ||
| 124 | { | ||
| 125 | if (platform_dev.dev.parent) | ||
| 126 | return -EBUSY; | ||
| 127 | platform_dev.dev.parent = parent; | ||
| 128 | |||
| 129 | /* finish seting up the platform device */ | ||
| 130 | resources[0].start = irq; | ||
| 131 | |||
| 132 | resources[1].start = base_addr; | ||
| 133 | resources[1].end = base_addr; | ||
| 134 | |||
| 135 | resources[2].start = base_addr + 1; | ||
| 136 | resources[2].end = base_addr + 1; | ||
| 137 | |||
| 138 | /* The driver core will probe for us. We know sl811-hcd has been | ||
| 139 | * initialized already because of the link order dependency. | ||
| 140 | */ | ||
| 141 | platform_dev.name = sl811h_driver.name; | ||
| 142 | return platform_device_register(&platform_dev); | ||
| 143 | } | ||
| 144 | |||
| 145 | /*====================================================================*/ | ||
| 146 | |||
| 147 | static void sl811_cs_detach(dev_link_t *link) | ||
| 148 | { | ||
| 149 | dev_link_t **linkp; | ||
| 150 | |||
| 151 | DBG(0, "sl811_cs_detach(0x%p)\n", link); | ||
| 152 | |||
| 153 | /* Locate device structure */ | ||
| 154 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { | ||
| 155 | if (*linkp == link) | ||
| 156 | break; | ||
| 157 | } | ||
| 158 | if (*linkp == NULL) | ||
| 159 | return; | ||
| 160 | |||
| 161 | /* Break the link with Card Services */ | ||
| 162 | if (link->handle) | ||
| 163 | pcmcia_deregister_client(link->handle); | ||
| 164 | |||
| 165 | /* Unlink device structure, and free it */ | ||
| 166 | *linkp = link->next; | ||
| 167 | /* This points to the parent local_info_t struct */ | ||
| 168 | kfree(link->priv); | ||
| 169 | } | ||
| 170 | |||
| 171 | static void sl811_cs_release(dev_link_t * link) | ||
| 172 | { | ||
| 173 | |||
| 174 | DBG(0, "sl811_cs_release(0x%p)\n", link); | ||
| 175 | |||
| 176 | if (link->open) { | ||
| 177 | DBG(1, "sl811_cs: release postponed, '%s' still open\n", | ||
| 178 | link->dev->dev_name); | ||
| 179 | link->state |= DEV_STALE_CONFIG; | ||
| 180 | return; | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Unlink the device chain */ | ||
| 184 | link->dev = NULL; | ||
| 185 | |||
| 186 | platform_device_unregister(&platform_dev); | ||
| 187 | pcmcia_release_configuration(link->handle); | ||
| 188 | if (link->io.NumPorts1) | ||
| 189 | pcmcia_release_io(link->handle, &link->io); | ||
| 190 | if (link->irq.AssignedIRQ) | ||
| 191 | pcmcia_release_irq(link->handle, &link->irq); | ||
| 192 | link->state &= ~DEV_CONFIG; | ||
| 193 | |||
| 194 | if (link->state & DEV_STALE_LINK) | ||
| 195 | sl811_cs_detach(link); | ||
| 196 | } | ||
| 197 | |||
| 198 | static void sl811_cs_config(dev_link_t *link) | ||
| 199 | { | ||
| 200 | client_handle_t handle = link->handle; | ||
| 201 | struct device *parent = &handle_to_dev(handle); | ||
| 202 | local_info_t *dev = link->priv; | ||
| 203 | tuple_t tuple; | ||
| 204 | cisparse_t parse; | ||
| 205 | int last_fn, last_ret; | ||
| 206 | u_char buf[64]; | ||
| 207 | config_info_t conf; | ||
| 208 | cistpl_cftable_entry_t dflt = { 0 }; | ||
| 209 | |||
| 210 | DBG(0, "sl811_cs_config(0x%p)\n", link); | ||
| 211 | |||
| 212 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
| 213 | tuple.Attributes = 0; | ||
| 214 | tuple.TupleData = buf; | ||
| 215 | tuple.TupleDataMax = sizeof(buf); | ||
| 216 | tuple.TupleOffset = 0; | ||
| 217 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
| 218 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
| 219 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | ||
| 220 | link->conf.ConfigBase = parse.config.base; | ||
| 221 | link->conf.Present = parse.config.rmask[0]; | ||
| 222 | |||
| 223 | /* Configure card */ | ||
| 224 | link->state |= DEV_CONFIG; | ||
| 225 | |||
| 226 | /* Look up the current Vcc */ | ||
| 227 | CS_CHECK(GetConfigurationInfo, | ||
| 228 | pcmcia_get_configuration_info(handle, &conf)); | ||
| 229 | link->conf.Vcc = conf.Vcc; | ||
| 230 | |||
| 231 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
| 232 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
| 233 | while (1) { | ||
| 234 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
| 235 | |||
| 236 | if (pcmcia_get_tuple_data(handle, &tuple) != 0 | ||
| 237 | || pcmcia_parse_tuple(handle, &tuple, &parse) | ||
| 238 | != 0) | ||
| 239 | goto next_entry; | ||
| 240 | |||
| 241 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { | ||
| 242 | dflt = *cfg; | ||
| 243 | } | ||
| 244 | |||
| 245 | if (cfg->index == 0) | ||
| 246 | goto next_entry; | ||
| 247 | |||
| 248 | link->conf.ConfigIndex = cfg->index; | ||
| 249 | |||
| 250 | /* Use power settings for Vcc and Vpp if present */ | ||
| 251 | /* Note that the CIS values need to be rescaled */ | ||
| 252 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
| 253 | if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 | ||
| 254 | != conf.Vcc) | ||
| 255 | goto next_entry; | ||
| 256 | } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
| 257 | if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 | ||
| 258 | != conf.Vcc) | ||
| 259 | goto next_entry; | ||
| 260 | } | ||
| 261 | |||
| 262 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
| 263 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
| 264 | cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
| 265 | else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
| 266 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
| 267 | dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
| 268 | |||
| 269 | /* we need an interrupt */ | ||
| 270 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) | ||
| 271 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
| 272 | |||
| 273 | /* IO window settings */ | ||
| 274 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | ||
| 275 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
| 276 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
| 277 | |||
| 278 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
| 279 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
| 280 | link->io.BasePort1 = io->win[0].base; | ||
| 281 | link->io.NumPorts1 = io->win[0].len; | ||
| 282 | |||
| 283 | if (pcmcia_request_io(link->handle, &link->io) != 0) | ||
| 284 | goto next_entry; | ||
| 285 | } | ||
| 286 | break; | ||
| 287 | |||
| 288 | next_entry: | ||
| 289 | if (link->io.NumPorts1) | ||
| 290 | pcmcia_release_io(link->handle, &link->io); | ||
| 291 | last_ret = pcmcia_get_next_tuple(handle, &tuple); | ||
| 292 | } | ||
| 293 | |||
| 294 | /* require an IRQ and two registers */ | ||
| 295 | if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) | ||
| 296 | goto cs_failed; | ||
| 297 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
| 298 | CS_CHECK(RequestIRQ, | ||
| 299 | pcmcia_request_irq(link->handle, &link->irq)); | ||
| 300 | else | ||
| 301 | goto cs_failed; | ||
| 302 | |||
| 303 | CS_CHECK(RequestConfiguration, | ||
| 304 | pcmcia_request_configuration(link->handle, &link->conf)); | ||
| 305 | |||
| 306 | sprintf(dev->node.dev_name, driver_name); | ||
| 307 | dev->node.major = dev->node.minor = 0; | ||
| 308 | link->dev = &dev->node; | ||
| 309 | |||
| 310 | printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", | ||
| 311 | dev->node.dev_name, link->conf.ConfigIndex, | ||
| 312 | link->conf.Vcc/10, link->conf.Vcc%10); | ||
| 313 | if (link->conf.Vpp1) | ||
| 314 | printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); | ||
| 315 | printk(", irq %d", link->irq.AssignedIRQ); | ||
| 316 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | ||
| 317 | link->io.BasePort1+link->io.NumPorts1-1); | ||
| 318 | printk("\n"); | ||
| 319 | |||
| 320 | link->state &= ~DEV_CONFIG_PENDING; | ||
| 321 | |||
| 322 | if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) | ||
| 323 | < 0) { | ||
| 324 | cs_failed: | ||
| 325 | printk("sl811_cs_config failed\n"); | ||
| 326 | cs_error(link->handle, last_fn, last_ret); | ||
| 327 | sl811_cs_release(link); | ||
| 328 | link->state &= ~DEV_CONFIG_PENDING; | ||
| 329 | } | ||
| 330 | } | ||
| 331 | |||
| 332 | static int | ||
| 333 | sl811_cs_event(event_t event, int priority, event_callback_args_t *args) | ||
| 334 | { | ||
| 335 | dev_link_t *link = args->client_data; | ||
| 336 | |||
| 337 | DBG(1, "sl811_cs_event(0x%06x)\n", event); | ||
| 338 | |||
| 339 | switch (event) { | ||
| 340 | case CS_EVENT_CARD_REMOVAL: | ||
| 341 | link->state &= ~DEV_PRESENT; | ||
| 342 | if (link->state & DEV_CONFIG) | ||
| 343 | sl811_cs_release(link); | ||
| 344 | break; | ||
| 345 | |||
| 346 | case CS_EVENT_CARD_INSERTION: | ||
| 347 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
| 348 | sl811_cs_config(link); | ||
| 349 | break; | ||
| 350 | |||
| 351 | case CS_EVENT_PM_SUSPEND: | ||
| 352 | link->state |= DEV_SUSPEND; | ||
| 353 | /* Fall through... */ | ||
| 354 | case CS_EVENT_RESET_PHYSICAL: | ||
| 355 | if (link->state & DEV_CONFIG) | ||
| 356 | pcmcia_release_configuration(link->handle); | ||
| 357 | break; | ||
| 358 | |||
| 359 | case CS_EVENT_PM_RESUME: | ||
| 360 | link->state &= ~DEV_SUSPEND; | ||
| 361 | /* Fall through... */ | ||
| 362 | case CS_EVENT_CARD_RESET: | ||
| 363 | if (link->state & DEV_CONFIG) | ||
| 364 | pcmcia_request_configuration(link->handle, &link->conf); | ||
| 365 | DBG(0, "reset sl811-hcd here?\n"); | ||
| 366 | break; | ||
| 367 | } | ||
| 368 | return 0; | ||
| 369 | } | ||
| 370 | |||
| 371 | static dev_link_t *sl811_cs_attach(void) | ||
| 372 | { | ||
| 373 | local_info_t *local; | ||
| 374 | dev_link_t *link; | ||
| 375 | client_reg_t client_reg; | ||
| 376 | int ret, i; | ||
| 377 | |||
| 378 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); | ||
| 379 | if (!local) | ||
| 380 | return NULL; | ||
| 381 | memset(local, 0, sizeof(local_info_t)); | ||
| 382 | link = &local->link; | ||
| 383 | link->priv = local; | ||
| 384 | |||
| 385 | /* Initialize */ | ||
| 386 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
| 387 | link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; | ||
| 388 | if (irq_list[0] == -1) | ||
| 389 | link->irq.IRQInfo2 = irq_mask; | ||
| 390 | else | ||
| 391 | for (i = 0; i < irq_list_count; i++) | ||
| 392 | link->irq.IRQInfo2 |= 1 << irq_list[i]; | ||
| 393 | link->irq.Handler = NULL; | ||
| 394 | |||
| 395 | link->conf.Attributes = 0; | ||
| 396 | link->conf.Vcc = 33; | ||
| 397 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
| 398 | |||
| 399 | /* Register with Card Services */ | ||
| 400 | link->next = dev_list; | ||
| 401 | dev_list = link; | ||
| 402 | client_reg.dev_info = (dev_info_t *) &driver_name; | ||
| 403 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | ||
| 404 | client_reg.EventMask = | ||
| 405 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
| 406 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
| 407 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
| 408 | client_reg.event_handler = &sl811_cs_event; | ||
| 409 | client_reg.Version = 0x0210; | ||
| 410 | client_reg.event_callback_args.client_data = link; | ||
| 411 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
| 412 | if (ret != CS_SUCCESS) { | ||
| 413 | cs_error(link->handle, RegisterClient, ret); | ||
| 414 | sl811_cs_detach(link); | ||
| 415 | return NULL; | ||
| 416 | } | ||
| 417 | |||
| 418 | return link; | ||
| 419 | } | ||
| 420 | |||
| 421 | static struct pcmcia_driver sl811_cs_driver = { | ||
| 422 | .owner = THIS_MODULE, | ||
| 423 | .drv = { | ||
| 424 | .name = (char *)driver_name, | ||
| 425 | }, | ||
| 426 | .attach = sl811_cs_attach, | ||
| 427 | .detach = sl811_cs_detach, | ||
| 428 | }; | ||
| 429 | |||
| 430 | /*====================================================================*/ | ||
| 431 | |||
| 432 | static int __init init_sl811_cs(void) | ||
| 433 | { | ||
| 434 | return pcmcia_register_driver(&sl811_cs_driver); | ||
| 435 | } | ||
| 436 | module_init(init_sl811_cs); | ||
| 437 | |||
| 438 | static void __exit exit_sl811_cs(void) | ||
| 439 | { | ||
| 440 | pcmcia_unregister_driver(&sl811_cs_driver); | ||
| 441 | } | ||
| 442 | module_exit(exit_sl811_cs); | ||
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 3e1e4fe20d85..53099190952c 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
| @@ -48,8 +48,6 @@ | |||
| 48 | #include "pwc-uncompress.h" | 48 | #include "pwc-uncompress.h" |
| 49 | #include "pwc-kiara.h" | 49 | #include "pwc-kiara.h" |
| 50 | #include "pwc-timon.h" | 50 | #include "pwc-timon.h" |
| 51 | #include "pwc-dec1.h" | ||
| 52 | #include "pwc-dec23.h" | ||
| 53 | 51 | ||
| 54 | /* Request types: video */ | 52 | /* Request types: video */ |
| 55 | #define SET_LUM_CTL 0x01 | 53 | #define SET_LUM_CTL 0x01 |
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index c596083f06ba..bc3b1635eab0 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c | |||
| @@ -29,8 +29,6 @@ | |||
| 29 | 29 | ||
| 30 | #include "pwc.h" | 30 | #include "pwc.h" |
| 31 | #include "pwc-uncompress.h" | 31 | #include "pwc-uncompress.h" |
| 32 | #include "pwc-dec1.h" | ||
| 33 | #include "pwc-dec23.h" | ||
| 34 | 32 | ||
| 35 | int pwc_decompress(struct pwc_device *pdev) | 33 | int pwc_decompress(struct pwc_device *pdev) |
| 36 | { | 34 | { |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 52394f08a947..051c3a77b41b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { | |||
| 364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, | 364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, |
| 365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, | 365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, |
| 366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, | 366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, |
| 367 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, | ||
| 367 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, | 368 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, |
| 368 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, | 369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, |
| 369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, | 370 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, |
| @@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { | |||
| 475 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
| 476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 477 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
| 477 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, | 478 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, |
| 479 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, | ||
| 478 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 480 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
| 479 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 481 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
| 480 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 482 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
| @@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 618 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 620 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
| 619 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 621 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
| 620 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, | 622 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, |
| 623 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, | ||
| 621 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 624 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
| 622 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 625 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
| 623 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 626 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index a52bb13a9ce4..8866376823a5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
| @@ -144,6 +144,8 @@ | |||
| 144 | 144 | ||
| 145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ | 145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ |
| 146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ | 146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ |
| 147 | /* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ | ||
| 148 | #define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ | ||
| 147 | 149 | ||
| 148 | /* | 150 | /* |
| 149 | * Definitions for ID TECH (www.idt-net.com) devices | 151 | * Definitions for ID TECH (www.idt-net.com) devices |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4536f63faaea..5da76dd8fb28 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -1297,13 +1297,6 @@ static int __init usb_serial_init(void) | |||
| 1297 | goto exit_bus; | 1297 | goto exit_bus; |
| 1298 | } | 1298 | } |
| 1299 | 1299 | ||
| 1300 | /* register the generic driver, if we should */ | ||
| 1301 | result = usb_serial_generic_register(debug); | ||
| 1302 | if (result < 0) { | ||
| 1303 | err("%s - registering generic driver failed", __FUNCTION__); | ||
| 1304 | goto exit_generic; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | usb_serial_tty_driver->owner = THIS_MODULE; | 1300 | usb_serial_tty_driver->owner = THIS_MODULE; |
| 1308 | usb_serial_tty_driver->driver_name = "usbserial"; | 1301 | usb_serial_tty_driver->driver_name = "usbserial"; |
| 1309 | usb_serial_tty_driver->devfs_name = "usb/tts/"; | 1302 | usb_serial_tty_driver->devfs_name = "usb/tts/"; |
| @@ -1329,17 +1322,24 @@ static int __init usb_serial_init(void) | |||
| 1329 | goto exit_tty; | 1322 | goto exit_tty; |
| 1330 | } | 1323 | } |
| 1331 | 1324 | ||
| 1325 | /* register the generic driver, if we should */ | ||
| 1326 | result = usb_serial_generic_register(debug); | ||
| 1327 | if (result < 0) { | ||
| 1328 | err("%s - registering generic driver failed", __FUNCTION__); | ||
| 1329 | goto exit_generic; | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | info(DRIVER_DESC " " DRIVER_VERSION); | 1332 | info(DRIVER_DESC " " DRIVER_VERSION); |
| 1333 | 1333 | ||
| 1334 | return result; | 1334 | return result; |
| 1335 | 1335 | ||
| 1336 | exit_generic: | ||
| 1337 | usb_deregister(&usb_serial_driver); | ||
| 1338 | |||
| 1336 | exit_tty: | 1339 | exit_tty: |
| 1337 | tty_unregister_driver(usb_serial_tty_driver); | 1340 | tty_unregister_driver(usb_serial_tty_driver); |
| 1338 | 1341 | ||
| 1339 | exit_reg_driver: | 1342 | exit_reg_driver: |
| 1340 | usb_serial_generic_deregister(); | ||
| 1341 | |||
| 1342 | exit_generic: | ||
| 1343 | bus_unregister(&usb_serial_bus_type); | 1343 | bus_unregister(&usb_serial_bus_type); |
| 1344 | 1344 | ||
| 1345 | exit_bus: | 1345 | exit_bus: |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 549e22939260..25f9a9a65c24 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
| @@ -228,17 +228,17 @@ MODULE_DESCRIPTION( | |||
| 228 | MODULE_LICENSE("Dual BSD/GPL"); | 228 | MODULE_LICENSE("Dual BSD/GPL"); |
| 229 | MODULE_DEVICE_TABLE(pci, intelfb_pci_table); | 229 | MODULE_DEVICE_TABLE(pci, intelfb_pci_table); |
| 230 | 230 | ||
| 231 | static int accel __initdata = 1; | 231 | static int accel = 1; |
| 232 | static int vram __initdata = 4; | 232 | static int vram = 4; |
| 233 | static int hwcursor __initdata = 1; | 233 | static int hwcursor = 1; |
| 234 | static int mtrr __initdata = 1; | 234 | static int mtrr = 1; |
| 235 | static int fixed __initdata = 0; | 235 | static int fixed = 0; |
| 236 | static int noinit __initdata = 0; | 236 | static int noinit = 0; |
| 237 | static int noregister __initdata = 0; | 237 | static int noregister = 0; |
| 238 | static int probeonly __initdata = 0; | 238 | static int probeonly = 0; |
| 239 | static int idonly __initdata = 0; | 239 | static int idonly = 0; |
| 240 | static int bailearly __initdata = 0; | 240 | static int bailearly = 0; |
| 241 | static char *mode __initdata = NULL; | 241 | static char *mode = NULL; |
| 242 | 242 | ||
| 243 | module_param(accel, bool, S_IRUGO); | 243 | module_param(accel, bool, S_IRUGO); |
| 244 | MODULE_PARM_DESC(accel, "Enable console acceleration"); | 244 | MODULE_PARM_DESC(accel, "Enable console acceleration"); |
diff --git a/fs/cifs/README b/fs/cifs/README index e74df0c73256..34b0cf7111f3 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
| @@ -371,7 +371,7 @@ A partial list of the supported mount options follows: | |||
| 371 | on newly created files, directories, and devices (create, | 371 | on newly created files, directories, and devices (create, |
| 372 | mkdir, mknod) which will result in the server setting the | 372 | mkdir, mknod) which will result in the server setting the |
| 373 | uid and gid to the default (usually the server uid of the | 373 | uid and gid to the default (usually the server uid of the |
| 374 | usern who mounted the share). Letting the server (rather than | 374 | user who mounted the share). Letting the server (rather than |
| 375 | the client) set the uid and gid is the default. This | 375 | the client) set the uid and gid is the default. This |
| 376 | parameter has no effect if the CIFS Unix Extensions are not | 376 | parameter has no effect if the CIFS Unix Extensions are not |
| 377 | negotiated. | 377 | negotiated. |
| @@ -384,7 +384,7 @@ A partial list of the supported mount options follows: | |||
| 384 | client (e.g. when the application is doing large sequential | 384 | client (e.g. when the application is doing large sequential |
| 385 | reads bigger than page size without rereading the same data) | 385 | reads bigger than page size without rereading the same data) |
| 386 | this can provide better performance than the default | 386 | this can provide better performance than the default |
| 387 | behavior which caches reads (reaadahead) and writes | 387 | behavior which caches reads (readahead) and writes |
| 388 | (writebehind) through the local Linux client pagecache | 388 | (writebehind) through the local Linux client pagecache |
| 389 | if oplock (caching token) is granted and held. Note that | 389 | if oplock (caching token) is granted and held. Note that |
| 390 | direct allows write operations larger than page size | 390 | direct allows write operations larger than page size |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 0010511083fc..ea239dea571e 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -228,7 +228,7 @@ extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, | |||
| 228 | const struct nls_table *nls_codepage, | 228 | const struct nls_table *nls_codepage, |
| 229 | int remap_special_chars); | 229 | int remap_special_chars); |
| 230 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 230 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ |
| 231 | extern int cifs_convertUCSpath(char *target, const __u16 *source, int maxlen, | 231 | extern int cifs_convertUCSpath(char *target, const __le16 *source, int maxlen, |
| 232 | const struct nls_table * codepage); | 232 | const struct nls_table * codepage); |
| 233 | extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, | 233 | extern int cifsConvertToUCS(__le16 * target, const char *source, int maxlen, |
| 234 | const struct nls_table * cp, int mapChars); | 234 | const struct nls_table * cp, int mapChars); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 741ff0c69f37..3c628bf667a5 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -567,7 +567,7 @@ DelFileRetry: | |||
| 567 | 567 | ||
| 568 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 568 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 569 | name_len = | 569 | name_len = |
| 570 | cifsConvertToUCS((__u16 *) pSMB->fileName, fileName, | 570 | cifsConvertToUCS((__le16 *) pSMB->fileName, fileName, |
| 571 | PATH_MAX, nls_codepage, remap); | 571 | PATH_MAX, nls_codepage, remap); |
| 572 | name_len++; /* trailing null */ | 572 | name_len++; /* trailing null */ |
| 573 | name_len *= 2; | 573 | name_len *= 2; |
| @@ -665,7 +665,7 @@ MkDirRetry: | |||
| 665 | return rc; | 665 | return rc; |
| 666 | 666 | ||
| 667 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 667 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 668 | name_len = cifsConvertToUCS((__u16 *) pSMB->DirName, name, | 668 | name_len = cifsConvertToUCS((__le16 *) pSMB->DirName, name, |
| 669 | PATH_MAX, nls_codepage, remap); | 669 | PATH_MAX, nls_codepage, remap); |
| 670 | name_len++; /* trailing null */ | 670 | name_len++; /* trailing null */ |
| 671 | name_len *= 2; | 671 | name_len *= 2; |
| @@ -719,7 +719,7 @@ openRetry: | |||
| 719 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 719 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 720 | count = 1; /* account for one byte pad to word boundary */ | 720 | count = 1; /* account for one byte pad to word boundary */ |
| 721 | name_len = | 721 | name_len = |
| 722 | cifsConvertToUCS((__u16 *) (pSMB->fileName + 1), | 722 | cifsConvertToUCS((__le16 *) (pSMB->fileName + 1), |
| 723 | fileName, PATH_MAX, nls_codepage, remap); | 723 | fileName, PATH_MAX, nls_codepage, remap); |
| 724 | name_len++; /* trailing null */ | 724 | name_len++; /* trailing null */ |
| 725 | name_len *= 2; | 725 | name_len *= 2; |
| @@ -1141,7 +1141,7 @@ renameRetry: | |||
| 1141 | 1141 | ||
| 1142 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1142 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1143 | name_len = | 1143 | name_len = |
| 1144 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, | 1144 | cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, |
| 1145 | PATH_MAX, nls_codepage, remap); | 1145 | PATH_MAX, nls_codepage, remap); |
| 1146 | name_len++; /* trailing null */ | 1146 | name_len++; /* trailing null */ |
| 1147 | name_len *= 2; | 1147 | name_len *= 2; |
| @@ -1149,7 +1149,7 @@ renameRetry: | |||
| 1149 | /* protocol requires ASCII signature byte on Unicode string */ | 1149 | /* protocol requires ASCII signature byte on Unicode string */ |
| 1150 | pSMB->OldFileName[name_len + 1] = 0x00; | 1150 | pSMB->OldFileName[name_len + 1] = 0x00; |
| 1151 | name_len2 = | 1151 | name_len2 = |
| 1152 | cifsConvertToUCS((__u16 *) &pSMB->OldFileName[name_len + 2], | 1152 | cifsConvertToUCS((__le16 *) &pSMB->OldFileName[name_len + 2], |
| 1153 | toName, PATH_MAX, nls_codepage, remap); | 1153 | toName, PATH_MAX, nls_codepage, remap); |
| 1154 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1154 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
| 1155 | name_len2 *= 2; /* convert to bytes */ | 1155 | name_len2 *= 2; /* convert to bytes */ |
| @@ -1236,10 +1236,10 @@ int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, | |||
| 1236 | /* unicode only call */ | 1236 | /* unicode only call */ |
| 1237 | if(target_name == NULL) { | 1237 | if(target_name == NULL) { |
| 1238 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); | 1238 | sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid); |
| 1239 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, | 1239 | len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, |
| 1240 | dummy_string, 24, nls_codepage, remap); | 1240 | dummy_string, 24, nls_codepage, remap); |
| 1241 | } else { | 1241 | } else { |
| 1242 | len_of_str = cifsConvertToUCS((__u16 *)rename_info->target_name, | 1242 | len_of_str = cifsConvertToUCS((__le16 *)rename_info->target_name, |
| 1243 | target_name, PATH_MAX, nls_codepage, remap); | 1243 | target_name, PATH_MAX, nls_codepage, remap); |
| 1244 | } | 1244 | } |
| 1245 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); | 1245 | rename_info->target_name_len = cpu_to_le32(2 * len_of_str); |
| @@ -1296,7 +1296,7 @@ copyRetry: | |||
| 1296 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); | 1296 | pSMB->Flags = cpu_to_le16(flags & COPY_TREE); |
| 1297 | 1297 | ||
| 1298 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1298 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1299 | name_len = cifsConvertToUCS((__u16 *) pSMB->OldFileName, | 1299 | name_len = cifsConvertToUCS((__le16 *) pSMB->OldFileName, |
| 1300 | fromName, PATH_MAX, nls_codepage, | 1300 | fromName, PATH_MAX, nls_codepage, |
| 1301 | remap); | 1301 | remap); |
| 1302 | name_len++; /* trailing null */ | 1302 | name_len++; /* trailing null */ |
| @@ -1304,7 +1304,7 @@ copyRetry: | |||
| 1304 | pSMB->OldFileName[name_len] = 0x04; /* pad */ | 1304 | pSMB->OldFileName[name_len] = 0x04; /* pad */ |
| 1305 | /* protocol requires ASCII signature byte on Unicode string */ | 1305 | /* protocol requires ASCII signature byte on Unicode string */ |
| 1306 | pSMB->OldFileName[name_len + 1] = 0x00; | 1306 | pSMB->OldFileName[name_len + 1] = 0x00; |
| 1307 | name_len2 = cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], | 1307 | name_len2 = cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], |
| 1308 | toName, PATH_MAX, nls_codepage, remap); | 1308 | toName, PATH_MAX, nls_codepage, remap); |
| 1309 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1309 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
| 1310 | name_len2 *= 2; /* convert to bytes */ | 1310 | name_len2 *= 2; /* convert to bytes */ |
| @@ -1453,7 +1453,7 @@ createHardLinkRetry: | |||
| 1453 | return rc; | 1453 | return rc; |
| 1454 | 1454 | ||
| 1455 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1455 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1456 | name_len = cifsConvertToUCS((__u16 *) pSMB->FileName, toName, | 1456 | name_len = cifsConvertToUCS((__le16 *) pSMB->FileName, toName, |
| 1457 | PATH_MAX, nls_codepage, remap); | 1457 | PATH_MAX, nls_codepage, remap); |
| 1458 | name_len++; /* trailing null */ | 1458 | name_len++; /* trailing null */ |
| 1459 | name_len *= 2; | 1459 | name_len *= 2; |
| @@ -1476,7 +1476,7 @@ createHardLinkRetry: | |||
| 1476 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 1476 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
| 1477 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1477 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1478 | name_len_target = | 1478 | name_len_target = |
| 1479 | cifsConvertToUCS((__u16 *) data_offset, fromName, PATH_MAX, | 1479 | cifsConvertToUCS((__le16 *) data_offset, fromName, PATH_MAX, |
| 1480 | nls_codepage, remap); | 1480 | nls_codepage, remap); |
| 1481 | name_len_target++; /* trailing null */ | 1481 | name_len_target++; /* trailing null */ |
| 1482 | name_len_target *= 2; | 1482 | name_len_target *= 2; |
| @@ -1546,14 +1546,14 @@ winCreateHardLinkRetry: | |||
| 1546 | 1546 | ||
| 1547 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1547 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1548 | name_len = | 1548 | name_len = |
| 1549 | cifsConvertToUCS((__u16 *) pSMB->OldFileName, fromName, | 1549 | cifsConvertToUCS((__le16 *) pSMB->OldFileName, fromName, |
| 1550 | PATH_MAX, nls_codepage, remap); | 1550 | PATH_MAX, nls_codepage, remap); |
| 1551 | name_len++; /* trailing null */ | 1551 | name_len++; /* trailing null */ |
| 1552 | name_len *= 2; | 1552 | name_len *= 2; |
| 1553 | pSMB->OldFileName[name_len] = 0; /* pad */ | 1553 | pSMB->OldFileName[name_len] = 0; /* pad */ |
| 1554 | pSMB->OldFileName[name_len + 1] = 0x04; | 1554 | pSMB->OldFileName[name_len + 1] = 0x04; |
| 1555 | name_len2 = | 1555 | name_len2 = |
| 1556 | cifsConvertToUCS((__u16 *)&pSMB->OldFileName[name_len + 2], | 1556 | cifsConvertToUCS((__le16 *)&pSMB->OldFileName[name_len + 2], |
| 1557 | toName, PATH_MAX, nls_codepage, remap); | 1557 | toName, PATH_MAX, nls_codepage, remap); |
| 1558 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; | 1558 | name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; |
| 1559 | name_len2 *= 2; /* convert to bytes */ | 1559 | name_len2 *= 2; /* convert to bytes */ |
| @@ -1939,7 +1939,7 @@ queryAclRetry: | |||
| 1939 | 1939 | ||
| 1940 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1940 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 1941 | name_len = | 1941 | name_len = |
| 1942 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 1942 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 1943 | PATH_MAX, nls_codepage, remap); | 1943 | PATH_MAX, nls_codepage, remap); |
| 1944 | name_len++; /* trailing null */ | 1944 | name_len++; /* trailing null */ |
| 1945 | name_len *= 2; | 1945 | name_len *= 2; |
| @@ -2024,7 +2024,7 @@ setAclRetry: | |||
| 2024 | return rc; | 2024 | return rc; |
| 2025 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2025 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2026 | name_len = | 2026 | name_len = |
| 2027 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 2027 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
| 2028 | PATH_MAX, nls_codepage, remap); | 2028 | PATH_MAX, nls_codepage, remap); |
| 2029 | name_len++; /* trailing null */ | 2029 | name_len++; /* trailing null */ |
| 2030 | name_len *= 2; | 2030 | name_len *= 2; |
| @@ -2188,7 +2188,7 @@ QPathInfoRetry: | |||
| 2188 | 2188 | ||
| 2189 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2189 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2190 | name_len = | 2190 | name_len = |
| 2191 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2191 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 2192 | PATH_MAX, nls_codepage, remap); | 2192 | PATH_MAX, nls_codepage, remap); |
| 2193 | name_len++; /* trailing null */ | 2193 | name_len++; /* trailing null */ |
| 2194 | name_len *= 2; | 2194 | name_len *= 2; |
| @@ -2269,7 +2269,7 @@ UnixQPathInfoRetry: | |||
| 2269 | 2269 | ||
| 2270 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2270 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2271 | name_len = | 2271 | name_len = |
| 2272 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2272 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 2273 | PATH_MAX, nls_codepage, remap); | 2273 | PATH_MAX, nls_codepage, remap); |
| 2274 | name_len++; /* trailing null */ | 2274 | name_len++; /* trailing null */ |
| 2275 | name_len *= 2; | 2275 | name_len *= 2; |
| @@ -2350,7 +2350,7 @@ findUniqueRetry: | |||
| 2350 | 2350 | ||
| 2351 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2351 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2352 | name_len = | 2352 | name_len = |
| 2353 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX | 2353 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, PATH_MAX |
| 2354 | /* find define for this maxpathcomponent */ | 2354 | /* find define for this maxpathcomponent */ |
| 2355 | , nls_codepage); | 2355 | , nls_codepage); |
| 2356 | name_len++; /* trailing null */ | 2356 | name_len++; /* trailing null */ |
| @@ -2435,7 +2435,7 @@ findFirstRetry: | |||
| 2435 | 2435 | ||
| 2436 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2436 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2437 | name_len = | 2437 | name_len = |
| 2438 | cifsConvertToUCS((__u16 *) pSMB->FileName,searchName, | 2438 | cifsConvertToUCS((__le16 *) pSMB->FileName,searchName, |
| 2439 | PATH_MAX, nls_codepage, remap); | 2439 | PATH_MAX, nls_codepage, remap); |
| 2440 | /* We can not add the asterik earlier in case | 2440 | /* We can not add the asterik earlier in case |
| 2441 | it got remapped to 0xF03A as if it were part of the | 2441 | it got remapped to 0xF03A as if it were part of the |
| @@ -2726,7 +2726,7 @@ GetInodeNumberRetry: | |||
| 2726 | 2726 | ||
| 2727 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 2727 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 2728 | name_len = | 2728 | name_len = |
| 2729 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 2729 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 2730 | PATH_MAX,nls_codepage, remap); | 2730 | PATH_MAX,nls_codepage, remap); |
| 2731 | name_len++; /* trailing null */ | 2731 | name_len++; /* trailing null */ |
| 2732 | name_len *= 2; | 2732 | name_len *= 2; |
| @@ -2837,7 +2837,7 @@ getDFSRetry: | |||
| 2837 | if (ses->capabilities & CAP_UNICODE) { | 2837 | if (ses->capabilities & CAP_UNICODE) { |
| 2838 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 2838 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
| 2839 | name_len = | 2839 | name_len = |
| 2840 | cifsConvertToUCS((__u16 *) pSMB->RequestFileName, | 2840 | cifsConvertToUCS((__le16 *) pSMB->RequestFileName, |
| 2841 | searchName, PATH_MAX, nls_codepage, remap); | 2841 | searchName, PATH_MAX, nls_codepage, remap); |
| 2842 | name_len++; /* trailing null */ | 2842 | name_len++; /* trailing null */ |
| 2843 | name_len *= 2; | 2843 | name_len *= 2; |
| @@ -3369,7 +3369,7 @@ SetEOFRetry: | |||
| 3369 | 3369 | ||
| 3370 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3370 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 3371 | name_len = | 3371 | name_len = |
| 3372 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3372 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
| 3373 | PATH_MAX, nls_codepage, remap); | 3373 | PATH_MAX, nls_codepage, remap); |
| 3374 | name_len++; /* trailing null */ | 3374 | name_len++; /* trailing null */ |
| 3375 | name_len *= 2; | 3375 | name_len *= 2; |
| @@ -3627,7 +3627,7 @@ SetTimesRetry: | |||
| 3627 | 3627 | ||
| 3628 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3628 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 3629 | name_len = | 3629 | name_len = |
| 3630 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3630 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
| 3631 | PATH_MAX, nls_codepage, remap); | 3631 | PATH_MAX, nls_codepage, remap); |
| 3632 | name_len++; /* trailing null */ | 3632 | name_len++; /* trailing null */ |
| 3633 | name_len *= 2; | 3633 | name_len *= 2; |
| @@ -3708,7 +3708,7 @@ SetAttrLgcyRetry: | |||
| 3708 | 3708 | ||
| 3709 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3709 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 3710 | name_len = | 3710 | name_len = |
| 3711 | ConvertToUCS((wchar_t *) pSMB->fileName, fileName, | 3711 | ConvertToUCS((__le16 *) pSMB->fileName, fileName, |
| 3712 | PATH_MAX, nls_codepage); | 3712 | PATH_MAX, nls_codepage); |
| 3713 | name_len++; /* trailing null */ | 3713 | name_len++; /* trailing null */ |
| 3714 | name_len *= 2; | 3714 | name_len *= 2; |
| @@ -3759,7 +3759,7 @@ setPermsRetry: | |||
| 3759 | 3759 | ||
| 3760 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3760 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 3761 | name_len = | 3761 | name_len = |
| 3762 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 3762 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
| 3763 | PATH_MAX, nls_codepage, remap); | 3763 | PATH_MAX, nls_codepage, remap); |
| 3764 | name_len++; /* trailing null */ | 3764 | name_len++; /* trailing null */ |
| 3765 | name_len *= 2; | 3765 | name_len *= 2; |
| @@ -3904,7 +3904,7 @@ QAllEAsRetry: | |||
| 3904 | 3904 | ||
| 3905 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 3905 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 3906 | name_len = | 3906 | name_len = |
| 3907 | cifsConvertToUCS((wchar_t *) pSMB->FileName, searchName, | 3907 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 3908 | PATH_MAX, nls_codepage, remap); | 3908 | PATH_MAX, nls_codepage, remap); |
| 3909 | name_len++; /* trailing null */ | 3909 | name_len++; /* trailing null */ |
| 3910 | name_len *= 2; | 3910 | name_len *= 2; |
| @@ -4047,7 +4047,7 @@ QEARetry: | |||
| 4047 | 4047 | ||
| 4048 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4048 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 4049 | name_len = | 4049 | name_len = |
| 4050 | cifsConvertToUCS((__u16 *) pSMB->FileName, searchName, | 4050 | cifsConvertToUCS((__le16 *) pSMB->FileName, searchName, |
| 4051 | PATH_MAX, nls_codepage, remap); | 4051 | PATH_MAX, nls_codepage, remap); |
| 4052 | name_len++; /* trailing null */ | 4052 | name_len++; /* trailing null */ |
| 4053 | name_len *= 2; | 4053 | name_len *= 2; |
| @@ -4194,7 +4194,7 @@ SetEARetry: | |||
| 4194 | 4194 | ||
| 4195 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 4195 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
| 4196 | name_len = | 4196 | name_len = |
| 4197 | cifsConvertToUCS((__u16 *) pSMB->FileName, fileName, | 4197 | cifsConvertToUCS((__le16 *) pSMB->FileName, fileName, |
| 4198 | PATH_MAX, nls_codepage, remap); | 4198 | PATH_MAX, nls_codepage, remap); |
| 4199 | name_len++; /* trailing null */ | 4199 | name_len++; /* trailing null */ |
| 4200 | name_len *= 2; | 4200 | name_len *= 2; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e3137aa48cdd..3f3538d4a1fa 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -392,7 +392,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
| 392 | rc = 0; | 392 | rc = 0; |
| 393 | d_add(direntry, NULL); | 393 | d_add(direntry, NULL); |
| 394 | } else { | 394 | } else { |
| 395 | cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc)); | 395 | cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", |
| 396 | rc,full_path)); | ||
| 396 | /* BB special case check for Access Denied - watch security | 397 | /* BB special case check for Access Denied - watch security |
| 397 | exposure of returning dir info implicitly via different rc | 398 | exposure of returning dir info implicitly via different rc |
| 398 | if file exists or not but no access BB */ | 399 | if file exists or not but no access BB */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 670947288262..b8b78cbb34c9 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -422,7 +422,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
| 422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 422 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 423 | 423 | ||
| 424 | if (!rc) { | 424 | if (!rc) { |
| 425 | direntry->d_inode->i_nlink--; | 425 | if(direntry->d_inode) |
| 426 | direntry->d_inode->i_nlink--; | ||
| 426 | } else if (rc == -ENOENT) { | 427 | } else if (rc == -ENOENT) { |
| 427 | d_drop(direntry); | 428 | d_drop(direntry); |
| 428 | } else if (rc == -ETXTBSY) { | 429 | } else if (rc == -ETXTBSY) { |
| @@ -440,7 +441,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
| 440 | cifs_sb->mnt_cifs_flags & | 441 | cifs_sb->mnt_cifs_flags & |
| 441 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 442 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 442 | CIFSSMBClose(xid, pTcon, netfid); | 443 | CIFSSMBClose(xid, pTcon, netfid); |
| 443 | direntry->d_inode->i_nlink--; | 444 | if(direntry->d_inode) |
| 445 | direntry->d_inode->i_nlink--; | ||
| 444 | } | 446 | } |
| 445 | } else if (rc == -EACCES) { | 447 | } else if (rc == -EACCES) { |
| 446 | /* try only if r/o attribute set in local lookup data? */ | 448 | /* try only if r/o attribute set in local lookup data? */ |
| @@ -494,7 +496,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
| 494 | cifs_sb->mnt_cifs_flags & | 496 | cifs_sb->mnt_cifs_flags & |
| 495 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 497 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 496 | if (!rc) { | 498 | if (!rc) { |
| 497 | direntry->d_inode->i_nlink--; | 499 | if(direntry->d_inode) |
| 500 | direntry->d_inode->i_nlink--; | ||
| 498 | } else if (rc == -ETXTBSY) { | 501 | } else if (rc == -ETXTBSY) { |
| 499 | int oplock = FALSE; | 502 | int oplock = FALSE; |
| 500 | __u16 netfid; | 503 | __u16 netfid; |
| @@ -514,17 +517,20 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) | |||
| 514 | cifs_sb->mnt_cifs_flags & | 517 | cifs_sb->mnt_cifs_flags & |
| 515 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 518 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 516 | CIFSSMBClose(xid, pTcon, netfid); | 519 | CIFSSMBClose(xid, pTcon, netfid); |
| 517 | direntry->d_inode->i_nlink--; | 520 | if(direntry->d_inode) |
| 521 | direntry->d_inode->i_nlink--; | ||
| 518 | } | 522 | } |
| 519 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ | 523 | /* BB if rc = -ETXTBUSY goto the rename logic BB */ |
| 520 | } | 524 | } |
| 521 | } | 525 | } |
| 522 | } | 526 | } |
| 523 | cifsInode = CIFS_I(direntry->d_inode); | 527 | if(direntry->d_inode) { |
| 524 | cifsInode->time = 0; /* will force revalidate to get info when | 528 | cifsInode = CIFS_I(direntry->d_inode); |
| 525 | needed */ | 529 | cifsInode->time = 0; /* will force revalidate to get info |
| 526 | direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = | 530 | when needed */ |
| 527 | current_fs_time(inode->i_sb); | 531 | direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); |
| 532 | } | ||
| 533 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | ||
| 528 | cifsInode = CIFS_I(inode); | 534 | cifsInode = CIFS_I(inode); |
| 529 | cifsInode->time = 0; /* force revalidate of dir as well */ | 535 | cifsInode->time = 0; /* force revalidate of dir as well */ |
| 530 | 536 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index db14b503d89e..072b4ee8c53e 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -571,6 +571,7 @@ cifs_convertUCSpath(char *target, const __le16 * source, int maxlen, | |||
| 571 | break; | 571 | break; |
| 572 | case UNI_LESSTHAN: | 572 | case UNI_LESSTHAN: |
| 573 | target[j] = '<'; | 573 | target[j] = '<'; |
| 574 | break; | ||
| 574 | default: | 575 | default: |
| 575 | len = cp->uni2char(src_char, &target[j], | 576 | len = cp->uni2char(src_char, &target[j], |
| 576 | NLS_MAX_CHARSET_SIZE); | 577 | NLS_MAX_CHARSET_SIZE); |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 14a0d339d036..4bf43ea87c46 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include "kern_util.h" | 23 | #include "kern_util.h" |
| 24 | #include "kern.h" | 24 | #include "kern.h" |
| 25 | #include "user_util.h" | 25 | #include "user_util.h" |
| 26 | #include "2_5compat.h" | ||
| 27 | #include "init.h" | 26 | #include "init.h" |
| 28 | 27 | ||
| 29 | struct hostfs_inode_info { | 28 | struct hostfs_inode_info { |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index 67423c696c0a..6fd57f154197 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
| @@ -12,15 +12,8 @@ | |||
| 12 | #include <asm/uaccess.h> | 12 | #include <asm/uaccess.h> |
| 13 | 13 | ||
| 14 | #ifndef HAVE_ARCH_DEVTREE_FIXUPS | 14 | #ifndef HAVE_ARCH_DEVTREE_FIXUPS |
| 15 | static inline void set_node_proc_entry(struct device_node *np, struct proc_dir_entry *de) | 15 | static inline void set_node_proc_entry(struct device_node *np, |
| 16 | { | 16 | struct proc_dir_entry *de) |
| 17 | } | ||
| 18 | |||
| 19 | static void inline set_node_name_link(struct device_node *np, struct proc_dir_entry *de) | ||
| 20 | { | ||
| 21 | } | ||
| 22 | |||
| 23 | static void inline set_node_addr_link(struct device_node *np, struct proc_dir_entry *de) | ||
| 24 | { | 17 | { |
| 25 | } | 18 | } |
| 26 | #endif | 19 | #endif |
| @@ -58,89 +51,67 @@ static int property_read_proc(char *page, char **start, off_t off, | |||
| 58 | /* | 51 | /* |
| 59 | * Process a node, adding entries for its children and its properties. | 52 | * Process a node, adding entries for its children and its properties. |
| 60 | */ | 53 | */ |
| 61 | void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *de) | 54 | void proc_device_tree_add_node(struct device_node *np, |
| 55 | struct proc_dir_entry *de) | ||
| 62 | { | 56 | { |
| 63 | struct property *pp; | 57 | struct property *pp; |
| 64 | struct proc_dir_entry *ent; | 58 | struct proc_dir_entry *ent; |
| 65 | struct device_node *child, *sib; | 59 | struct device_node *child; |
| 66 | const char *p, *at; | 60 | struct proc_dir_entry *list = NULL, **lastp; |
| 67 | int l; | 61 | const char *p; |
| 68 | struct proc_dir_entry *list, **lastp, *al; | ||
| 69 | 62 | ||
| 70 | set_node_proc_entry(np, de); | 63 | set_node_proc_entry(np, de); |
| 71 | lastp = &list; | 64 | lastp = &list; |
| 72 | for (pp = np->properties; pp != 0; pp = pp->next) { | 65 | for (child = NULL; (child = of_get_next_child(np, child));) { |
| 73 | /* | ||
| 74 | * Unfortunately proc_register puts each new entry | ||
| 75 | * at the beginning of the list. So we rearrange them. | ||
| 76 | */ | ||
| 77 | ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ? | ||
| 78 | S_IRUGO : S_IRUSR, de, property_read_proc, pp); | ||
| 79 | if (ent == 0) | ||
| 80 | break; | ||
| 81 | if (!strncmp(pp->name, "security-", 9)) | ||
| 82 | ent->size = 0; /* don't leak number of password chars */ | ||
| 83 | else | ||
| 84 | ent->size = pp->length; | ||
| 85 | *lastp = ent; | ||
| 86 | lastp = &ent->next; | ||
| 87 | } | ||
| 88 | child = NULL; | ||
| 89 | while ((child = of_get_next_child(np, child))) { | ||
| 90 | p = strrchr(child->full_name, '/'); | 66 | p = strrchr(child->full_name, '/'); |
| 91 | if (!p) | 67 | if (!p) |
| 92 | p = child->full_name; | 68 | p = child->full_name; |
| 93 | else | 69 | else |
| 94 | ++p; | 70 | ++p; |
| 95 | /* chop off '@0' if the name ends with that */ | ||
| 96 | l = strlen(p); | ||
| 97 | if (l > 2 && p[l-2] == '@' && p[l-1] == '0') | ||
| 98 | l -= 2; | ||
| 99 | ent = proc_mkdir(p, de); | 71 | ent = proc_mkdir(p, de); |
| 100 | if (ent == 0) | 72 | if (ent == 0) |
| 101 | break; | 73 | break; |
| 102 | *lastp = ent; | 74 | *lastp = ent; |
| 75 | ent->next = NULL; | ||
| 103 | lastp = &ent->next; | 76 | lastp = &ent->next; |
| 104 | proc_device_tree_add_node(child, ent); | 77 | proc_device_tree_add_node(child, ent); |
| 105 | 78 | } | |
| 106 | /* | 79 | of_node_put(child); |
| 107 | * If we left the address part on the name, consider | 80 | for (pp = np->properties; pp != 0; pp = pp->next) { |
| 108 | * adding symlinks from the name and address parts. | ||
| 109 | */ | ||
| 110 | if (p[l] != 0 || (at = strchr(p, '@')) == 0) | ||
| 111 | continue; | ||
| 112 | |||
| 113 | /* | 81 | /* |
| 114 | * If this is the first node with a given name property, | 82 | * Yet another Apple device-tree bogosity: on some machines, |
| 115 | * add a symlink with the name property as its name. | 83 | * they have properties & nodes with the same name. Those |
| 84 | * properties are quite unimportant for us though, thus we | ||
| 85 | * simply "skip" them here, but we do have to check. | ||
| 116 | */ | 86 | */ |
| 117 | sib = NULL; | 87 | for (ent = list; ent != NULL; ent = ent->next) |
| 118 | while ((sib = of_get_next_child(np, sib)) && sib != child) | 88 | if (!strcmp(ent->name, pp->name)) |
| 119 | if (sib->name && strcmp(sib->name, child->name) == 0) | ||
| 120 | break; | ||
| 121 | if (sib == child && strncmp(p, child->name, l) != 0) { | ||
| 122 | al = proc_symlink(child->name, de, ent->name); | ||
| 123 | if (al == 0) { | ||
| 124 | of_node_put(sib); | ||
| 125 | break; | 89 | break; |
| 126 | } | 90 | if (ent != NULL) { |
| 127 | set_node_name_link(child, al); | 91 | printk(KERN_WARNING "device-tree: property \"%s\" name" |
| 128 | *lastp = al; | 92 | " conflicts with node in %s\n", pp->name, |
| 129 | lastp = &al->next; | 93 | np->full_name); |
| 94 | continue; | ||
| 130 | } | 95 | } |
| 131 | of_node_put(sib); | 96 | |
| 132 | /* | 97 | /* |
| 133 | * Add another directory with the @address part as its name. | 98 | * Unfortunately proc_register puts each new entry |
| 99 | * at the beginning of the list. So we rearrange them. | ||
| 134 | */ | 100 | */ |
| 135 | al = proc_symlink(at, de, ent->name); | 101 | ent = create_proc_read_entry(pp->name, |
| 136 | if (al == 0) | 102 | strncmp(pp->name, "security-", 9) |
| 103 | ? S_IRUGO : S_IRUSR, de, | ||
| 104 | property_read_proc, pp); | ||
| 105 | if (ent == 0) | ||
| 137 | break; | 106 | break; |
| 138 | set_node_addr_link(child, al); | 107 | if (!strncmp(pp->name, "security-", 9)) |
| 139 | *lastp = al; | 108 | ent->size = 0; /* don't leak number of password chars */ |
| 140 | lastp = &al->next; | 109 | else |
| 110 | ent->size = pp->length; | ||
| 111 | ent->next = NULL; | ||
| 112 | *lastp = ent; | ||
| 113 | lastp = &ent->next; | ||
| 141 | } | 114 | } |
| 142 | of_node_put(child); | ||
| 143 | *lastp = NULL; | ||
| 144 | de->subdir = list; | 115 | de->subdir = list; |
| 145 | } | 116 | } |
| 146 | 117 | ||
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index 457a8fe28575..85d8dbe843f1 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
| 48 | /* How many days come before each month (0-12). */ | 48 | /* How many days come before each month (0-12). */ |
| 49 | const unsigned short int __mon_yday[2][13] = | 49 | static const unsigned short int __mon_yday[2][13] = |
| 50 | { | 50 | { |
| 51 | /* Normal years. */ | 51 | /* Normal years. */ |
| 52 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, | 52 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, |
diff --git a/include/asm-i386/timer.h b/include/asm-i386/timer.h index 40c54f69780e..c34709849839 100644 --- a/include/asm-i386/timer.h +++ b/include/asm-i386/timer.h | |||
| @@ -53,6 +53,7 @@ extern struct init_timer_opts timer_cyclone_init; | |||
| 53 | 53 | ||
| 54 | extern unsigned long calibrate_tsc(void); | 54 | extern unsigned long calibrate_tsc(void); |
| 55 | extern void init_cpu_khz(void); | 55 | extern void init_cpu_khz(void); |
| 56 | extern int recalibrate_cpu_khz(void); | ||
| 56 | #ifdef CONFIG_HPET_TIMER | 57 | #ifdef CONFIG_HPET_TIMER |
| 57 | extern struct init_timer_opts timer_hpet_init; | 58 | extern struct init_timer_opts timer_hpet_init; |
| 58 | extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr); | 59 | extern unsigned long calibrate_tsc_hpet(unsigned long *tsc_hpet_quotient_ptr); |
diff --git a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h index ed5416c5b1ac..7f3333dd00e4 100644 --- a/include/asm-ia64/perfmon.h +++ b/include/asm-ia64/perfmon.h | |||
| @@ -177,6 +177,10 @@ typedef union { | |||
| 177 | 177 | ||
| 178 | extern long perfmonctl(int fd, int cmd, void *arg, int narg); | 178 | extern long perfmonctl(int fd, int cmd, void *arg, int narg); |
| 179 | 179 | ||
| 180 | typedef struct { | ||
| 181 | void (*handler)(int irq, void *arg, struct pt_regs *regs); | ||
| 182 | } pfm_intr_handler_desc_t; | ||
| 183 | |||
| 180 | extern void pfm_save_regs (struct task_struct *); | 184 | extern void pfm_save_regs (struct task_struct *); |
| 181 | extern void pfm_load_regs (struct task_struct *); | 185 | extern void pfm_load_regs (struct task_struct *); |
| 182 | 186 | ||
| @@ -187,6 +191,10 @@ extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, | |||
| 187 | extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs); | 191 | extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs); |
| 188 | extern void pfm_init_percpu(void); | 192 | extern void pfm_init_percpu(void); |
| 189 | extern void pfm_handle_work(void); | 193 | extern void pfm_handle_work(void); |
| 194 | extern int pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); | ||
| 195 | extern int pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); | ||
| 196 | |||
| 197 | |||
| 190 | 198 | ||
| 191 | /* | 199 | /* |
| 192 | * Reset PMD register flags | 200 | * Reset PMD register flags |
diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index 56d74ca76b5d..eb0395ad0d6a 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h | |||
| @@ -115,6 +115,13 @@ | |||
| 115 | #define SAL_IROUTER_INTR_XMIT SAL_CONSOLE_INTR_XMIT | 115 | #define SAL_IROUTER_INTR_XMIT SAL_CONSOLE_INTR_XMIT |
| 116 | #define SAL_IROUTER_INTR_RECV SAL_CONSOLE_INTR_RECV | 116 | #define SAL_IROUTER_INTR_RECV SAL_CONSOLE_INTR_RECV |
| 117 | 117 | ||
| 118 | /* | ||
| 119 | * Error Handling Features | ||
| 120 | */ | ||
| 121 | #define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1 | ||
| 122 | #define SAL_ERR_FEAT_LOG_SBES 0x2 | ||
| 123 | #define SAL_ERR_FEAT_MFR_OVERRIDE 0x4 | ||
| 124 | #define SAL_ERR_FEAT_SBE_THRESHOLD 0xffff0000 | ||
| 118 | 125 | ||
| 119 | /* | 126 | /* |
| 120 | * SAL Error Codes | 127 | * SAL Error Codes |
| @@ -342,6 +349,25 @@ ia64_sn_plat_cpei_handler(void) | |||
| 342 | } | 349 | } |
| 343 | 350 | ||
| 344 | /* | 351 | /* |
| 352 | * Set Error Handling Features | ||
| 353 | */ | ||
| 354 | static inline u64 | ||
| 355 | ia64_sn_plat_set_error_handling_features(void) | ||
| 356 | { | ||
| 357 | struct ia64_sal_retval ret_stuff; | ||
| 358 | |||
| 359 | ret_stuff.status = 0; | ||
| 360 | ret_stuff.v0 = 0; | ||
| 361 | ret_stuff.v1 = 0; | ||
| 362 | ret_stuff.v2 = 0; | ||
| 363 | SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES, | ||
| 364 | (SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV | SAL_ERR_FEAT_LOG_SBES), | ||
| 365 | 0, 0, 0, 0, 0, 0); | ||
| 366 | |||
| 367 | return ret_stuff.status; | ||
| 368 | } | ||
| 369 | |||
| 370 | /* | ||
| 345 | * Checks for console input. | 371 | * Checks for console input. |
| 346 | */ | 372 | */ |
| 347 | static inline u64 | 373 | static inline u64 |
| @@ -472,7 +498,7 @@ static inline u64 | |||
| 472 | ia64_sn_pod_mode(void) | 498 | ia64_sn_pod_mode(void) |
| 473 | { | 499 | { |
| 474 | struct ia64_sal_retval isrv; | 500 | struct ia64_sal_retval isrv; |
| 475 | SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); | 501 | SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); |
| 476 | if (isrv.status) | 502 | if (isrv.status) |
| 477 | return 0; | 503 | return 0; |
| 478 | return isrv.v0; | 504 | return isrv.v0; |
diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h index 42fd1068cf2a..c5883dbed63f 100644 --- a/include/asm-ppc/cpm2.h +++ b/include/asm-ppc/cpm2.h | |||
| @@ -1039,6 +1039,52 @@ typedef struct im_idma { | |||
| 1039 | #define CMXSCR_TS4CS_CLK7 0x00000006 /* SCC4 Tx Clock Source is CLK7 */ | 1039 | #define CMXSCR_TS4CS_CLK7 0x00000006 /* SCC4 Tx Clock Source is CLK7 */ |
| 1040 | #define CMXSCR_TS4CS_CLK8 0x00000007 /* SCC4 Tx Clock Source is CLK8 */ | 1040 | #define CMXSCR_TS4CS_CLK8 0x00000007 /* SCC4 Tx Clock Source is CLK8 */ |
| 1041 | 1041 | ||
| 1042 | /*----------------------------------------------------------------------- | ||
| 1043 | * SIUMCR - SIU Module Configuration Register 4-31 | ||
| 1044 | */ | ||
| 1045 | #define SIUMCR_BBD 0x80000000 /* Bus Busy Disable */ | ||
| 1046 | #define SIUMCR_ESE 0x40000000 /* External Snoop Enable */ | ||
| 1047 | #define SIUMCR_PBSE 0x20000000 /* Parity Byte Select Enable */ | ||
| 1048 | #define SIUMCR_CDIS 0x10000000 /* Core Disable */ | ||
| 1049 | #define SIUMCR_DPPC00 0x00000000 /* Data Parity Pins Configuration*/ | ||
| 1050 | #define SIUMCR_DPPC01 0x04000000 /* - " - */ | ||
| 1051 | #define SIUMCR_DPPC10 0x08000000 /* - " - */ | ||
| 1052 | #define SIUMCR_DPPC11 0x0c000000 /* - " - */ | ||
| 1053 | #define SIUMCR_L2CPC00 0x00000000 /* L2 Cache Pins Configuration */ | ||
| 1054 | #define SIUMCR_L2CPC01 0x01000000 /* - " - */ | ||
| 1055 | #define SIUMCR_L2CPC10 0x02000000 /* - " - */ | ||
| 1056 | #define SIUMCR_L2CPC11 0x03000000 /* - " - */ | ||
| 1057 | #define SIUMCR_LBPC00 0x00000000 /* Local Bus Pins Configuration */ | ||
| 1058 | #define SIUMCR_LBPC01 0x00400000 /* - " - */ | ||
| 1059 | #define SIUMCR_LBPC10 0x00800000 /* - " - */ | ||
| 1060 | #define SIUMCR_LBPC11 0x00c00000 /* - " - */ | ||
| 1061 | #define SIUMCR_APPC00 0x00000000 /* Address Parity Pins Configuration*/ | ||
| 1062 | #define SIUMCR_APPC01 0x00100000 /* - " - */ | ||
| 1063 | #define SIUMCR_APPC10 0x00200000 /* - " - */ | ||
| 1064 | #define SIUMCR_APPC11 0x00300000 /* - " - */ | ||
| 1065 | #define SIUMCR_CS10PC00 0x00000000 /* CS10 Pin Configuration */ | ||
| 1066 | #define SIUMCR_CS10PC01 0x00040000 /* - " - */ | ||
| 1067 | #define SIUMCR_CS10PC10 0x00080000 /* - " - */ | ||
| 1068 | #define SIUMCR_CS10PC11 0x000c0000 /* - " - */ | ||
| 1069 | #define SIUMCR_BCTLC00 0x00000000 /* Buffer Control Configuration */ | ||
| 1070 | #define SIUMCR_BCTLC01 0x00010000 /* - " - */ | ||
| 1071 | #define SIUMCR_BCTLC10 0x00020000 /* - " - */ | ||
| 1072 | #define SIUMCR_BCTLC11 0x00030000 /* - " - */ | ||
| 1073 | #define SIUMCR_MMR00 0x00000000 /* Mask Masters Requests */ | ||
| 1074 | #define SIUMCR_MMR01 0x00004000 /* - " - */ | ||
| 1075 | #define SIUMCR_MMR10 0x00008000 /* - " - */ | ||
| 1076 | #define SIUMCR_MMR11 0x0000c000 /* - " - */ | ||
| 1077 | #define SIUMCR_LPBSE 0x00002000 /* LocalBus Parity Byte Select Enable*/ | ||
| 1078 | |||
| 1079 | /*----------------------------------------------------------------------- | ||
| 1080 | * SCCR - System Clock Control Register 9-8 | ||
| 1081 | */ | ||
| 1082 | #define SCCR_PCI_MODE 0x00000100 /* PCI Mode */ | ||
| 1083 | #define SCCR_PCI_MODCK 0x00000080 /* Value of PCI_MODCK pin */ | ||
| 1084 | #define SCCR_PCIDF_MSK 0x00000078 /* PCI division factor */ | ||
| 1085 | #define SCCR_PCIDF_SHIFT 3 | ||
| 1086 | |||
| 1087 | |||
| 1042 | #endif /* __CPM2__ */ | 1088 | #endif /* __CPM2__ */ |
| 1043 | #endif /* __KERNEL__ */ | 1089 | #endif /* __KERNEL__ */ |
| 1044 | 1090 | ||
diff --git a/include/asm-ppc/m8260_pci.h b/include/asm-ppc/m8260_pci.h index 163a6b91d5b2..bf9e05dd54b5 100644 --- a/include/asm-ppc/m8260_pci.h +++ b/include/asm-ppc/m8260_pci.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | * Define the vendor/device ID for the MPC8265. | 19 | * Define the vendor/device ID for the MPC8265. |
| 20 | */ | 20 | */ |
| 21 | #define PCI_DEVICE_ID_MPC8265 ((0x18C0 << 16) | PCI_VENDOR_ID_MOTOROLA) | 21 | #define PCI_DEVICE_ID_MPC8265 ((0x18C0 << 16) | PCI_VENDOR_ID_MOTOROLA) |
| 22 | #define PCI_DEVICE_ID_MPC8272 ((0x18C1 << 16) | PCI_VENDOR_ID_MOTOROLA) | ||
| 22 | 23 | ||
| 23 | #define M8265_PCIBR0 0x101ac | 24 | #define M8265_PCIBR0 0x101ac |
| 24 | #define M8265_PCIBR1 0x101b0 | 25 | #define M8265_PCIBR1 0x101b0 |
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h index d820894e5991..89eb8a2ac693 100644 --- a/include/asm-ppc/mpc8260.h +++ b/include/asm-ppc/mpc8260.h | |||
| @@ -41,7 +41,7 @@ | |||
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #ifdef CONFIG_PCI_8260 | 43 | #ifdef CONFIG_PCI_8260 |
| 44 | #include <syslib/m8260_pci.h> | 44 | #include <syslib/m82xx_pci.h> |
| 45 | #endif | 45 | #endif |
| 46 | 46 | ||
| 47 | /* Make sure the memory translation stuff is there if PCI not used. | 47 | /* Make sure the memory translation stuff is there if PCI not used. |
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index 2440a2c90ae9..04b1a84f7ca3 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h | |||
| @@ -147,9 +147,7 @@ struct device_node { | |||
| 147 | struct device_node *sibling; | 147 | struct device_node *sibling; |
| 148 | struct device_node *next; /* next device of same type */ | 148 | struct device_node *next; /* next device of same type */ |
| 149 | struct device_node *allnext; /* next in list of all nodes */ | 149 | struct device_node *allnext; /* next in list of all nodes */ |
| 150 | struct proc_dir_entry *pde; /* this node's proc directory */ | 150 | struct proc_dir_entry *pde; /* this node's proc directory */ |
| 151 | struct proc_dir_entry *name_link; /* name symlink */ | ||
| 152 | struct proc_dir_entry *addr_link; /* addr symlink */ | ||
| 153 | struct kref kref; | 151 | struct kref kref; |
| 154 | unsigned long _flags; | 152 | unsigned long _flags; |
| 155 | }; | 153 | }; |
| @@ -174,15 +172,6 @@ static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_e | |||
| 174 | dn->pde = de; | 172 | dn->pde = de; |
| 175 | } | 173 | } |
| 176 | 174 | ||
| 177 | static void inline set_node_name_link(struct device_node *dn, struct proc_dir_entry *de) | ||
| 178 | { | ||
| 179 | dn->name_link = de; | ||
| 180 | } | ||
| 181 | |||
| 182 | static void inline set_node_addr_link(struct device_node *dn, struct proc_dir_entry *de) | ||
| 183 | { | ||
| 184 | dn->addr_link = de; | ||
| 185 | } | ||
| 186 | 175 | ||
| 187 | /* OBSOLETE: Old stlye node lookup */ | 176 | /* OBSOLETE: Old stlye node lookup */ |
| 188 | extern struct device_node *find_devices(const char *name); | 177 | extern struct device_node *find_devices(const char *name); |
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index d82f883d8e6d..4bbbd9f3c37e 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h | |||
| @@ -27,7 +27,7 @@ struct thread_info { | |||
| 27 | 27 | ||
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #define PREEMPT_ACTIVE 0x4000000 | 30 | #define PREEMPT_ACTIVE 0x10000000 |
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | * macros/functions for gaining access to the thread information structure | 33 | * macros/functions for gaining access to the thread information structure |
diff --git a/include/asm-sh64/thread_info.h b/include/asm-sh64/thread_info.h index e65f394da472..8a32d6bd0b79 100644 --- a/include/asm-sh64/thread_info.h +++ b/include/asm-sh64/thread_info.h | |||
| @@ -73,7 +73,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 73 | 73 | ||
| 74 | #define THREAD_SIZE 8192 | 74 | #define THREAD_SIZE 8192 |
| 75 | 75 | ||
| 76 | #define PREEMPT_ACTIVE 0x4000000 | 76 | #define PREEMPT_ACTIVE 0x10000000 |
| 77 | 77 | ||
| 78 | /* thread information flags */ | 78 | /* thread information flags */ |
| 79 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 79 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
diff --git a/include/asm-sparc64/iommu.h b/include/asm-sparc64/iommu.h index 5fd16e42a045..0de7a3da79cd 100644 --- a/include/asm-sparc64/iommu.h +++ b/include/asm-sparc64/iommu.h | |||
| @@ -16,4 +16,6 @@ | |||
| 16 | #define IOPTE_CACHE 0x0000000000000010UL /* Cached (in UPA E-cache) */ | 16 | #define IOPTE_CACHE 0x0000000000000010UL /* Cached (in UPA E-cache) */ |
| 17 | #define IOPTE_WRITE 0x0000000000000002UL /* Writeable */ | 17 | #define IOPTE_WRITE 0x0000000000000002UL /* Writeable */ |
| 18 | 18 | ||
| 19 | #define IOMMU_NUM_CTXS 4096 | ||
| 20 | |||
| 19 | #endif /* !(_SPARC_IOMMU_H) */ | 21 | #endif /* !(_SPARC_IOMMU_H) */ |
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 92999631c819..4c15610a2bac 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
| 16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
| 17 | #include <asm/oplib.h> | 17 | #include <asm/oplib.h> |
| 18 | #include <asm/iommu.h> | ||
| 18 | 19 | ||
| 19 | /* The abstraction used here is that there are PCI controllers, | 20 | /* The abstraction used here is that there are PCI controllers, |
| 20 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules | 21 | * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules |
| @@ -40,9 +41,6 @@ struct pci_iommu { | |||
| 40 | */ | 41 | */ |
| 41 | spinlock_t lock; | 42 | spinlock_t lock; |
| 42 | 43 | ||
| 43 | /* Context allocator. */ | ||
| 44 | unsigned int iommu_cur_ctx; | ||
| 45 | |||
| 46 | /* IOMMU page table, a linear array of ioptes. */ | 44 | /* IOMMU page table, a linear array of ioptes. */ |
| 47 | iopte_t *page_table; /* The page table itself. */ | 45 | iopte_t *page_table; /* The page table itself. */ |
| 48 | int page_table_sz_bits; /* log2 of ow many pages does it map? */ | 46 | int page_table_sz_bits; /* log2 of ow many pages does it map? */ |
| @@ -87,6 +85,10 @@ struct pci_iommu { | |||
| 87 | u16 flush; | 85 | u16 flush; |
| 88 | } alloc_info[PBM_NCLUSTERS]; | 86 | } alloc_info[PBM_NCLUSTERS]; |
| 89 | 87 | ||
| 88 | /* CTX allocation. */ | ||
| 89 | unsigned long ctx_lowest_free; | ||
| 90 | unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)]; | ||
| 91 | |||
| 90 | /* Here a PCI controller driver describes the areas of | 92 | /* Here a PCI controller driver describes the areas of |
| 91 | * PCI memory space where DMA to/from physical memory | 93 | * PCI memory space where DMA to/from physical memory |
| 92 | * are addressed. Drivers interrogate the PCI layer | 94 | * are addressed. Drivers interrogate the PCI layer |
diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 504ea8e486b0..5afee8a8cdf3 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h | |||
| @@ -98,7 +98,13 @@ extern unsigned long uml_physmem; | |||
| 98 | 98 | ||
| 99 | extern unsigned long to_phys(void *virt); | 99 | extern unsigned long to_phys(void *virt); |
| 100 | extern void *to_virt(unsigned long phys); | 100 | extern void *to_virt(unsigned long phys); |
| 101 | #define __pa(virt) to_phys((void *) virt) | 101 | |
| 102 | /* Cast to unsigned long before casting to void * to avoid a warning from | ||
| 103 | * mmap_kmem about cutting a long long down to a void *. Not sure that | ||
| 104 | * casting is the right thing, but 32-bit UML can't have 64-bit virtual | ||
| 105 | * addresses | ||
| 106 | */ | ||
| 107 | #define __pa(virt) to_phys((void *) (unsigned long) virt) | ||
| 102 | #define __va(phys) to_virt((unsigned long) phys) | 108 | #define __va(phys) to_virt((unsigned long) phys) |
| 103 | 109 | ||
| 104 | #define page_to_pfn(page) ((page) - mem_map) | 110 | #define page_to_pfn(page) ((page) - mem_map) |
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index 510e513c7f88..a88040920311 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
| @@ -114,17 +114,9 @@ extern unsigned long end_iomem; | |||
| 114 | extern unsigned long pg0[1024]; | 114 | extern unsigned long pg0[1024]; |
| 115 | 115 | ||
| 116 | /* | 116 | /* |
| 117 | * BAD_PAGETABLE is used when we need a bogus page-table, while | ||
| 118 | * BAD_PAGE is used for a bogus page. | ||
| 119 | * | ||
| 120 | * ZERO_PAGE is a global shared page that is always zero: used | 117 | * ZERO_PAGE is a global shared page that is always zero: used |
| 121 | * for zero-mapped memory areas etc.. | 118 | * for zero-mapped memory areas etc.. |
| 122 | */ | 119 | */ |
| 123 | extern pte_t __bad_page(void); | ||
| 124 | extern pte_t * __bad_pagetable(void); | ||
| 125 | |||
| 126 | #define BAD_PAGETABLE __bad_pagetable() | ||
| 127 | #define BAD_PAGE __bad_page() | ||
| 128 | 120 | ||
| 129 | #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) | 121 | #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) |
| 130 | 122 | ||
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h index a10ea155907e..1feaaf148ef1 100644 --- a/include/asm-um/thread_info.h +++ b/include/asm-um/thread_info.h | |||
| @@ -41,18 +41,17 @@ struct thread_info { | |||
| 41 | #define init_thread_info (init_thread_union.thread_info) | 41 | #define init_thread_info (init_thread_union.thread_info) |
| 42 | #define init_stack (init_thread_union.stack) | 42 | #define init_stack (init_thread_union.stack) |
| 43 | 43 | ||
| 44 | #define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) | ||
| 44 | /* how to get the thread information struct from C */ | 45 | /* how to get the thread information struct from C */ |
| 45 | static inline struct thread_info *current_thread_info(void) | 46 | static inline struct thread_info *current_thread_info(void) |
| 46 | { | 47 | { |
| 47 | struct thread_info *ti; | 48 | struct thread_info *ti; |
| 48 | unsigned long mask = PAGE_SIZE * | 49 | unsigned long mask = THREAD_SIZE - 1; |
| 49 | (1 << CONFIG_KERNEL_STACK_ORDER) - 1; | 50 | ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); |
| 50 | ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); | ||
| 51 | return ti; | 51 | return ti; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | /* thread information allocation */ | 54 | /* thread information allocation */ |
| 55 | #define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) | ||
| 56 | #define alloc_thread_info(tsk) \ | 55 | #define alloc_thread_info(tsk) \ |
| 57 | ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL)) | 56 | ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL)) |
| 58 | #define free_thread_info(ti) kfree(ti) | 57 | #define free_thread_info(ti) kfree(ti) |
| @@ -62,7 +61,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 62 | 61 | ||
| 63 | #endif | 62 | #endif |
| 64 | 63 | ||
| 65 | #define PREEMPT_ACTIVE 0x4000000 | 64 | #define PREEMPT_ACTIVE 0x10000000 |
| 66 | 65 | ||
| 67 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | 66 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ |
| 68 | #define TIF_SIGPENDING 1 /* signal pending */ | 67 | #define TIF_SIGPENDING 1 /* signal pending */ |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index f21af067d015..927daa86c9b3 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -49,7 +49,7 @@ int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list); | |||
| 49 | /* Frequency values here are CPU kHz so that hardware which doesn't run | 49 | /* Frequency values here are CPU kHz so that hardware which doesn't run |
| 50 | * with some frequencies can complain without having to guess what per | 50 | * with some frequencies can complain without having to guess what per |
| 51 | * cent / per mille means. | 51 | * cent / per mille means. |
| 52 | * Maximum transition latency is in microseconds - if it's unknown, | 52 | * Maximum transition latency is in nanoseconds - if it's unknown, |
| 53 | * CPUFREQ_ETERNAL shall be used. | 53 | * CPUFREQ_ETERNAL shall be used. |
| 54 | */ | 54 | */ |
| 55 | 55 | ||
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 220748b7abea..a1478258d002 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
| @@ -56,18 +56,32 @@ static inline int is_zero_ether_addr(const u8 *addr) | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | * is_multicast_ether_addr - Determine if the given Ethernet address is a | ||
| 60 | * multicast address. | ||
| 61 | * | ||
| 62 | * @addr: Pointer to a six-byte array containing the Ethernet address | ||
| 63 | * | ||
| 64 | * Return true if the address is a multicast address. | ||
| 65 | */ | ||
| 66 | static inline int is_multicast_ether_addr(const u8 *addr) | ||
| 67 | { | ||
| 68 | return addr[0] & 0x01; | ||
| 69 | } | ||
| 70 | |||
| 71 | /** | ||
| 59 | * is_valid_ether_addr - Determine if the given Ethernet address is valid | 72 | * is_valid_ether_addr - Determine if the given Ethernet address is valid |
| 60 | * @addr: Pointer to a six-byte array containing the Ethernet address | 73 | * @addr: Pointer to a six-byte array containing the Ethernet address |
| 61 | * | 74 | * |
| 62 | * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not | 75 | * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not |
| 63 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. The multicast | 76 | * a multicast address, and is not FF:FF:FF:FF:FF:FF. |
| 64 | * and FF:FF:... tests are combined into the single test "!(addr[0]&1)". | ||
| 65 | * | 77 | * |
| 66 | * Return true if the address is valid. | 78 | * Return true if the address is valid. |
| 67 | */ | 79 | */ |
| 68 | static inline int is_valid_ether_addr(const u8 *addr) | 80 | static inline int is_valid_ether_addr(const u8 *addr) |
| 69 | { | 81 | { |
| 70 | return !(addr[0]&1) && !is_zero_ether_addr(addr); | 82 | /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to |
| 83 | * explicitly check for it here. */ | ||
| 84 | return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr); | ||
| 71 | } | 85 | } |
| 72 | 86 | ||
| 73 | /** | 87 | /** |
| @@ -83,6 +97,6 @@ static inline void random_ether_addr(u8 *addr) | |||
| 83 | addr [0] &= 0xfe; /* clear multicast bit */ | 97 | addr [0] &= 0xfe; /* clear multicast bit */ |
| 84 | addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ | 98 | addr [0] |= 0x02; /* set local assignment bit (IEEE802) */ |
| 85 | } | 99 | } |
| 86 | #endif | 100 | #endif /* __KERNEL__ */ |
| 87 | 101 | ||
| 88 | #endif /* _LINUX_ETHERDEVICE_H */ | 102 | #endif /* _LINUX_ETHERDEVICE_H */ |
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c85b210490ea..a0ab26aab450 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
| @@ -256,6 +256,7 @@ struct net_device; | |||
| 256 | u32 ethtool_op_get_link(struct net_device *dev); | 256 | u32 ethtool_op_get_link(struct net_device *dev); |
| 257 | u32 ethtool_op_get_tx_csum(struct net_device *dev); | 257 | u32 ethtool_op_get_tx_csum(struct net_device *dev); |
| 258 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); | 258 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data); |
| 259 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data); | ||
| 259 | u32 ethtool_op_get_sg(struct net_device *dev); | 260 | u32 ethtool_op_get_sg(struct net_device *dev); |
| 260 | int ethtool_op_set_sg(struct net_device *dev, u32 data); | 261 | int ethtool_op_set_sg(struct net_device *dev, u32 data); |
| 261 | u32 ethtool_op_get_tso(struct net_device *dev); | 262 | u32 ethtool_op_get_tso(struct net_device *dev); |
diff --git a/include/linux/gameport.h b/include/linux/gameport.h index b1272f822cfa..cd623eccdbea 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h | |||
| @@ -67,6 +67,8 @@ int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mo | |||
| 67 | void gameport_close(struct gameport *gameport); | 67 | void gameport_close(struct gameport *gameport); |
| 68 | void gameport_rescan(struct gameport *gameport); | 68 | void gameport_rescan(struct gameport *gameport); |
| 69 | 69 | ||
| 70 | #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) | ||
| 71 | |||
| 70 | void __gameport_register_port(struct gameport *gameport, struct module *owner); | 72 | void __gameport_register_port(struct gameport *gameport, struct module *owner); |
| 71 | static inline void gameport_register_port(struct gameport *gameport) | 73 | static inline void gameport_register_port(struct gameport *gameport) |
| 72 | { | 74 | { |
| @@ -75,6 +77,29 @@ static inline void gameport_register_port(struct gameport *gameport) | |||
| 75 | 77 | ||
| 76 | void gameport_unregister_port(struct gameport *gameport); | 78 | void gameport_unregister_port(struct gameport *gameport); |
| 77 | 79 | ||
| 80 | void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) | ||
| 81 | __attribute__ ((format (printf, 2, 3))); | ||
| 82 | |||
| 83 | #else | ||
| 84 | |||
| 85 | static inline void gameport_register_port(struct gameport *gameport) | ||
| 86 | { | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | static inline void gameport_unregister_port(struct gameport *gameport) | ||
| 91 | { | ||
| 92 | return; | ||
| 93 | } | ||
| 94 | |||
| 95 | static inline void gameport_set_phys(struct gameport *gameport, | ||
| 96 | const char *fmt, ...) | ||
| 97 | { | ||
| 98 | return; | ||
| 99 | } | ||
| 100 | |||
| 101 | #endif | ||
| 102 | |||
| 78 | static inline struct gameport *gameport_allocate_port(void) | 103 | static inline struct gameport *gameport_allocate_port(void) |
| 79 | { | 104 | { |
| 80 | struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); | 105 | struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); |
| @@ -92,9 +117,6 @@ static inline void gameport_set_name(struct gameport *gameport, const char *name | |||
| 92 | strlcpy(gameport->name, name, sizeof(gameport->name)); | 117 | strlcpy(gameport->name, name, sizeof(gameport->name)); |
| 93 | } | 118 | } |
| 94 | 119 | ||
| 95 | void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) | ||
| 96 | __attribute__ ((format (printf, 2, 3))); | ||
| 97 | |||
| 98 | /* | 120 | /* |
| 99 | * Use the following fucntions to manipulate gameport's per-port | 121 | * Use the following fucntions to manipulate gameport's per-port |
| 100 | * driver-specific data. | 122 | * driver-specific data. |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index ebc712e91066..8336dba18971 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
| @@ -43,13 +43,17 @@ | |||
| 43 | #define __IRQ_MASK(x) ((1UL << (x))-1) | 43 | #define __IRQ_MASK(x) ((1UL << (x))-1) |
| 44 | 44 | ||
| 45 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) | 45 | #define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT) |
| 46 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) | ||
| 47 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | 46 | #define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) |
| 47 | #define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT) | ||
| 48 | 48 | ||
| 49 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) | 49 | #define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT) |
| 50 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) | 50 | #define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT) |
| 51 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) | 51 | #define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT) |
| 52 | 52 | ||
| 53 | #if PREEMPT_ACTIVE < (1 << (HARDIRQ_SHIFT + HARDIRQ_BITS)) | ||
| 54 | #error PREEMPT_ACTIVE is too low! | ||
| 55 | #endif | ||
| 56 | |||
| 53 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) | 57 | #define hardirq_count() (preempt_count() & HARDIRQ_MASK) |
| 54 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) | 58 | #define softirq_count() (preempt_count() & SOFTIRQ_MASK) |
| 55 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) | 59 | #define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK)) |
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 6fafb27877a7..7e1e15f934f3 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h | |||
| @@ -29,6 +29,7 @@ struct ipv4_devconf | |||
| 29 | int no_xfrm; | 29 | int no_xfrm; |
| 30 | int no_policy; | 30 | int no_policy; |
| 31 | int force_igmp_version; | 31 | int force_igmp_version; |
| 32 | int promote_secondaries; | ||
| 32 | void *sysctl; | 33 | void *sysctl; |
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| @@ -71,6 +72,7 @@ struct in_device | |||
| 71 | #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) | 72 | #define IN_DEV_SEC_REDIRECTS(in_dev) (ipv4_devconf.secure_redirects || (in_dev)->cnf.secure_redirects) |
| 72 | #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) | 73 | #define IN_DEV_IDTAG(in_dev) ((in_dev)->cnf.tag) |
| 73 | #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) | 74 | #define IN_DEV_MEDIUM_ID(in_dev) ((in_dev)->cnf.medium_id) |
| 75 | #define IN_DEV_PROMOTE_SECONDARIES(in_dev) (ipv4_devconf.promote_secondaries || (in_dev)->cnf.promote_secondaries) | ||
| 74 | 76 | ||
| 75 | #define IN_DEV_RX_REDIRECTS(in_dev) \ | 77 | #define IN_DEV_RX_REDIRECTS(in_dev) \ |
| 76 | ((IN_DEV_FORWARD(in_dev) && \ | 78 | ((IN_DEV_FORWARD(in_dev) && \ |
diff --git a/include/linux/libata.h b/include/linux/libata.h index ad410590664f..b009f801e7c5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -410,6 +410,7 @@ extern u8 ata_chk_err(struct ata_port *ap); | |||
| 410 | extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); | 410 | extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf); |
| 411 | extern int ata_port_start (struct ata_port *ap); | 411 | extern int ata_port_start (struct ata_port *ap); |
| 412 | extern void ata_port_stop (struct ata_port *ap); | 412 | extern void ata_port_stop (struct ata_port *ap); |
| 413 | extern void ata_host_stop (struct ata_host_set *host_set); | ||
| 413 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 414 | extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
| 414 | extern void ata_qc_prep(struct ata_queued_cmd *qc); | 415 | extern void ata_qc_prep(struct ata_queued_cmd *qc); |
| 415 | extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); | 416 | extern int ata_qc_issue_prot(struct ata_queued_cmd *qc); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b25bd02720d3..470af8c1a4a0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -401,7 +401,7 @@ struct net_device | |||
| 401 | } reg_state; | 401 | } reg_state; |
| 402 | 402 | ||
| 403 | /* Net device features */ | 403 | /* Net device features */ |
| 404 | int features; | 404 | unsigned long features; |
| 405 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ | 405 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ |
| 406 | #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ | 406 | #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ |
| 407 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ | 407 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ |
| @@ -913,6 +913,7 @@ extern void dev_mc_discard(struct net_device *dev); | |||
| 913 | extern void dev_set_promiscuity(struct net_device *dev, int inc); | 913 | extern void dev_set_promiscuity(struct net_device *dev, int inc); |
| 914 | extern void dev_set_allmulti(struct net_device *dev, int inc); | 914 | extern void dev_set_allmulti(struct net_device *dev, int inc); |
| 915 | extern void netdev_state_change(struct net_device *dev); | 915 | extern void netdev_state_change(struct net_device *dev); |
| 916 | extern void netdev_features_change(struct net_device *dev); | ||
| 916 | /* Load a device via the kmod */ | 917 | /* Load a device via the kmod */ |
| 917 | extern void dev_load(const char *name); | 918 | extern void dev_load(const char *name); |
| 918 | extern void dev_mcast_init(void); | 919 | extern void dev_mcast_init(void); |
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 9303a003e9ab..5937dd6053c3 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h | |||
| @@ -56,6 +56,7 @@ extern int notifier_call_chain(struct notifier_block **n, unsigned long val, voi | |||
| 56 | #define NETDEV_CHANGEADDR 0x0008 | 56 | #define NETDEV_CHANGEADDR 0x0008 |
| 57 | #define NETDEV_GOING_DOWN 0x0009 | 57 | #define NETDEV_GOING_DOWN 0x0009 |
| 58 | #define NETDEV_CHANGENAME 0x000A | 58 | #define NETDEV_CHANGENAME 0x000A |
| 59 | #define NETDEV_FEAT_CHANGE 0x000B | ||
| 59 | 60 | ||
| 60 | #define SYS_DOWN 0x0001 /* Notify of system down */ | 61 | #define SYS_DOWN 0x0001 /* Notify of system down */ |
| 61 | #define SYS_RESTART SYS_DOWN | 62 | #define SYS_RESTART SYS_DOWN |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 7ccbc2e4272c..b0d6134e1ee6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -1230,6 +1230,12 @@ | |||
| 1230 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 | 1230 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 |
| 1231 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 | 1231 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 |
| 1232 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B | 1232 | #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B |
| 1233 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 | ||
| 1234 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 | ||
| 1235 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 | ||
| 1236 | #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 | ||
| 1237 | #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 | ||
| 1238 | #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B | ||
| 1233 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 | 1239 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 |
| 1234 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 | 1240 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 |
| 1235 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 | 1241 | #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 772998147e3e..23032d9d6071 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
| @@ -399,6 +399,7 @@ enum | |||
| 399 | NET_IPV4_CONF_FORCE_IGMP_VERSION=17, | 399 | NET_IPV4_CONF_FORCE_IGMP_VERSION=17, |
| 400 | NET_IPV4_CONF_ARP_ANNOUNCE=18, | 400 | NET_IPV4_CONF_ARP_ANNOUNCE=18, |
| 401 | NET_IPV4_CONF_ARP_IGNORE=19, | 401 | NET_IPV4_CONF_ARP_IGNORE=19, |
| 402 | NET_IPV4_CONF_PROMOTE_SECONDARIES=20, | ||
| 402 | __NET_IPV4_CONF_MAX | 403 | __NET_IPV4_CONF_MAX |
| 403 | }; | 404 | }; |
| 404 | 405 | ||
diff --git a/include/net/route.h b/include/net/route.h index efe92b239ef1..d34ca8fc6756 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
| @@ -181,9 +181,6 @@ static inline int ip_route_newports(struct rtable **rp, u16 sport, u16 dport, | |||
| 181 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); | 181 | memcpy(&fl, &(*rp)->fl, sizeof(fl)); |
| 182 | fl.fl_ip_sport = sport; | 182 | fl.fl_ip_sport = sport; |
| 183 | fl.fl_ip_dport = dport; | 183 | fl.fl_ip_dport = dport; |
| 184 | #if defined(CONFIG_IP_ROUTE_MULTIPATH_CACHED) | ||
| 185 | fl.flags |= FLOWI_FLAG_MULTIPATHOLDROUTE; | ||
| 186 | #endif | ||
| 187 | ip_rt_put(*rp); | 184 | ip_rt_put(*rp); |
| 188 | *rp = NULL; | 185 | *rp = NULL; |
| 189 | return ip_route_output_flow(rp, &fl, sk, 0); | 186 | return ip_route_output_flow(rp, &fl, sk, 0); |
diff --git a/init/Kconfig b/init/Kconfig index d920baed109a..a7660ccc693f 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
| @@ -442,7 +442,7 @@ config OBSOLETE_MODPARM | |||
| 442 | 442 | ||
| 443 | config MODVERSIONS | 443 | config MODVERSIONS |
| 444 | bool "Module versioning support (EXPERIMENTAL)" | 444 | bool "Module versioning support (EXPERIMENTAL)" |
| 445 | depends on MODULES && EXPERIMENTAL && !UML | 445 | depends on MODULES && EXPERIMENTAL |
| 446 | help | 446 | help |
| 447 | Usually, you have to use modules compiled with your kernel. | 447 | Usually, you have to use modules compiled with your kernel. |
| 448 | Saying Y here makes it sometimes possible to use modules | 448 | Saying Y here makes it sometimes possible to use modules |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 06b5a6323998..436c7d93c00a 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
| @@ -119,8 +119,6 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
| 119 | */ | 119 | */ |
| 120 | desc->handler->ack(irq); | 120 | desc->handler->ack(irq); |
| 121 | action_ret = handle_IRQ_event(irq, regs, desc->action); | 121 | action_ret = handle_IRQ_event(irq, regs, desc->action); |
| 122 | if (!noirqdebug) | ||
| 123 | note_interrupt(irq, desc, action_ret); | ||
| 124 | desc->handler->end(irq); | 122 | desc->handler->end(irq); |
| 125 | return 1; | 123 | return 1; |
| 126 | } | 124 | } |
diff --git a/kernel/module.c b/kernel/module.c index 5734ab09d3f9..83b3d376708c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -1758,6 +1758,7 @@ sys_init_module(void __user *umod, | |||
| 1758 | const char __user *uargs) | 1758 | const char __user *uargs) |
| 1759 | { | 1759 | { |
| 1760 | struct module *mod; | 1760 | struct module *mod; |
| 1761 | mm_segment_t old_fs = get_fs(); | ||
| 1761 | int ret = 0; | 1762 | int ret = 0; |
| 1762 | 1763 | ||
| 1763 | /* Must have permission */ | 1764 | /* Must have permission */ |
| @@ -1775,6 +1776,9 @@ sys_init_module(void __user *umod, | |||
| 1775 | return PTR_ERR(mod); | 1776 | return PTR_ERR(mod); |
| 1776 | } | 1777 | } |
| 1777 | 1778 | ||
| 1779 | /* flush the icache in correct context */ | ||
| 1780 | set_fs(KERNEL_DS); | ||
| 1781 | |||
| 1778 | /* Flush the instruction cache, since we've played with text */ | 1782 | /* Flush the instruction cache, since we've played with text */ |
| 1779 | if (mod->module_init) | 1783 | if (mod->module_init) |
| 1780 | flush_icache_range((unsigned long)mod->module_init, | 1784 | flush_icache_range((unsigned long)mod->module_init, |
| @@ -1783,6 +1787,8 @@ sys_init_module(void __user *umod, | |||
| 1783 | flush_icache_range((unsigned long)mod->module_core, | 1787 | flush_icache_range((unsigned long)mod->module_core, |
| 1784 | (unsigned long)mod->module_core + mod->core_size); | 1788 | (unsigned long)mod->module_core + mod->core_size); |
| 1785 | 1789 | ||
| 1790 | set_fs(old_fs); | ||
| 1791 | |||
| 1786 | /* Now sew it into the lists. They won't access us, since | 1792 | /* Now sew it into the lists. They won't access us, since |
| 1787 | strong_try_module_get() will fail. */ | 1793 | strong_try_module_get() will fail. */ |
| 1788 | stop_machine_run(__link_module, mod, NR_CPUS); | 1794 | stop_machine_run(__link_module, mod, NR_CPUS); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index ac23847ce0e3..0c421295e613 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -151,7 +151,8 @@ config DEBUG_FS | |||
| 151 | 151 | ||
| 152 | config FRAME_POINTER | 152 | config FRAME_POINTER |
| 153 | bool "Compile the kernel with frame pointers" | 153 | bool "Compile the kernel with frame pointers" |
| 154 | depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV) | 154 | depends on DEBUG_KERNEL && ((X86 && !X86_64) || CRIS || M68K || M68KNOMMU || FRV || UML) |
| 155 | default y if DEBUG_INFO && UML | ||
| 155 | help | 156 | help |
| 156 | If you say Y here the resulting kernel image will be slightly larger | 157 | If you say Y here the resulting kernel image will be slightly larger |
| 157 | and slower, but it will give very useful debugging information. | 158 | and slower, but it will give very useful debugging information. |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index d9b72fde433c..f564ee99782d 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
| @@ -21,10 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | static struct net_device_stats *br_dev_get_stats(struct net_device *dev) | 22 | static struct net_device_stats *br_dev_get_stats(struct net_device *dev) |
| 23 | { | 23 | { |
| 24 | struct net_bridge *br; | 24 | struct net_bridge *br = netdev_priv(dev); |
| 25 | |||
| 26 | br = dev->priv; | ||
| 27 | |||
| 28 | return &br->statistics; | 25 | return &br->statistics; |
| 29 | } | 26 | } |
| 30 | 27 | ||
| @@ -54,9 +51,11 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 54 | 51 | ||
| 55 | static int br_dev_open(struct net_device *dev) | 52 | static int br_dev_open(struct net_device *dev) |
| 56 | { | 53 | { |
| 57 | netif_start_queue(dev); | 54 | struct net_bridge *br = netdev_priv(dev); |
| 58 | 55 | ||
| 59 | br_stp_enable_bridge(dev->priv); | 56 | br_features_recompute(br); |
| 57 | netif_start_queue(dev); | ||
| 58 | br_stp_enable_bridge(br); | ||
| 60 | 59 | ||
| 61 | return 0; | 60 | return 0; |
| 62 | } | 61 | } |
| @@ -67,7 +66,7 @@ static void br_dev_set_multicast_list(struct net_device *dev) | |||
| 67 | 66 | ||
| 68 | static int br_dev_stop(struct net_device *dev) | 67 | static int br_dev_stop(struct net_device *dev) |
| 69 | { | 68 | { |
| 70 | br_stp_disable_bridge(dev->priv); | 69 | br_stp_disable_bridge(netdev_priv(dev)); |
| 71 | 70 | ||
| 72 | netif_stop_queue(dev); | 71 | netif_stop_queue(dev); |
| 73 | 72 | ||
| @@ -76,7 +75,7 @@ static int br_dev_stop(struct net_device *dev) | |||
| 76 | 75 | ||
| 77 | static int br_change_mtu(struct net_device *dev, int new_mtu) | 76 | static int br_change_mtu(struct net_device *dev, int new_mtu) |
| 78 | { | 77 | { |
| 79 | if ((new_mtu < 68) || new_mtu > br_min_mtu(dev->priv)) | 78 | if (new_mtu < 68 || new_mtu > br_min_mtu(netdev_priv(dev))) |
| 80 | return -EINVAL; | 79 | return -EINVAL; |
| 81 | 80 | ||
| 82 | dev->mtu = new_mtu; | 81 | dev->mtu = new_mtu; |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 69872bf3b87e..91bb895375f4 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -314,6 +314,28 @@ int br_min_mtu(const struct net_bridge *br) | |||
| 314 | return mtu; | 314 | return mtu; |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | /* | ||
| 318 | * Recomputes features using slave's features | ||
| 319 | */ | ||
| 320 | void br_features_recompute(struct net_bridge *br) | ||
| 321 | { | ||
| 322 | struct net_bridge_port *p; | ||
| 323 | unsigned long features, checksum; | ||
| 324 | |||
| 325 | features = NETIF_F_SG | NETIF_F_FRAGLIST | ||
| 326 | | NETIF_F_HIGHDMA | NETIF_F_TSO; | ||
| 327 | checksum = NETIF_F_IP_CSUM; /* least commmon subset */ | ||
| 328 | |||
| 329 | list_for_each_entry(p, &br->port_list, list) { | ||
| 330 | if (!(p->dev->features | ||
| 331 | & (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM))) | ||
| 332 | checksum = 0; | ||
| 333 | features &= p->dev->features; | ||
| 334 | } | ||
| 335 | |||
| 336 | br->dev->features = features | checksum | NETIF_F_LLTX; | ||
| 337 | } | ||
| 338 | |||
| 317 | /* called with RTNL */ | 339 | /* called with RTNL */ |
| 318 | int br_add_if(struct net_bridge *br, struct net_device *dev) | 340 | int br_add_if(struct net_bridge *br, struct net_device *dev) |
| 319 | { | 341 | { |
| @@ -368,6 +390,7 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 368 | 390 | ||
| 369 | spin_lock_bh(&br->lock); | 391 | spin_lock_bh(&br->lock); |
| 370 | br_stp_recalculate_bridge_id(br); | 392 | br_stp_recalculate_bridge_id(br); |
| 393 | br_features_recompute(br); | ||
| 371 | spin_unlock_bh(&br->lock); | 394 | spin_unlock_bh(&br->lock); |
| 372 | 395 | ||
| 373 | return 0; | 396 | return 0; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 2b1cce46cab4..8f5f2e730992 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -26,7 +26,7 @@ static int br_pass_frame_up_finish(struct sk_buff *skb) | |||
| 26 | #ifdef CONFIG_NETFILTER_DEBUG | 26 | #ifdef CONFIG_NETFILTER_DEBUG |
| 27 | skb->nf_debug = 0; | 27 | skb->nf_debug = 0; |
| 28 | #endif | 28 | #endif |
| 29 | netif_rx(skb); | 29 | netif_receive_skb(skb); |
| 30 | 30 | ||
| 31 | return 0; | 31 | return 0; |
| 32 | } | 32 | } |
| @@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
| 54 | struct net_bridge_fdb_entry *dst; | 54 | struct net_bridge_fdb_entry *dst; |
| 55 | int passedup = 0; | 55 | int passedup = 0; |
| 56 | 56 | ||
| 57 | /* insert into forwarding database after filtering to avoid spoofing */ | ||
| 58 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | ||
| 59 | |||
| 57 | if (br->dev->flags & IFF_PROMISC) { | 60 | if (br->dev->flags & IFF_PROMISC) { |
| 58 | struct sk_buff *skb2; | 61 | struct sk_buff *skb2; |
| 59 | 62 | ||
| @@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) | |||
| 108 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) | 111 | if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) |
| 109 | goto err; | 112 | goto err; |
| 110 | 113 | ||
| 111 | if (p->state == BR_STATE_LEARNING || | 114 | if (p->state == BR_STATE_LEARNING) |
| 112 | p->state == BR_STATE_FORWARDING) | ||
| 113 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | 115 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); |
| 114 | 116 | ||
| 115 | if (p->br->stp_enabled && | 117 | if (p->br->stp_enabled && |
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index f8fb49e34764..917311c6828b 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
| @@ -65,6 +65,15 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
| 65 | } | 65 | } |
| 66 | break; | 66 | break; |
| 67 | 67 | ||
| 68 | case NETDEV_FEAT_CHANGE: | ||
| 69 | if (br->dev->flags & IFF_UP) | ||
| 70 | br_features_recompute(br); | ||
| 71 | |||
| 72 | /* could do recursive feature change notification | ||
| 73 | * but who would care?? | ||
| 74 | */ | ||
| 75 | break; | ||
| 76 | |||
| 68 | case NETDEV_DOWN: | 77 | case NETDEV_DOWN: |
| 69 | if (br->dev->flags & IFF_UP) | 78 | if (br->dev->flags & IFF_UP) |
| 70 | br_stp_disable_port(p); | 79 | br_stp_disable_port(p); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 54d63f1372a0..bdf95a74d8cd 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -174,6 +174,7 @@ extern int br_add_if(struct net_bridge *br, | |||
| 174 | extern int br_del_if(struct net_bridge *br, | 174 | extern int br_del_if(struct net_bridge *br, |
| 175 | struct net_device *dev); | 175 | struct net_device *dev); |
| 176 | extern int br_min_mtu(const struct net_bridge *br); | 176 | extern int br_min_mtu(const struct net_bridge *br); |
| 177 | extern void br_features_recompute(struct net_bridge *br); | ||
| 177 | 178 | ||
| 178 | /* br_input.c */ | 179 | /* br_input.c */ |
| 179 | extern int br_handle_frame_finish(struct sk_buff *skb); | 180 | extern int br_handle_frame_finish(struct sk_buff *skb); |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index b91a875aca01..d071f1c9ad0b 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
| @@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *skb) | |||
| 140 | struct net_bridge *br = p->br; | 140 | struct net_bridge *br = p->br; |
| 141 | unsigned char *buf; | 141 | unsigned char *buf; |
| 142 | 142 | ||
| 143 | /* insert into forwarding database after filtering to avoid spoofing */ | ||
| 144 | br_fdb_update(p->br, p, eth_hdr(skb)->h_source); | ||
| 145 | |||
| 143 | /* need at least the 802 and STP headers */ | 146 | /* need at least the 802 and STP headers */ |
| 144 | if (!pskb_may_pull(skb, sizeof(header)+1) || | 147 | if (!pskb_may_pull(skb, sizeof(header)+1) || |
| 145 | memcmp(skb->data, header, sizeof(header))) | 148 | memcmp(skb->data, header, sizeof(header))) |
diff --git a/net/core/dev.c b/net/core/dev.c index d4d9e2680adb..f15a3ffff635 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -761,6 +761,18 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
| 761 | } | 761 | } |
| 762 | 762 | ||
| 763 | /** | 763 | /** |
| 764 | * netdev_features_change - device changes fatures | ||
| 765 | * @dev: device to cause notification | ||
| 766 | * | ||
| 767 | * Called to indicate a device has changed features. | ||
| 768 | */ | ||
| 769 | void netdev_features_change(struct net_device *dev) | ||
| 770 | { | ||
| 771 | notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); | ||
| 772 | } | ||
| 773 | EXPORT_SYMBOL(netdev_features_change); | ||
| 774 | |||
| 775 | /** | ||
| 764 | * netdev_state_change - device changes state | 776 | * netdev_state_change - device changes state |
| 765 | * @dev: device to cause notification | 777 | * @dev: device to cause notification |
| 766 | * | 778 | * |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f05fde97c43d..8ec484894d68 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -29,7 +29,7 @@ u32 ethtool_op_get_link(struct net_device *dev) | |||
| 29 | 29 | ||
| 30 | u32 ethtool_op_get_tx_csum(struct net_device *dev) | 30 | u32 ethtool_op_get_tx_csum(struct net_device *dev) |
| 31 | { | 31 | { |
| 32 | return (dev->features & NETIF_F_IP_CSUM) != 0; | 32 | return (dev->features & (NETIF_F_IP_CSUM | NETIF_F_HW_CSUM)) != 0; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | 35 | int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) |
| @@ -42,6 +42,15 @@ int ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
| 42 | return 0; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | int ethtool_op_set_tx_hw_csum(struct net_device *dev, u32 data) | ||
| 46 | { | ||
| 47 | if (data) | ||
| 48 | dev->features |= NETIF_F_HW_CSUM; | ||
| 49 | else | ||
| 50 | dev->features &= ~NETIF_F_HW_CSUM; | ||
| 51 | |||
| 52 | return 0; | ||
| 53 | } | ||
| 45 | u32 ethtool_op_get_sg(struct net_device *dev) | 54 | u32 ethtool_op_get_sg(struct net_device *dev) |
| 46 | { | 55 | { |
| 47 | return (dev->features & NETIF_F_SG) != 0; | 56 | return (dev->features & NETIF_F_SG) != 0; |
| @@ -682,6 +691,7 @@ int dev_ethtool(struct ifreq *ifr) | |||
| 682 | void __user *useraddr = ifr->ifr_data; | 691 | void __user *useraddr = ifr->ifr_data; |
| 683 | u32 ethcmd; | 692 | u32 ethcmd; |
| 684 | int rc; | 693 | int rc; |
| 694 | unsigned long old_features; | ||
| 685 | 695 | ||
| 686 | /* | 696 | /* |
| 687 | * XXX: This can be pushed down into the ethtool_* handlers that | 697 | * XXX: This can be pushed down into the ethtool_* handlers that |
| @@ -703,6 +713,8 @@ int dev_ethtool(struct ifreq *ifr) | |||
| 703 | if ((rc = dev->ethtool_ops->begin(dev)) < 0) | 713 | if ((rc = dev->ethtool_ops->begin(dev)) < 0) |
| 704 | return rc; | 714 | return rc; |
| 705 | 715 | ||
| 716 | old_features = dev->features; | ||
| 717 | |||
| 706 | switch (ethcmd) { | 718 | switch (ethcmd) { |
| 707 | case ETHTOOL_GSET: | 719 | case ETHTOOL_GSET: |
| 708 | rc = ethtool_get_settings(dev, useraddr); | 720 | rc = ethtool_get_settings(dev, useraddr); |
| @@ -712,7 +724,6 @@ int dev_ethtool(struct ifreq *ifr) | |||
| 712 | break; | 724 | break; |
| 713 | case ETHTOOL_GDRVINFO: | 725 | case ETHTOOL_GDRVINFO: |
| 714 | rc = ethtool_get_drvinfo(dev, useraddr); | 726 | rc = ethtool_get_drvinfo(dev, useraddr); |
| 715 | |||
| 716 | break; | 727 | break; |
| 717 | case ETHTOOL_GREGS: | 728 | case ETHTOOL_GREGS: |
| 718 | rc = ethtool_get_regs(dev, useraddr); | 729 | rc = ethtool_get_regs(dev, useraddr); |
| @@ -801,6 +812,10 @@ int dev_ethtool(struct ifreq *ifr) | |||
| 801 | 812 | ||
| 802 | if(dev->ethtool_ops->complete) | 813 | if(dev->ethtool_ops->complete) |
| 803 | dev->ethtool_ops->complete(dev); | 814 | dev->ethtool_ops->complete(dev); |
| 815 | |||
| 816 | if (old_features != dev->features) | ||
| 817 | netdev_features_change(dev); | ||
| 818 | |||
| 804 | return rc; | 819 | return rc; |
| 805 | 820 | ||
| 806 | ioctl: | 821 | ioctl: |
| @@ -817,3 +832,4 @@ EXPORT_SYMBOL(ethtool_op_get_tx_csum); | |||
| 817 | EXPORT_SYMBOL(ethtool_op_set_sg); | 832 | EXPORT_SYMBOL(ethtool_op_set_sg); |
| 818 | EXPORT_SYMBOL(ethtool_op_set_tso); | 833 | EXPORT_SYMBOL(ethtool_op_set_tso); |
| 819 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); | 834 | EXPORT_SYMBOL(ethtool_op_set_tx_csum); |
| 835 | EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum); | ||
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 060f703659e8..910eb4c05a47 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #define to_net_dev(class) container_of(class, struct net_device, class_dev) | 21 | #define to_net_dev(class) container_of(class, struct net_device, class_dev) |
| 22 | 22 | ||
| 23 | static const char fmt_hex[] = "%#x\n"; | 23 | static const char fmt_hex[] = "%#x\n"; |
| 24 | static const char fmt_long_hex[] = "%#lx\n"; | ||
| 24 | static const char fmt_dec[] = "%d\n"; | 25 | static const char fmt_dec[] = "%d\n"; |
| 25 | static const char fmt_ulong[] = "%lu\n"; | 26 | static const char fmt_ulong[] = "%lu\n"; |
| 26 | 27 | ||
| @@ -91,7 +92,7 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \ | |||
| 91 | NETDEVICE_ATTR(addr_len, fmt_dec); | 92 | NETDEVICE_ATTR(addr_len, fmt_dec); |
| 92 | NETDEVICE_ATTR(iflink, fmt_dec); | 93 | NETDEVICE_ATTR(iflink, fmt_dec); |
| 93 | NETDEVICE_ATTR(ifindex, fmt_dec); | 94 | NETDEVICE_ATTR(ifindex, fmt_dec); |
| 94 | NETDEVICE_ATTR(features, fmt_hex); | 95 | NETDEVICE_ATTR(features, fmt_long_hex); |
| 95 | NETDEVICE_ATTR(type, fmt_dec); | 96 | NETDEVICE_ATTR(type, fmt_dec); |
| 96 | 97 | ||
| 97 | /* use same locking rules as GIFHWADDR ioctl's */ | 98 | /* use same locking rules as GIFHWADDR ioctl's */ |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 3cc96730c4ed..478a30179a52 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
| @@ -233,11 +233,14 @@ int inet_addr_onlink(struct in_device *in_dev, u32 a, u32 b) | |||
| 233 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 233 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, |
| 234 | int destroy) | 234 | int destroy) |
| 235 | { | 235 | { |
| 236 | struct in_ifaddr *promote = NULL; | ||
| 236 | struct in_ifaddr *ifa1 = *ifap; | 237 | struct in_ifaddr *ifa1 = *ifap; |
| 237 | 238 | ||
| 238 | ASSERT_RTNL(); | 239 | ASSERT_RTNL(); |
| 239 | 240 | ||
| 240 | /* 1. Deleting primary ifaddr forces deletion all secondaries */ | 241 | /* 1. Deleting primary ifaddr forces deletion all secondaries |
| 242 | * unless alias promotion is set | ||
| 243 | **/ | ||
| 241 | 244 | ||
| 242 | if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { | 245 | if (!(ifa1->ifa_flags & IFA_F_SECONDARY)) { |
| 243 | struct in_ifaddr *ifa; | 246 | struct in_ifaddr *ifa; |
| @@ -251,11 +254,16 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
| 251 | continue; | 254 | continue; |
| 252 | } | 255 | } |
| 253 | 256 | ||
| 254 | *ifap1 = ifa->ifa_next; | 257 | if (!IN_DEV_PROMOTE_SECONDARIES(in_dev)) { |
| 258 | *ifap1 = ifa->ifa_next; | ||
| 255 | 259 | ||
| 256 | rtmsg_ifa(RTM_DELADDR, ifa); | 260 | rtmsg_ifa(RTM_DELADDR, ifa); |
| 257 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); | 261 | notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); |
| 258 | inet_free_ifa(ifa); | 262 | inet_free_ifa(ifa); |
| 263 | } else { | ||
| 264 | promote = ifa; | ||
| 265 | break; | ||
| 266 | } | ||
| 259 | } | 267 | } |
| 260 | } | 268 | } |
| 261 | 269 | ||
| @@ -281,6 +289,13 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
| 281 | if (!in_dev->ifa_list) | 289 | if (!in_dev->ifa_list) |
| 282 | inetdev_destroy(in_dev); | 290 | inetdev_destroy(in_dev); |
| 283 | } | 291 | } |
| 292 | |||
| 293 | if (promote && IN_DEV_PROMOTE_SECONDARIES(in_dev)) { | ||
| 294 | /* not sure if we should send a delete notify first? */ | ||
| 295 | promote->ifa_flags &= ~IFA_F_SECONDARY; | ||
| 296 | rtmsg_ifa(RTM_NEWADDR, promote); | ||
| 297 | notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); | ||
| 298 | } | ||
| 284 | } | 299 | } |
| 285 | 300 | ||
| 286 | static int inet_insert_ifa(struct in_ifaddr *ifa) | 301 | static int inet_insert_ifa(struct in_ifaddr *ifa) |
| @@ -1384,6 +1399,15 @@ static struct devinet_sysctl_table { | |||
| 1384 | .proc_handler = &ipv4_doint_and_flush, | 1399 | .proc_handler = &ipv4_doint_and_flush, |
| 1385 | .strategy = &ipv4_doint_and_flush_strategy, | 1400 | .strategy = &ipv4_doint_and_flush_strategy, |
| 1386 | }, | 1401 | }, |
| 1402 | { | ||
| 1403 | .ctl_name = NET_IPV4_CONF_PROMOTE_SECONDARIES, | ||
| 1404 | .procname = "promote_secondaries", | ||
| 1405 | .data = &ipv4_devconf.promote_secondaries, | ||
| 1406 | .maxlen = sizeof(int), | ||
| 1407 | .mode = 0644, | ||
| 1408 | .proc_handler = &ipv4_doint_and_flush, | ||
| 1409 | .strategy = &ipv4_doint_and_flush_strategy, | ||
| 1410 | }, | ||
| 1387 | }, | 1411 | }, |
| 1388 | .devinet_dev = { | 1412 | .devinet_dev = { |
| 1389 | { | 1413 | { |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 053a883247ba..eae84cc39d3f 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
| @@ -478,7 +478,7 @@ static int __init esp4_init(void) | |||
| 478 | { | 478 | { |
| 479 | struct xfrm_decap_state decap; | 479 | struct xfrm_decap_state decap; |
| 480 | 480 | ||
| 481 | if (sizeof(struct esp_decap_data) < | 481 | if (sizeof(struct esp_decap_data) > |
| 482 | sizeof(decap.decap_data)) { | 482 | sizeof(decap.decap_data)) { |
| 483 | extern void decap_data_too_small(void); | 483 | extern void decap_data_too_small(void); |
| 484 | 484 | ||
diff --git a/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c index 9349686131fc..cf2e6bcf7973 100644 --- a/net/ipv4/multipath_drr.c +++ b/net/ipv4/multipath_drr.c | |||
| @@ -57,7 +57,6 @@ struct multipath_device { | |||
| 57 | 57 | ||
| 58 | static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES]; | 58 | static struct multipath_device state[MULTIPATH_MAX_DEVICECANDIDATES]; |
| 59 | static DEFINE_SPINLOCK(state_lock); | 59 | static DEFINE_SPINLOCK(state_lock); |
| 60 | static struct rtable *last_selection = NULL; | ||
| 61 | 60 | ||
| 62 | static int inline __multipath_findslot(void) | 61 | static int inline __multipath_findslot(void) |
| 63 | { | 62 | { |
| @@ -111,11 +110,6 @@ struct notifier_block drr_dev_notifier = { | |||
| 111 | .notifier_call = drr_dev_event, | 110 | .notifier_call = drr_dev_event, |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | static void drr_remove(struct rtable *rt) | ||
| 115 | { | ||
| 116 | if (last_selection == rt) | ||
| 117 | last_selection = NULL; | ||
| 118 | } | ||
| 119 | 113 | ||
| 120 | static void drr_safe_inc(atomic_t *usecount) | 114 | static void drr_safe_inc(atomic_t *usecount) |
| 121 | { | 115 | { |
| @@ -144,14 +138,6 @@ static void drr_select_route(const struct flowi *flp, | |||
| 144 | int devidx = -1; | 138 | int devidx = -1; |
| 145 | int cur_min_devidx = -1; | 139 | int cur_min_devidx = -1; |
| 146 | 140 | ||
| 147 | /* if necessary and possible utilize the old alternative */ | ||
| 148 | if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 && | ||
| 149 | last_selection != NULL) { | ||
| 150 | result = last_selection; | ||
| 151 | *rp = result; | ||
| 152 | return; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* 1. make sure all alt. nexthops have the same GC related data */ | 141 | /* 1. make sure all alt. nexthops have the same GC related data */ |
| 156 | /* 2. determine the new candidate to be returned */ | 142 | /* 2. determine the new candidate to be returned */ |
| 157 | result = NULL; | 143 | result = NULL; |
| @@ -229,12 +215,10 @@ static void drr_select_route(const struct flowi *flp, | |||
| 229 | } | 215 | } |
| 230 | 216 | ||
| 231 | *rp = result; | 217 | *rp = result; |
| 232 | last_selection = result; | ||
| 233 | } | 218 | } |
| 234 | 219 | ||
| 235 | static struct ip_mp_alg_ops drr_ops = { | 220 | static struct ip_mp_alg_ops drr_ops = { |
| 236 | .mp_alg_select_route = drr_select_route, | 221 | .mp_alg_select_route = drr_select_route, |
| 237 | .mp_alg_remove = drr_remove, | ||
| 238 | }; | 222 | }; |
| 239 | 223 | ||
| 240 | static int __init drr_init(void) | 224 | static int __init drr_init(void) |
| @@ -244,7 +228,7 @@ static int __init drr_init(void) | |||
| 244 | if (err) | 228 | if (err) |
| 245 | return err; | 229 | return err; |
| 246 | 230 | ||
| 247 | err = multipath_alg_register(&drr_ops, IP_MP_ALG_RR); | 231 | err = multipath_alg_register(&drr_ops, IP_MP_ALG_DRR); |
| 248 | if (err) | 232 | if (err) |
| 249 | goto fail; | 233 | goto fail; |
| 250 | 234 | ||
diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c index 554a82568160..061b6b253982 100644 --- a/net/ipv4/multipath_rr.c +++ b/net/ipv4/multipath_rr.c | |||
| @@ -47,29 +47,12 @@ | |||
| 47 | #include <net/checksum.h> | 47 | #include <net/checksum.h> |
| 48 | #include <net/ip_mp_alg.h> | 48 | #include <net/ip_mp_alg.h> |
| 49 | 49 | ||
| 50 | #define MULTIPATH_MAX_CANDIDATES 40 | ||
| 51 | |||
| 52 | static struct rtable* last_used = NULL; | ||
| 53 | |||
| 54 | static void rr_remove(struct rtable *rt) | ||
| 55 | { | ||
| 56 | if (last_used == rt) | ||
| 57 | last_used = NULL; | ||
| 58 | } | ||
| 59 | |||
| 60 | static void rr_select_route(const struct flowi *flp, | 50 | static void rr_select_route(const struct flowi *flp, |
| 61 | struct rtable *first, struct rtable **rp) | 51 | struct rtable *first, struct rtable **rp) |
| 62 | { | 52 | { |
| 63 | struct rtable *nh, *result, *min_use_cand = NULL; | 53 | struct rtable *nh, *result, *min_use_cand = NULL; |
| 64 | int min_use = -1; | 54 | int min_use = -1; |
| 65 | 55 | ||
| 66 | /* if necessary and possible utilize the old alternative */ | ||
| 67 | if ((flp->flags & FLOWI_FLAG_MULTIPATHOLDROUTE) != 0 && | ||
| 68 | last_used != NULL) { | ||
| 69 | result = last_used; | ||
| 70 | goto out; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* 1. make sure all alt. nexthops have the same GC related data | 56 | /* 1. make sure all alt. nexthops have the same GC related data |
| 74 | * 2. determine the new candidate to be returned | 57 | * 2. determine the new candidate to be returned |
| 75 | */ | 58 | */ |
| @@ -90,15 +73,12 @@ static void rr_select_route(const struct flowi *flp, | |||
| 90 | if (!result) | 73 | if (!result) |
| 91 | result = first; | 74 | result = first; |
| 92 | 75 | ||
| 93 | out: | ||
| 94 | last_used = result; | ||
| 95 | result->u.dst.__use++; | 76 | result->u.dst.__use++; |
| 96 | *rp = result; | 77 | *rp = result; |
| 97 | } | 78 | } |
| 98 | 79 | ||
| 99 | static struct ip_mp_alg_ops rr_ops = { | 80 | static struct ip_mp_alg_ops rr_ops = { |
| 100 | .mp_alg_select_route = rr_select_route, | 81 | .mp_alg_select_route = rr_select_route, |
| 101 | .mp_alg_remove = rr_remove, | ||
| 102 | }; | 82 | }; |
| 103 | 83 | ||
| 104 | static int __init rr_init(void) | 84 | static int __init rr_init(void) |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index e5746b674413..eda1fba431a4 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | * communicating with userspace via netlink. | 3 | * communicating with userspace via netlink. |
| 4 | * | 4 | * |
| 5 | * (C) 2000-2002 James Morris <jmorris@intercode.com.au> | 5 | * (C) 2000-2002 James Morris <jmorris@intercode.com.au> |
| 6 | * (C) 2003-2005 Netfilter Core Team <coreteam@netfilter.org> | ||
| 6 | * | 7 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
| @@ -17,6 +18,7 @@ | |||
| 17 | * 2005-01-10: Added /proc counter for dropped packets; fixed so | 18 | * 2005-01-10: Added /proc counter for dropped packets; fixed so |
| 18 | * packets aren't delivered to user space if they're going | 19 | * packets aren't delivered to user space if they're going |
| 19 | * to be dropped. | 20 | * to be dropped. |
| 21 | * 2005-05-26: local_bh_{disable,enable} around nf_reinject (Harald Welte) | ||
| 20 | * | 22 | * |
| 21 | */ | 23 | */ |
| 22 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| @@ -71,7 +73,15 @@ static DECLARE_MUTEX(ipqnl_sem); | |||
| 71 | static void | 73 | static void |
| 72 | ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) | 74 | ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict) |
| 73 | { | 75 | { |
| 76 | /* TCP input path (and probably other bits) assume to be called | ||
| 77 | * from softirq context, not from syscall, like ipq_issue_verdict is | ||
| 78 | * called. TCP input path deadlocks with locks taken from timer | ||
| 79 | * softirq, e.g. We therefore emulate this by local_bh_disable() */ | ||
| 80 | |||
| 81 | local_bh_disable(); | ||
| 74 | nf_reinject(entry->skb, entry->info, verdict); | 82 | nf_reinject(entry->skb, entry->info, verdict); |
| 83 | local_bh_enable(); | ||
| 84 | |||
| 75 | kfree(entry); | 85 | kfree(entry); |
| 76 | } | 86 | } |
| 77 | 87 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 4a6952e3fee9..7c24e64b443f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -738,7 +738,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 738 | unsigned long amount; | 738 | unsigned long amount; |
| 739 | 739 | ||
| 740 | amount = 0; | 740 | amount = 0; |
| 741 | spin_lock_irq(&sk->sk_receive_queue.lock); | 741 | spin_lock_bh(&sk->sk_receive_queue.lock); |
| 742 | skb = skb_peek(&sk->sk_receive_queue); | 742 | skb = skb_peek(&sk->sk_receive_queue); |
| 743 | if (skb != NULL) { | 743 | if (skb != NULL) { |
| 744 | /* | 744 | /* |
| @@ -748,7 +748,7 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 748 | */ | 748 | */ |
| 749 | amount = skb->len - sizeof(struct udphdr); | 749 | amount = skb->len - sizeof(struct udphdr); |
| 750 | } | 750 | } |
| 751 | spin_unlock_irq(&sk->sk_receive_queue.lock); | 751 | spin_unlock_bh(&sk->sk_receive_queue.lock); |
| 752 | return put_user(amount, (int __user *)arg); | 752 | return put_user(amount, (int __user *)arg); |
| 753 | } | 753 | } |
| 754 | 754 | ||
| @@ -848,12 +848,12 @@ csum_copy_err: | |||
| 848 | /* Clear queue. */ | 848 | /* Clear queue. */ |
| 849 | if (flags&MSG_PEEK) { | 849 | if (flags&MSG_PEEK) { |
| 850 | int clear = 0; | 850 | int clear = 0; |
| 851 | spin_lock_irq(&sk->sk_receive_queue.lock); | 851 | spin_lock_bh(&sk->sk_receive_queue.lock); |
| 852 | if (skb == skb_peek(&sk->sk_receive_queue)) { | 852 | if (skb == skb_peek(&sk->sk_receive_queue)) { |
| 853 | __skb_unlink(skb, &sk->sk_receive_queue); | 853 | __skb_unlink(skb, &sk->sk_receive_queue); |
| 854 | clear = 1; | 854 | clear = 1; |
| 855 | } | 855 | } |
| 856 | spin_unlock_irq(&sk->sk_receive_queue.lock); | 856 | spin_unlock_bh(&sk->sk_receive_queue.lock); |
| 857 | if (clear) | 857 | if (clear) |
| 858 | kfree_skb(skb); | 858 | kfree_skb(skb); |
| 859 | } | 859 | } |
| @@ -1334,7 +1334,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 1334 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; | 1334 | struct sk_buff_head *rcvq = &sk->sk_receive_queue; |
| 1335 | struct sk_buff *skb; | 1335 | struct sk_buff *skb; |
| 1336 | 1336 | ||
| 1337 | spin_lock_irq(&rcvq->lock); | 1337 | spin_lock_bh(&rcvq->lock); |
| 1338 | while ((skb = skb_peek(rcvq)) != NULL) { | 1338 | while ((skb = skb_peek(rcvq)) != NULL) { |
| 1339 | if (udp_checksum_complete(skb)) { | 1339 | if (udp_checksum_complete(skb)) { |
| 1340 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); | 1340 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); |
| @@ -1345,7 +1345,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
| 1345 | break; | 1345 | break; |
| 1346 | } | 1346 | } |
| 1347 | } | 1347 | } |
| 1348 | spin_unlock_irq(&rcvq->lock); | 1348 | spin_unlock_bh(&rcvq->lock); |
| 1349 | 1349 | ||
| 1350 | /* nothing to see, move along */ | 1350 | /* nothing to see, move along */ |
| 1351 | if (skb == NULL) | 1351 | if (skb == NULL) |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index a93f6dc51979..0e5f7499debb 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
| @@ -535,10 +535,12 @@ release: | |||
| 535 | if (err) | 535 | if (err) |
| 536 | goto done; | 536 | goto done; |
| 537 | 537 | ||
| 538 | /* Do not check for fault */ | 538 | if (!freq.flr_label) { |
| 539 | if (!freq.flr_label) | 539 | if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, |
| 540 | copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, | 540 | &fl->label, sizeof(fl->label))) { |
| 541 | &fl->label, sizeof(fl->label)); | 541 | /* Intentionally ignore fault. */ |
| 542 | } | ||
| 543 | } | ||
| 542 | 544 | ||
| 543 | sfl1->fl = fl; | 545 | sfl1->fl = fl; |
| 544 | sfl1->next = np->ipv6_fl_list; | 546 | sfl1->next = np->ipv6_fl_list; |
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 8a3db9d95bab..d8bd2a569c7c 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <asm/byteorder.h> | 18 | #include <asm/byteorder.h> |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | #if 1 /* control */ | 21 | #if 0 /* control */ |
| 22 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) | 22 | #define DPRINTK(format,args...) printk(KERN_DEBUG format,##args) |
| 23 | #else | 23 | #else |
| 24 | #define DPRINTK(format,args...) | 24 | #define DPRINTK(format,args...) |
| @@ -73,8 +73,13 @@ static int dsmark_graft(struct Qdisc *sch,unsigned long arg, | |||
| 73 | 73 | ||
| 74 | DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, | 74 | DPRINTK("dsmark_graft(sch %p,[qdisc %p],new %p,old %p)\n",sch,p,new, |
| 75 | old); | 75 | old); |
| 76 | if (!new) | 76 | |
| 77 | new = &noop_qdisc; | 77 | if (new == NULL) { |
| 78 | new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); | ||
| 79 | if (new == NULL) | ||
| 80 | new = &noop_qdisc; | ||
| 81 | } | ||
| 82 | |||
| 78 | sch_tree_lock(sch); | 83 | sch_tree_lock(sch); |
| 79 | *old = xchg(&p->q,new); | 84 | *old = xchg(&p->q,new); |
| 80 | if (*old) | 85 | if (*old) |
| @@ -163,14 +168,15 @@ static void dsmark_walk(struct Qdisc *sch,struct qdisc_walker *walker) | |||
| 163 | return; | 168 | return; |
| 164 | for (i = 0; i < p->indices; i++) { | 169 | for (i = 0; i < p->indices; i++) { |
| 165 | if (p->mask[i] == 0xff && !p->value[i]) | 170 | if (p->mask[i] == 0xff && !p->value[i]) |
| 166 | continue; | 171 | goto ignore; |
| 167 | if (walker->count >= walker->skip) { | 172 | if (walker->count >= walker->skip) { |
| 168 | if (walker->fn(sch, i+1, walker) < 0) { | 173 | if (walker->fn(sch, i+1, walker) < 0) { |
| 169 | walker->stop = 1; | 174 | walker->stop = 1; |
| 170 | break; | 175 | break; |
| 171 | } | 176 | } |
| 172 | } | 177 | } |
| 173 | walker->count++; | 178 | ignore: |
| 179 | walker->count++; | ||
| 174 | } | 180 | } |
| 175 | } | 181 | } |
| 176 | 182 | ||
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index a9602f89d6b1..e537bd66a707 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
| @@ -112,7 +112,7 @@ config SOUND_BCM_CS4297A | |||
| 112 | 112 | ||
| 113 | config SOUND_ES1370 | 113 | config SOUND_ES1370 |
| 114 | tristate "Ensoniq AudioPCI (ES1370)" | 114 | tristate "Ensoniq AudioPCI (ES1370)" |
| 115 | depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT | 115 | depends on SOUND_PRIME!=n && SOUND && PCI |
| 116 | help | 116 | help |
| 117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 117 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
| 118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find | 118 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find |
| @@ -125,7 +125,7 @@ config SOUND_ES1370 | |||
| 125 | 125 | ||
| 126 | config SOUND_ES1371 | 126 | config SOUND_ES1371 |
| 127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" | 127 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" |
| 128 | depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT | 128 | depends on SOUND_PRIME!=n && SOUND && PCI |
| 129 | help | 129 | help |
| 130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 130 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
| 131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if | 131 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if |
| @@ -138,7 +138,7 @@ config SOUND_ES1371 | |||
| 138 | 138 | ||
| 139 | config SOUND_ESSSOLO1 | 139 | config SOUND_ESSSOLO1 |
| 140 | tristate "ESS Technology Solo1" | 140 | tristate "ESS Technology Solo1" |
| 141 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT && PCI | 141 | depends on SOUND_PRIME!=n && SOUND && PCI |
| 142 | help | 142 | help |
| 143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology | 143 | Say Y or M if you have a PCI sound card utilizing the ESS Technology |
| 144 | Solo1 chip. To find out if your sound card uses a | 144 | Solo1 chip. To find out if your sound card uses a |
| @@ -179,7 +179,7 @@ config SOUND_HARMONY | |||
| 179 | 179 | ||
| 180 | config SOUND_SONICVIBES | 180 | config SOUND_SONICVIBES |
| 181 | tristate "S3 SonicVibes" | 181 | tristate "S3 SonicVibes" |
| 182 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT | 182 | depends on SOUND_PRIME!=n && SOUND |
| 183 | help | 183 | help |
| 184 | Say Y or M if you have a PCI sound card utilizing the S3 | 184 | Say Y or M if you have a PCI sound card utilizing the S3 |
| 185 | SonicVibes chipset. To find out if your sound card uses a | 185 | SonicVibes chipset. To find out if your sound card uses a |
| @@ -226,7 +226,7 @@ config SOUND_AU1550_AC97 | |||
| 226 | 226 | ||
| 227 | config SOUND_TRIDENT | 227 | config SOUND_TRIDENT |
| 228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" | 228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" |
| 229 | depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT | 229 | depends on SOUND_PRIME!=n && SOUND |
| 230 | ---help--- | 230 | ---help--- |
| 231 | Say Y or M if you have a PCI sound card utilizing the Trident | 231 | Say Y or M if you have a PCI sound card utilizing the Trident |
| 232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 | 232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 |
| @@ -739,7 +739,7 @@ config SOUND_NM256 | |||
| 739 | 739 | ||
| 740 | config SOUND_MAD16 | 740 | config SOUND_MAD16 |
| 741 | tristate "OPTi MAD16 and/or Mozart based cards" | 741 | tristate "OPTi MAD16 and/or Mozart based cards" |
| 742 | depends on SOUND_OSS && SOUND_GAMEPORT | 742 | depends on SOUND_OSS |
| 743 | ---help--- | 743 | ---help--- |
| 744 | Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi | 744 | Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi |
| 745 | 82C928 or 82C929 or 82C931) audio interface chip. These chips are | 745 | 82C928 or 82C929 or 82C931) audio interface chip. These chips are |
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 32d94754acf8..080ef3928465 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
| @@ -876,7 +876,7 @@ static void __init detect_byte_swap(pmac_t *chip) | |||
| 876 | */ | 876 | */ |
| 877 | static int __init snd_pmac_detect(pmac_t *chip) | 877 | static int __init snd_pmac_detect(pmac_t *chip) |
| 878 | { | 878 | { |
| 879 | struct device_node *sound; | 879 | struct device_node *sound = NULL; |
| 880 | unsigned int *prop, l; | 880 | unsigned int *prop, l; |
| 881 | struct macio_chip* macio; | 881 | struct macio_chip* macio; |
| 882 | 882 | ||
| @@ -906,20 +906,22 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
| 906 | chip->is_pbook_G3 = 1; | 906 | chip->is_pbook_G3 = 1; |
| 907 | chip->node = find_devices("awacs"); | 907 | chip->node = find_devices("awacs"); |
| 908 | if (chip->node) | 908 | if (chip->node) |
| 909 | return 0; /* ok */ | 909 | sound = chip->node; |
| 910 | 910 | ||
| 911 | /* | 911 | /* |
| 912 | * powermac G3 models have a node called "davbus" | 912 | * powermac G3 models have a node called "davbus" |
| 913 | * with a child called "sound". | 913 | * with a child called "sound". |
| 914 | */ | 914 | */ |
| 915 | chip->node = find_devices("davbus"); | 915 | if (!chip->node) |
| 916 | chip->node = find_devices("davbus"); | ||
| 916 | /* | 917 | /* |
| 917 | * if we didn't find a davbus device, try 'i2s-a' since | 918 | * if we didn't find a davbus device, try 'i2s-a' since |
| 918 | * this seems to be what iBooks have | 919 | * this seems to be what iBooks have |
| 919 | */ | 920 | */ |
| 920 | if (! chip->node) { | 921 | if (! chip->node) { |
| 921 | chip->node = find_devices("i2s-a"); | 922 | chip->node = find_devices("i2s-a"); |
| 922 | if (chip->node && chip->node->parent && chip->node->parent->parent) { | 923 | if (chip->node && chip->node->parent && |
| 924 | chip->node->parent->parent) { | ||
| 923 | if (device_is_compatible(chip->node->parent->parent, | 925 | if (device_is_compatible(chip->node->parent->parent, |
| 924 | "K2-Keylargo")) | 926 | "K2-Keylargo")) |
| 925 | chip->is_k2 = 1; | 927 | chip->is_k2 = 1; |
| @@ -928,9 +930,11 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
| 928 | if (! chip->node) | 930 | if (! chip->node) |
| 929 | return -ENODEV; | 931 | return -ENODEV; |
| 930 | 932 | ||
| 931 | sound = find_devices("sound"); | 933 | if (!sound) { |
| 932 | while (sound && sound->parent != chip->node) | 934 | sound = find_devices("sound"); |
| 933 | sound = sound->next; | 935 | while (sound && sound->parent != chip->node) |
| 936 | sound = sound->next; | ||
| 937 | } | ||
| 934 | if (! sound) | 938 | if (! sound) |
| 935 | return -ENODEV; | 939 | return -ENODEV; |
| 936 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); | 940 | prop = (unsigned int *) get_property(sound, "sub-frame", NULL); |
| @@ -1019,7 +1023,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
| 1019 | } | 1023 | } |
| 1020 | } | 1024 | } |
| 1021 | if (chip->pdev == NULL) | 1025 | if (chip->pdev == NULL) |
| 1022 | printk(KERN_WARNING "snd-powermac: can't locate macio PCI device !\n"); | 1026 | printk(KERN_WARNING "snd-powermac: can't locate macio PCI" |
| 1027 | " device !\n"); | ||
| 1023 | 1028 | ||
| 1024 | detect_byte_swap(chip); | 1029 | detect_byte_swap(chip); |
| 1025 | 1030 | ||
| @@ -1027,7 +1032,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
| 1027 | are available */ | 1032 | are available */ |
| 1028 | prop = (unsigned int *) get_property(sound, "sample-rates", &l); | 1033 | prop = (unsigned int *) get_property(sound, "sample-rates", &l); |
| 1029 | if (! prop) | 1034 | if (! prop) |
| 1030 | prop = (unsigned int *) get_property(sound, "output-frame-rates", &l); | 1035 | prop = (unsigned int *) get_property(sound, |
| 1036 | "output-frame-rates", &l); | ||
| 1031 | if (prop) { | 1037 | if (prop) { |
| 1032 | int i; | 1038 | int i; |
| 1033 | chip->freqs_ok = 0; | 1039 | chip->freqs_ok = 0; |
| @@ -1054,7 +1060,8 @@ static int __init snd_pmac_detect(pmac_t *chip) | |||
| 1054 | /* | 1060 | /* |
| 1055 | * exported - boolean info callbacks for ease of programming | 1061 | * exported - boolean info callbacks for ease of programming |
| 1056 | */ | 1062 | */ |
| 1057 | int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 1063 | int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, |
| 1064 | snd_ctl_elem_info_t *uinfo) | ||
| 1058 | { | 1065 | { |
| 1059 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1066 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
| 1060 | uinfo->count = 2; | 1067 | uinfo->count = 2; |
| @@ -1063,7 +1070,8 @@ int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * | |||
| 1063 | return 0; | 1070 | return 0; |
| 1064 | } | 1071 | } |
| 1065 | 1072 | ||
| 1066 | int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) | 1073 | int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, |
| 1074 | snd_ctl_elem_info_t *uinfo) | ||
| 1067 | { | 1075 | { |
| 1068 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | 1076 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; |
| 1069 | uinfo->count = 1; | 1077 | uinfo->count = 1; |
