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 /drivers | |
parent | decc6d0b68f27bbb8a0357fccf41936a3c196b03 (diff) | |
parent | 1e86d1c648508fd50e6c9960576b87906a7906ad (diff) |
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
Diffstat (limited to 'drivers')
51 files changed, 2274 insertions, 652 deletions
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"); |