diff options
Diffstat (limited to 'drivers')
148 files changed, 4890 insertions, 1833 deletions
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 38aca048e951..66a9d8145562 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/pm_qos_params.h> | 41 | #include <linux/pm_qos_params.h> |
42 | #include <linux/clockchips.h> | 42 | #include <linux/clockchips.h> |
43 | #include <linux/cpuidle.h> | 43 | #include <linux/cpuidle.h> |
44 | #include <linux/irqflags.h> | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * Include the apic definitions for x86 to have the APIC timer related defines | 47 | * Include the apic definitions for x86 to have the APIC timer related defines |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 5260e9e0df48..989429cfed88 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -347,8 +347,9 @@ static inline int memory_probe_init(void) | |||
347 | * section belongs to... | 347 | * section belongs to... |
348 | */ | 348 | */ |
349 | 349 | ||
350 | static int add_memory_block(unsigned long node_id, struct mem_section *section, | 350 | static int add_memory_block(int nid, struct mem_section *section, |
351 | unsigned long state, int phys_device) | 351 | unsigned long state, int phys_device, |
352 | enum mem_add_context context) | ||
352 | { | 353 | { |
353 | struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); | 354 | struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL); |
354 | int ret = 0; | 355 | int ret = 0; |
@@ -370,6 +371,10 @@ static int add_memory_block(unsigned long node_id, struct mem_section *section, | |||
370 | ret = mem_create_simple_file(mem, phys_device); | 371 | ret = mem_create_simple_file(mem, phys_device); |
371 | if (!ret) | 372 | if (!ret) |
372 | ret = mem_create_simple_file(mem, removable); | 373 | ret = mem_create_simple_file(mem, removable); |
374 | if (!ret) { | ||
375 | if (context == HOTPLUG) | ||
376 | ret = register_mem_sect_under_node(mem, nid); | ||
377 | } | ||
373 | 378 | ||
374 | return ret; | 379 | return ret; |
375 | } | 380 | } |
@@ -382,7 +387,7 @@ static int add_memory_block(unsigned long node_id, struct mem_section *section, | |||
382 | * | 387 | * |
383 | * This could be made generic for all sysdev classes. | 388 | * This could be made generic for all sysdev classes. |
384 | */ | 389 | */ |
385 | static struct memory_block *find_memory_block(struct mem_section *section) | 390 | struct memory_block *find_memory_block(struct mem_section *section) |
386 | { | 391 | { |
387 | struct kobject *kobj; | 392 | struct kobject *kobj; |
388 | struct sys_device *sysdev; | 393 | struct sys_device *sysdev; |
@@ -411,6 +416,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, | |||
411 | struct memory_block *mem; | 416 | struct memory_block *mem; |
412 | 417 | ||
413 | mem = find_memory_block(section); | 418 | mem = find_memory_block(section); |
419 | unregister_mem_sect_under_nodes(mem); | ||
414 | mem_remove_simple_file(mem, phys_index); | 420 | mem_remove_simple_file(mem, phys_index); |
415 | mem_remove_simple_file(mem, state); | 421 | mem_remove_simple_file(mem, state); |
416 | mem_remove_simple_file(mem, phys_device); | 422 | mem_remove_simple_file(mem, phys_device); |
@@ -424,9 +430,9 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section, | |||
424 | * need an interface for the VM to add new memory regions, | 430 | * need an interface for the VM to add new memory regions, |
425 | * but without onlining it. | 431 | * but without onlining it. |
426 | */ | 432 | */ |
427 | int register_new_memory(struct mem_section *section) | 433 | int register_new_memory(int nid, struct mem_section *section) |
428 | { | 434 | { |
429 | return add_memory_block(0, section, MEM_OFFLINE, 0); | 435 | return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG); |
430 | } | 436 | } |
431 | 437 | ||
432 | int unregister_memory_section(struct mem_section *section) | 438 | int unregister_memory_section(struct mem_section *section) |
@@ -458,7 +464,8 @@ int __init memory_dev_init(void) | |||
458 | for (i = 0; i < NR_MEM_SECTIONS; i++) { | 464 | for (i = 0; i < NR_MEM_SECTIONS; i++) { |
459 | if (!present_section_nr(i)) | 465 | if (!present_section_nr(i)) |
460 | continue; | 466 | continue; |
461 | err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0); | 467 | err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, |
468 | 0, BOOT); | ||
462 | if (!ret) | 469 | if (!ret) |
463 | ret = err; | 470 | ret = err; |
464 | } | 471 | } |
diff --git a/drivers/base/node.c b/drivers/base/node.c index 91636cd8b6c9..43fa90b837ee 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
9 | #include <linux/memory.h> | ||
9 | #include <linux/node.h> | 10 | #include <linux/node.h> |
10 | #include <linux/hugetlb.h> | 11 | #include <linux/hugetlb.h> |
11 | #include <linux/cpumask.h> | 12 | #include <linux/cpumask.h> |
@@ -248,6 +249,105 @@ int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) | |||
248 | return 0; | 249 | return 0; |
249 | } | 250 | } |
250 | 251 | ||
252 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | ||
253 | #define page_initialized(page) (page->lru.next) | ||
254 | |||
255 | static int get_nid_for_pfn(unsigned long pfn) | ||
256 | { | ||
257 | struct page *page; | ||
258 | |||
259 | if (!pfn_valid_within(pfn)) | ||
260 | return -1; | ||
261 | page = pfn_to_page(pfn); | ||
262 | if (!page_initialized(page)) | ||
263 | return -1; | ||
264 | return pfn_to_nid(pfn); | ||
265 | } | ||
266 | |||
267 | /* register memory section under specified node if it spans that node */ | ||
268 | int register_mem_sect_under_node(struct memory_block *mem_blk, int nid) | ||
269 | { | ||
270 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | ||
271 | |||
272 | if (!mem_blk) | ||
273 | return -EFAULT; | ||
274 | if (!node_online(nid)) | ||
275 | return 0; | ||
276 | sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); | ||
277 | sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; | ||
278 | for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { | ||
279 | int page_nid; | ||
280 | |||
281 | page_nid = get_nid_for_pfn(pfn); | ||
282 | if (page_nid < 0) | ||
283 | continue; | ||
284 | if (page_nid != nid) | ||
285 | continue; | ||
286 | return sysfs_create_link_nowarn(&node_devices[nid].sysdev.kobj, | ||
287 | &mem_blk->sysdev.kobj, | ||
288 | kobject_name(&mem_blk->sysdev.kobj)); | ||
289 | } | ||
290 | /* mem section does not span the specified node */ | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | /* unregister memory section under all nodes that it spans */ | ||
295 | int unregister_mem_sect_under_nodes(struct memory_block *mem_blk) | ||
296 | { | ||
297 | nodemask_t unlinked_nodes; | ||
298 | unsigned long pfn, sect_start_pfn, sect_end_pfn; | ||
299 | |||
300 | if (!mem_blk) | ||
301 | return -EFAULT; | ||
302 | nodes_clear(unlinked_nodes); | ||
303 | sect_start_pfn = section_nr_to_pfn(mem_blk->phys_index); | ||
304 | sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; | ||
305 | for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { | ||
306 | unsigned int nid; | ||
307 | |||
308 | nid = get_nid_for_pfn(pfn); | ||
309 | if (nid < 0) | ||
310 | continue; | ||
311 | if (!node_online(nid)) | ||
312 | continue; | ||
313 | if (node_test_and_set(nid, unlinked_nodes)) | ||
314 | continue; | ||
315 | sysfs_remove_link(&node_devices[nid].sysdev.kobj, | ||
316 | kobject_name(&mem_blk->sysdev.kobj)); | ||
317 | } | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static int link_mem_sections(int nid) | ||
322 | { | ||
323 | unsigned long start_pfn = NODE_DATA(nid)->node_start_pfn; | ||
324 | unsigned long end_pfn = start_pfn + NODE_DATA(nid)->node_spanned_pages; | ||
325 | unsigned long pfn; | ||
326 | int err = 0; | ||
327 | |||
328 | for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { | ||
329 | unsigned long section_nr = pfn_to_section_nr(pfn); | ||
330 | struct mem_section *mem_sect; | ||
331 | struct memory_block *mem_blk; | ||
332 | int ret; | ||
333 | |||
334 | if (!present_section_nr(section_nr)) | ||
335 | continue; | ||
336 | mem_sect = __nr_to_section(section_nr); | ||
337 | mem_blk = find_memory_block(mem_sect); | ||
338 | ret = register_mem_sect_under_node(mem_blk, nid); | ||
339 | if (!err) | ||
340 | err = ret; | ||
341 | |||
342 | /* discard ref obtained in find_memory_block() */ | ||
343 | kobject_put(&mem_blk->sysdev.kobj); | ||
344 | } | ||
345 | return err; | ||
346 | } | ||
347 | #else | ||
348 | static int link_mem_sections(int nid) { return 0; } | ||
349 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ | ||
350 | |||
251 | int register_one_node(int nid) | 351 | int register_one_node(int nid) |
252 | { | 352 | { |
253 | int error = 0; | 353 | int error = 0; |
@@ -267,6 +367,9 @@ int register_one_node(int nid) | |||
267 | if (cpu_to_node(cpu) == nid) | 367 | if (cpu_to_node(cpu) == nid) |
268 | register_cpu_under_node(cpu, nid); | 368 | register_cpu_under_node(cpu, nid); |
269 | } | 369 | } |
370 | |||
371 | /* link memory sections under this node */ | ||
372 | error = link_mem_sections(nid); | ||
270 | } | 373 | } |
271 | 374 | ||
272 | return error; | 375 | return error; |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 1697043119bd..35914b6e1d2a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -841,7 +841,7 @@ config JS_RTC | |||
841 | 841 | ||
842 | config GEN_RTC | 842 | config GEN_RTC |
843 | tristate "Generic /dev/rtc emulation" | 843 | tristate "Generic /dev/rtc emulation" |
844 | depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32 | 844 | depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32 && !BLACKFIN |
845 | ---help--- | 845 | ---help--- |
846 | If you say Y here and create a character special file /dev/rtc with | 846 | If you say Y here and create a character special file /dev/rtc with |
847 | major number 10 and minor number 135 using mknod ("man mknod"), you | 847 | major number 10 and minor number 135 using mknod ("man mknod"), you |
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index 4246b8e36cb3..45d3e80156d4 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
@@ -554,7 +554,7 @@ int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list) | |||
554 | __get_user(fontpos, &list->fontpos); | 554 | __get_user(fontpos, &list->fontpos); |
555 | if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0) | 555 | if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0) |
556 | err = err1; | 556 | err = err1; |
557 | list++; | 557 | list++; |
558 | } | 558 | } |
559 | 559 | ||
560 | if (con_unify_unimap(vc, p)) | 560 | if (con_unify_unimap(vc, p)) |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 6431f6921a67..3586b3b3df3f 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -425,9 +425,6 @@ static ssize_t read_oldmem(struct file *file, char __user *buf, | |||
425 | } | 425 | } |
426 | #endif | 426 | #endif |
427 | 427 | ||
428 | extern long vread(char *buf, char *addr, unsigned long count); | ||
429 | extern long vwrite(char *buf, char *addr, unsigned long count); | ||
430 | |||
431 | #ifdef CONFIG_DEVKMEM | 428 | #ifdef CONFIG_DEVKMEM |
432 | /* | 429 | /* |
433 | * This function reads the *virtual* memory as seen by the kernel. | 430 | * This function reads the *virtual* memory as seen by the kernel. |
diff --git a/drivers/char/random.c b/drivers/char/random.c index c7afc068c28d..7c13581ca9cd 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -407,7 +407,7 @@ struct entropy_store { | |||
407 | /* read-write data: */ | 407 | /* read-write data: */ |
408 | spinlock_t lock; | 408 | spinlock_t lock; |
409 | unsigned add_ptr; | 409 | unsigned add_ptr; |
410 | int entropy_count; /* Must at no time exceed ->POOLBITS! */ | 410 | int entropy_count; |
411 | int input_rotate; | 411 | int input_rotate; |
412 | }; | 412 | }; |
413 | 413 | ||
@@ -767,11 +767,10 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, | |||
767 | { | 767 | { |
768 | unsigned long flags; | 768 | unsigned long flags; |
769 | 769 | ||
770 | BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); | ||
771 | |||
772 | /* Hold lock while accounting */ | 770 | /* Hold lock while accounting */ |
773 | spin_lock_irqsave(&r->lock, flags); | 771 | spin_lock_irqsave(&r->lock, flags); |
774 | 772 | ||
773 | BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); | ||
775 | DEBUG_ENT("trying to extract %d bits from %s\n", | 774 | DEBUG_ENT("trying to extract %d bits from %s\n", |
776 | nbytes * 8, r->name); | 775 | nbytes * 8, r->name); |
777 | 776 | ||
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 94966edfb44d..d41b9f6f7903 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -82,7 +82,7 @@ static void sysrq_handle_loglevel(int key, struct tty_struct *tty) | |||
82 | } | 82 | } |
83 | static struct sysrq_key_op sysrq_loglevel_op = { | 83 | static struct sysrq_key_op sysrq_loglevel_op = { |
84 | .handler = sysrq_handle_loglevel, | 84 | .handler = sysrq_handle_loglevel, |
85 | .help_msg = "loglevel0-8", | 85 | .help_msg = "loglevel(0-9)", |
86 | .action_msg = "Changing Loglevel", | 86 | .action_msg = "Changing Loglevel", |
87 | .enable_mask = SYSRQ_ENABLE_LOG, | 87 | .enable_mask = SYSRQ_ENABLE_LOG, |
88 | }; | 88 | }; |
@@ -233,7 +233,7 @@ static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | |||
233 | 233 | ||
234 | static struct sysrq_key_op sysrq_showallcpus_op = { | 234 | static struct sysrq_key_op sysrq_showallcpus_op = { |
235 | .handler = sysrq_handle_showallcpus, | 235 | .handler = sysrq_handle_showallcpus, |
236 | .help_msg = "aLlcpus", | 236 | .help_msg = "show-backtrace-all-active-cpus(L)", |
237 | .action_msg = "Show backtrace of all active CPUs", | 237 | .action_msg = "Show backtrace of all active CPUs", |
238 | .enable_mask = SYSRQ_ENABLE_DUMP, | 238 | .enable_mask = SYSRQ_ENABLE_DUMP, |
239 | }; | 239 | }; |
@@ -247,7 +247,7 @@ static void sysrq_handle_showregs(int key, struct tty_struct *tty) | |||
247 | } | 247 | } |
248 | static struct sysrq_key_op sysrq_showregs_op = { | 248 | static struct sysrq_key_op sysrq_showregs_op = { |
249 | .handler = sysrq_handle_showregs, | 249 | .handler = sysrq_handle_showregs, |
250 | .help_msg = "showPc", | 250 | .help_msg = "show-registers(P)", |
251 | .action_msg = "Show Regs", | 251 | .action_msg = "Show Regs", |
252 | .enable_mask = SYSRQ_ENABLE_DUMP, | 252 | .enable_mask = SYSRQ_ENABLE_DUMP, |
253 | }; | 253 | }; |
@@ -258,7 +258,7 @@ static void sysrq_handle_showstate(int key, struct tty_struct *tty) | |||
258 | } | 258 | } |
259 | static struct sysrq_key_op sysrq_showstate_op = { | 259 | static struct sysrq_key_op sysrq_showstate_op = { |
260 | .handler = sysrq_handle_showstate, | 260 | .handler = sysrq_handle_showstate, |
261 | .help_msg = "showTasks", | 261 | .help_msg = "show-task-states(T)", |
262 | .action_msg = "Show State", | 262 | .action_msg = "Show State", |
263 | .enable_mask = SYSRQ_ENABLE_DUMP, | 263 | .enable_mask = SYSRQ_ENABLE_DUMP, |
264 | }; | 264 | }; |
@@ -269,7 +269,7 @@ static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) | |||
269 | } | 269 | } |
270 | static struct sysrq_key_op sysrq_showstate_blocked_op = { | 270 | static struct sysrq_key_op sysrq_showstate_blocked_op = { |
271 | .handler = sysrq_handle_showstate_blocked, | 271 | .handler = sysrq_handle_showstate_blocked, |
272 | .help_msg = "shoW-blocked-tasks", | 272 | .help_msg = "show-blocked-tasks(W)", |
273 | .action_msg = "Show Blocked State", | 273 | .action_msg = "Show Blocked State", |
274 | .enable_mask = SYSRQ_ENABLE_DUMP, | 274 | .enable_mask = SYSRQ_ENABLE_DUMP, |
275 | }; | 275 | }; |
@@ -297,7 +297,7 @@ static void sysrq_handle_showmem(int key, struct tty_struct *tty) | |||
297 | } | 297 | } |
298 | static struct sysrq_key_op sysrq_showmem_op = { | 298 | static struct sysrq_key_op sysrq_showmem_op = { |
299 | .handler = sysrq_handle_showmem, | 299 | .handler = sysrq_handle_showmem, |
300 | .help_msg = "showMem", | 300 | .help_msg = "show-memory-usage(M)", |
301 | .action_msg = "Show Memory", | 301 | .action_msg = "Show Memory", |
302 | .enable_mask = SYSRQ_ENABLE_DUMP, | 302 | .enable_mask = SYSRQ_ENABLE_DUMP, |
303 | }; | 303 | }; |
@@ -323,7 +323,7 @@ static void sysrq_handle_term(int key, struct tty_struct *tty) | |||
323 | } | 323 | } |
324 | static struct sysrq_key_op sysrq_term_op = { | 324 | static struct sysrq_key_op sysrq_term_op = { |
325 | .handler = sysrq_handle_term, | 325 | .handler = sysrq_handle_term, |
326 | .help_msg = "tErm", | 326 | .help_msg = "terminate-all-tasks(E)", |
327 | .action_msg = "Terminate All Tasks", | 327 | .action_msg = "Terminate All Tasks", |
328 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 328 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
329 | }; | 329 | }; |
@@ -341,7 +341,7 @@ static void sysrq_handle_moom(int key, struct tty_struct *tty) | |||
341 | } | 341 | } |
342 | static struct sysrq_key_op sysrq_moom_op = { | 342 | static struct sysrq_key_op sysrq_moom_op = { |
343 | .handler = sysrq_handle_moom, | 343 | .handler = sysrq_handle_moom, |
344 | .help_msg = "Full", | 344 | .help_msg = "memory-full-oom-kill(F)", |
345 | .action_msg = "Manual OOM execution", | 345 | .action_msg = "Manual OOM execution", |
346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 346 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
347 | }; | 347 | }; |
@@ -353,7 +353,7 @@ static void sysrq_handle_kill(int key, struct tty_struct *tty) | |||
353 | } | 353 | } |
354 | static struct sysrq_key_op sysrq_kill_op = { | 354 | static struct sysrq_key_op sysrq_kill_op = { |
355 | .handler = sysrq_handle_kill, | 355 | .handler = sysrq_handle_kill, |
356 | .help_msg = "kIll", | 356 | .help_msg = "kill-all-tasks(I)", |
357 | .action_msg = "Kill All Tasks", | 357 | .action_msg = "Kill All Tasks", |
358 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 358 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
359 | }; | 359 | }; |
@@ -364,7 +364,7 @@ static void sysrq_handle_unrt(int key, struct tty_struct *tty) | |||
364 | } | 364 | } |
365 | static struct sysrq_key_op sysrq_unrt_op = { | 365 | static struct sysrq_key_op sysrq_unrt_op = { |
366 | .handler = sysrq_handle_unrt, | 366 | .handler = sysrq_handle_unrt, |
367 | .help_msg = "Nice", | 367 | .help_msg = "nice-all-RT-tasks(N)", |
368 | .action_msg = "Nice All RT Tasks", | 368 | .action_msg = "Nice All RT Tasks", |
369 | .enable_mask = SYSRQ_ENABLE_RTNICE, | 369 | .enable_mask = SYSRQ_ENABLE_RTNICE, |
370 | }; | 370 | }; |
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index e2667a8c2997..eee47fd16d79 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig | |||
@@ -109,6 +109,13 @@ config EDAC_X38 | |||
109 | Support for error detection and correction on the Intel | 109 | Support for error detection and correction on the Intel |
110 | X38 server chipsets. | 110 | X38 server chipsets. |
111 | 111 | ||
112 | config EDAC_I5400 | ||
113 | tristate "Intel 5400 (Seaburg) chipsets" | ||
114 | depends on EDAC_MM_EDAC && PCI && X86 | ||
115 | help | ||
116 | Support for error detection and correction the Intel | ||
117 | i5400 MCH chipset (Seaburg). | ||
118 | |||
112 | config EDAC_I82860 | 119 | config EDAC_I82860 |
113 | tristate "Intel 82860" | 120 | tristate "Intel 82860" |
114 | depends on EDAC_MM_EDAC && PCI && X86_32 | 121 | depends on EDAC_MM_EDAC && PCI && X86_32 |
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 62c2d9bad8dc..b75196927de3 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile | |||
@@ -20,6 +20,7 @@ endif | |||
20 | obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o | 20 | obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o |
21 | obj-$(CONFIG_EDAC_I5000) += i5000_edac.o | 21 | obj-$(CONFIG_EDAC_I5000) += i5000_edac.o |
22 | obj-$(CONFIG_EDAC_I5100) += i5100_edac.o | 22 | obj-$(CONFIG_EDAC_I5100) += i5100_edac.o |
23 | obj-$(CONFIG_EDAC_I5400) += i5400_edac.o | ||
23 | obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o | 24 | obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o |
24 | obj-$(CONFIG_EDAC_E752X) += e752x_edac.o | 25 | obj-$(CONFIG_EDAC_E752X) += e752x_edac.o |
25 | obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o | 26 | obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o |
diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index 4041e9143283..ca9113e1c106 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c | |||
@@ -333,7 +333,7 @@ static int add_edac_dev_to_global_list(struct edac_device_ctl_info *edac_dev) | |||
333 | fail0: | 333 | fail0: |
334 | edac_printk(KERN_WARNING, EDAC_MC, | 334 | edac_printk(KERN_WARNING, EDAC_MC, |
335 | "%s (%s) %s %s already assigned %d\n", | 335 | "%s (%s) %s %s already assigned %d\n", |
336 | rover->dev->bus_id, edac_dev_name(rover), | 336 | dev_name(rover->dev), edac_dev_name(rover), |
337 | rover->mod_name, rover->ctl_name, rover->dev_idx); | 337 | rover->mod_name, rover->ctl_name, rover->dev_idx); |
338 | return 1; | 338 | return 1; |
339 | 339 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index d110392d48f4..25d66940b4fa 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -401,7 +401,7 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci) | |||
401 | 401 | ||
402 | fail0: | 402 | fail0: |
403 | edac_printk(KERN_WARNING, EDAC_MC, | 403 | edac_printk(KERN_WARNING, EDAC_MC, |
404 | "%s (%s) %s %s already assigned %d\n", p->dev->bus_id, | 404 | "%s (%s) %s %s already assigned %d\n", dev_name(p->dev), |
405 | edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx); | 405 | edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx); |
406 | return 1; | 406 | return 1; |
407 | 407 | ||
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c index 22ec9d5d4312..5d3c8083a40e 100644 --- a/drivers/edac/edac_pci.c +++ b/drivers/edac/edac_pci.c | |||
@@ -150,7 +150,7 @@ static int add_edac_pci_to_global_list(struct edac_pci_ctl_info *pci) | |||
150 | fail0: | 150 | fail0: |
151 | edac_printk(KERN_WARNING, EDAC_PCI, | 151 | edac_printk(KERN_WARNING, EDAC_PCI, |
152 | "%s (%s) %s %s already assigned %d\n", | 152 | "%s (%s) %s %s already assigned %d\n", |
153 | rover->dev->bus_id, edac_dev_name(rover), | 153 | dev_name(rover->dev), edac_dev_name(rover), |
154 | rover->mod_name, rover->ctl_name, rover->pci_idx); | 154 | rover->mod_name, rover->ctl_name, rover->pci_idx); |
155 | return 1; | 155 | return 1; |
156 | 156 | ||
diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 5c153dccc95e..422728cfe994 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c | |||
@@ -569,7 +569,7 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) | |||
569 | 569 | ||
570 | local_irq_restore(flags); | 570 | local_irq_restore(flags); |
571 | 571 | ||
572 | debugf4("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id); | 572 | debugf4("PCI STATUS= 0x%04x %s\n", status, dev_name(&dev->dev)); |
573 | 573 | ||
574 | /* check the status reg for errors on boards NOT marked as broken | 574 | /* check the status reg for errors on boards NOT marked as broken |
575 | * if broken, we cannot trust any of the status bits | 575 | * if broken, we cannot trust any of the status bits |
@@ -600,13 +600,13 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) | |||
600 | } | 600 | } |
601 | 601 | ||
602 | 602 | ||
603 | debugf4("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id); | 603 | debugf4("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev_name(&dev->dev)); |
604 | 604 | ||
605 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | 605 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
606 | /* On bridges, need to examine secondary status register */ | 606 | /* On bridges, need to examine secondary status register */ |
607 | status = get_pci_parity_status(dev, 1); | 607 | status = get_pci_parity_status(dev, 1); |
608 | 608 | ||
609 | debugf4("PCI SEC_STATUS= 0x%04x %s\n", status, dev->dev.bus_id); | 609 | debugf4("PCI SEC_STATUS= 0x%04x %s\n", status, dev_name(&dev->dev)); |
610 | 610 | ||
611 | /* check the secondary status reg for errors, | 611 | /* check the secondary status reg for errors, |
612 | * on NOT broken boards | 612 | * on NOT broken boards |
diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c new file mode 100644 index 000000000000..b08b6d8e2dc7 --- /dev/null +++ b/drivers/edac/i5400_edac.c | |||
@@ -0,0 +1,1476 @@ | |||
1 | /* | ||
2 | * Intel 5400 class Memory Controllers kernel module (Seaburg) | ||
3 | * | ||
4 | * This file may be distributed under the terms of the | ||
5 | * GNU General Public License. | ||
6 | * | ||
7 | * Copyright (c) 2008 by: | ||
8 | * Ben Woodard <woodard@redhat.com> | ||
9 | * Mauro Carvalho Chehab <mchehab@redhat.com> | ||
10 | * | ||
11 | * Red Hat Inc. http://www.redhat.com | ||
12 | * | ||
13 | * Forked and adapted from the i5000_edac driver which was | ||
14 | * written by Douglas Thompson Linux Networx <norsk5@xmission.com> | ||
15 | * | ||
16 | * This module is based on the following document: | ||
17 | * | ||
18 | * Intel 5400 Chipset Memory Controller Hub (MCH) - Datasheet | ||
19 | * http://developer.intel.com/design/chipsets/datashts/313070.htm | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/pci_ids.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/edac.h> | ||
29 | #include <linux/mmzone.h> | ||
30 | |||
31 | #include "edac_core.h" | ||
32 | |||
33 | /* | ||
34 | * Alter this version for the I5400 module when modifications are made | ||
35 | */ | ||
36 | #define I5400_REVISION " Ver: 1.0.0 " __DATE__ | ||
37 | |||
38 | #define EDAC_MOD_STR "i5400_edac" | ||
39 | |||
40 | #define i5400_printk(level, fmt, arg...) \ | ||
41 | edac_printk(level, "i5400", fmt, ##arg) | ||
42 | |||
43 | #define i5400_mc_printk(mci, level, fmt, arg...) \ | ||
44 | edac_mc_chipset_printk(mci, level, "i5400", fmt, ##arg) | ||
45 | |||
46 | /* Limits for i5400 */ | ||
47 | #define NUM_MTRS_PER_BRANCH 4 | ||
48 | #define CHANNELS_PER_BRANCH 2 | ||
49 | #define MAX_CHANNELS 4 | ||
50 | #define MAX_DIMMS (MAX_CHANNELS * 4) /* Up to 4 DIMM's per channel */ | ||
51 | #define MAX_CSROWS (MAX_DIMMS * 2) /* max possible csrows per channel */ | ||
52 | |||
53 | /* Device 16, | ||
54 | * Function 0: System Address | ||
55 | * Function 1: Memory Branch Map, Control, Errors Register | ||
56 | * Function 2: FSB Error Registers | ||
57 | * | ||
58 | * All 3 functions of Device 16 (0,1,2) share the SAME DID and | ||
59 | * uses PCI_DEVICE_ID_INTEL_5400_ERR for device 16 (0,1,2), | ||
60 | * PCI_DEVICE_ID_INTEL_5400_FBD0 and PCI_DEVICE_ID_INTEL_5400_FBD1 | ||
61 | * for device 21 (0,1). | ||
62 | */ | ||
63 | |||
64 | /* OFFSETS for Function 0 */ | ||
65 | #define AMBASE 0x48 /* AMB Mem Mapped Reg Region Base */ | ||
66 | #define MAXCH 0x56 /* Max Channel Number */ | ||
67 | #define MAXDIMMPERCH 0x57 /* Max DIMM PER Channel Number */ | ||
68 | |||
69 | /* OFFSETS for Function 1 */ | ||
70 | #define TOLM 0x6C | ||
71 | #define REDMEMB 0x7C | ||
72 | #define REC_ECC_LOCATOR_ODD(x) ((x) & 0x3fe00) /* bits [17:9] indicate ODD, [8:0] indicate EVEN */ | ||
73 | #define MIR0 0x80 | ||
74 | #define MIR1 0x84 | ||
75 | #define AMIR0 0x8c | ||
76 | #define AMIR1 0x90 | ||
77 | |||
78 | /* Fatal error registers */ | ||
79 | #define FERR_FAT_FBD 0x98 /* also called as FERR_FAT_FB_DIMM at datasheet */ | ||
80 | #define FERR_FAT_FBDCHAN (3<<28) /* channel index where the highest-order error occurred */ | ||
81 | |||
82 | #define NERR_FAT_FBD 0x9c | ||
83 | #define FERR_NF_FBD 0xa0 /* also called as FERR_NFAT_FB_DIMM at datasheet */ | ||
84 | |||
85 | /* Non-fatal error register */ | ||
86 | #define NERR_NF_FBD 0xa4 | ||
87 | |||
88 | /* Enable error mask */ | ||
89 | #define EMASK_FBD 0xa8 | ||
90 | |||
91 | #define ERR0_FBD 0xac | ||
92 | #define ERR1_FBD 0xb0 | ||
93 | #define ERR2_FBD 0xb4 | ||
94 | #define MCERR_FBD 0xb8 | ||
95 | |||
96 | /* No OFFSETS for Device 16 Function 2 */ | ||
97 | |||
98 | /* | ||
99 | * Device 21, | ||
100 | * Function 0: Memory Map Branch 0 | ||
101 | * | ||
102 | * Device 22, | ||
103 | * Function 0: Memory Map Branch 1 | ||
104 | */ | ||
105 | |||
106 | /* OFFSETS for Function 0 */ | ||
107 | #define AMBPRESENT_0 0x64 | ||
108 | #define AMBPRESENT_1 0x66 | ||
109 | #define MTR0 0x80 | ||
110 | #define MTR1 0x82 | ||
111 | #define MTR2 0x84 | ||
112 | #define MTR3 0x86 | ||
113 | |||
114 | /* OFFSETS for Function 1 */ | ||
115 | #define NRECFGLOG 0x74 | ||
116 | #define RECFGLOG 0x78 | ||
117 | #define NRECMEMA 0xbe | ||
118 | #define NRECMEMB 0xc0 | ||
119 | #define NRECFB_DIMMA 0xc4 | ||
120 | #define NRECFB_DIMMB 0xc8 | ||
121 | #define NRECFB_DIMMC 0xcc | ||
122 | #define NRECFB_DIMMD 0xd0 | ||
123 | #define NRECFB_DIMME 0xd4 | ||
124 | #define NRECFB_DIMMF 0xd8 | ||
125 | #define REDMEMA 0xdC | ||
126 | #define RECMEMA 0xf0 | ||
127 | #define RECMEMB 0xf4 | ||
128 | #define RECFB_DIMMA 0xf8 | ||
129 | #define RECFB_DIMMB 0xec | ||
130 | #define RECFB_DIMMC 0xf0 | ||
131 | #define RECFB_DIMMD 0xf4 | ||
132 | #define RECFB_DIMME 0xf8 | ||
133 | #define RECFB_DIMMF 0xfC | ||
134 | |||
135 | /* | ||
136 | * Error indicator bits and masks | ||
137 | * Error masks are according with Table 5-17 of i5400 datasheet | ||
138 | */ | ||
139 | |||
140 | enum error_mask { | ||
141 | EMASK_M1 = 1<<0, /* Memory Write error on non-redundant retry */ | ||
142 | EMASK_M2 = 1<<1, /* Memory or FB-DIMM configuration CRC read error */ | ||
143 | EMASK_M3 = 1<<2, /* Reserved */ | ||
144 | EMASK_M4 = 1<<3, /* Uncorrectable Data ECC on Replay */ | ||
145 | EMASK_M5 = 1<<4, /* Aliased Uncorrectable Non-Mirrored Demand Data ECC */ | ||
146 | EMASK_M6 = 1<<5, /* Unsupported on i5400 */ | ||
147 | EMASK_M7 = 1<<6, /* Aliased Uncorrectable Resilver- or Spare-Copy Data ECC */ | ||
148 | EMASK_M8 = 1<<7, /* Aliased Uncorrectable Patrol Data ECC */ | ||
149 | EMASK_M9 = 1<<8, /* Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC */ | ||
150 | EMASK_M10 = 1<<9, /* Unsupported on i5400 */ | ||
151 | EMASK_M11 = 1<<10, /* Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC */ | ||
152 | EMASK_M12 = 1<<11, /* Non-Aliased Uncorrectable Patrol Data ECC */ | ||
153 | EMASK_M13 = 1<<12, /* Memory Write error on first attempt */ | ||
154 | EMASK_M14 = 1<<13, /* FB-DIMM Configuration Write error on first attempt */ | ||
155 | EMASK_M15 = 1<<14, /* Memory or FB-DIMM configuration CRC read error */ | ||
156 | EMASK_M16 = 1<<15, /* Channel Failed-Over Occurred */ | ||
157 | EMASK_M17 = 1<<16, /* Correctable Non-Mirrored Demand Data ECC */ | ||
158 | EMASK_M18 = 1<<17, /* Unsupported on i5400 */ | ||
159 | EMASK_M19 = 1<<18, /* Correctable Resilver- or Spare-Copy Data ECC */ | ||
160 | EMASK_M20 = 1<<19, /* Correctable Patrol Data ECC */ | ||
161 | EMASK_M21 = 1<<20, /* FB-DIMM Northbound parity error on FB-DIMM Sync Status */ | ||
162 | EMASK_M22 = 1<<21, /* SPD protocol Error */ | ||
163 | EMASK_M23 = 1<<22, /* Non-Redundant Fast Reset Timeout */ | ||
164 | EMASK_M24 = 1<<23, /* Refresh error */ | ||
165 | EMASK_M25 = 1<<24, /* Memory Write error on redundant retry */ | ||
166 | EMASK_M26 = 1<<25, /* Redundant Fast Reset Timeout */ | ||
167 | EMASK_M27 = 1<<26, /* Correctable Counter Threshold Exceeded */ | ||
168 | EMASK_M28 = 1<<27, /* DIMM-Spare Copy Completed */ | ||
169 | EMASK_M29 = 1<<28, /* DIMM-Isolation Completed */ | ||
170 | }; | ||
171 | |||
172 | /* | ||
173 | * Names to translate bit error into something useful | ||
174 | */ | ||
175 | static const char *error_name[] = { | ||
176 | [0] = "Memory Write error on non-redundant retry", | ||
177 | [1] = "Memory or FB-DIMM configuration CRC read error", | ||
178 | /* Reserved */ | ||
179 | [3] = "Uncorrectable Data ECC on Replay", | ||
180 | [4] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC", | ||
181 | /* M6 Unsupported on i5400 */ | ||
182 | [6] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC", | ||
183 | [7] = "Aliased Uncorrectable Patrol Data ECC", | ||
184 | [8] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC", | ||
185 | /* M10 Unsupported on i5400 */ | ||
186 | [10] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC", | ||
187 | [11] = "Non-Aliased Uncorrectable Patrol Data ECC", | ||
188 | [12] = "Memory Write error on first attempt", | ||
189 | [13] = "FB-DIMM Configuration Write error on first attempt", | ||
190 | [14] = "Memory or FB-DIMM configuration CRC read error", | ||
191 | [15] = "Channel Failed-Over Occurred", | ||
192 | [16] = "Correctable Non-Mirrored Demand Data ECC", | ||
193 | /* M18 Unsupported on i5400 */ | ||
194 | [18] = "Correctable Resilver- or Spare-Copy Data ECC", | ||
195 | [19] = "Correctable Patrol Data ECC", | ||
196 | [20] = "FB-DIMM Northbound parity error on FB-DIMM Sync Status", | ||
197 | [21] = "SPD protocol Error", | ||
198 | [22] = "Non-Redundant Fast Reset Timeout", | ||
199 | [23] = "Refresh error", | ||
200 | [24] = "Memory Write error on redundant retry", | ||
201 | [25] = "Redundant Fast Reset Timeout", | ||
202 | [26] = "Correctable Counter Threshold Exceeded", | ||
203 | [27] = "DIMM-Spare Copy Completed", | ||
204 | [28] = "DIMM-Isolation Completed", | ||
205 | }; | ||
206 | |||
207 | /* Fatal errors */ | ||
208 | #define ERROR_FAT_MASK (EMASK_M1 | \ | ||
209 | EMASK_M2 | \ | ||
210 | EMASK_M23) | ||
211 | |||
212 | /* Correctable errors */ | ||
213 | #define ERROR_NF_CORRECTABLE (EMASK_M27 | \ | ||
214 | EMASK_M20 | \ | ||
215 | EMASK_M19 | \ | ||
216 | EMASK_M18 | \ | ||
217 | EMASK_M17 | \ | ||
218 | EMASK_M16) | ||
219 | #define ERROR_NF_DIMM_SPARE (EMASK_M29 | \ | ||
220 | EMASK_M28) | ||
221 | #define ERROR_NF_SPD_PROTOCOL (EMASK_M22) | ||
222 | #define ERROR_NF_NORTH_CRC (EMASK_M21) | ||
223 | |||
224 | /* Recoverable errors */ | ||
225 | #define ERROR_NF_RECOVERABLE (EMASK_M26 | \ | ||
226 | EMASK_M25 | \ | ||
227 | EMASK_M24 | \ | ||
228 | EMASK_M15 | \ | ||
229 | EMASK_M14 | \ | ||
230 | EMASK_M13 | \ | ||
231 | EMASK_M12 | \ | ||
232 | EMASK_M11 | \ | ||
233 | EMASK_M9 | \ | ||
234 | EMASK_M8 | \ | ||
235 | EMASK_M7 | \ | ||
236 | EMASK_M5) | ||
237 | |||
238 | /* uncorrectable errors */ | ||
239 | #define ERROR_NF_UNCORRECTABLE (EMASK_M4) | ||
240 | |||
241 | /* mask to all non-fatal errors */ | ||
242 | #define ERROR_NF_MASK (ERROR_NF_CORRECTABLE | \ | ||
243 | ERROR_NF_UNCORRECTABLE | \ | ||
244 | ERROR_NF_RECOVERABLE | \ | ||
245 | ERROR_NF_DIMM_SPARE | \ | ||
246 | ERROR_NF_SPD_PROTOCOL | \ | ||
247 | ERROR_NF_NORTH_CRC) | ||
248 | |||
249 | /* | ||
250 | * Define error masks for the several registers | ||
251 | */ | ||
252 | |||
253 | /* Enable all fatal and non fatal errors */ | ||
254 | #define ENABLE_EMASK_ALL (ERROR_FAT_MASK | ERROR_NF_MASK) | ||
255 | |||
256 | /* mask for fatal error registers */ | ||
257 | #define FERR_FAT_MASK ERROR_FAT_MASK | ||
258 | |||
259 | /* masks for non-fatal error register */ | ||
260 | static inline int to_nf_mask(unsigned int mask) | ||
261 | { | ||
262 | return (mask & EMASK_M29) | (mask >> 3); | ||
263 | }; | ||
264 | |||
265 | static inline int from_nf_ferr(unsigned int mask) | ||
266 | { | ||
267 | return (mask & EMASK_M29) | /* Bit 28 */ | ||
268 | (mask & ((1 << 28) - 1) << 3); /* Bits 0 to 27 */ | ||
269 | }; | ||
270 | |||
271 | #define FERR_NF_MASK to_nf_mask(ERROR_NF_MASK) | ||
272 | #define FERR_NF_CORRECTABLE to_nf_mask(ERROR_NF_CORRECTABLE) | ||
273 | #define FERR_NF_DIMM_SPARE to_nf_mask(ERROR_NF_DIMM_SPARE) | ||
274 | #define FERR_NF_SPD_PROTOCOL to_nf_mask(ERROR_NF_SPD_PROTOCOL) | ||
275 | #define FERR_NF_NORTH_CRC to_nf_mask(ERROR_NF_NORTH_CRC) | ||
276 | #define FERR_NF_RECOVERABLE to_nf_mask(ERROR_NF_RECOVERABLE) | ||
277 | #define FERR_NF_UNCORRECTABLE to_nf_mask(ERROR_NF_UNCORRECTABLE) | ||
278 | |||
279 | /* Defines to extract the vaious fields from the | ||
280 | * MTRx - Memory Technology Registers | ||
281 | */ | ||
282 | #define MTR_DIMMS_PRESENT(mtr) ((mtr) & (1 << 10)) | ||
283 | #define MTR_DIMMS_ETHROTTLE(mtr) ((mtr) & (1 << 9)) | ||
284 | #define MTR_DRAM_WIDTH(mtr) (((mtr) & (1 << 8)) ? 8 : 4) | ||
285 | #define MTR_DRAM_BANKS(mtr) (((mtr) & (1 << 6)) ? 8 : 4) | ||
286 | #define MTR_DRAM_BANKS_ADDR_BITS(mtr) ((MTR_DRAM_BANKS(mtr) == 8) ? 3 : 2) | ||
287 | #define MTR_DIMM_RANK(mtr) (((mtr) >> 5) & 0x1) | ||
288 | #define MTR_DIMM_RANK_ADDR_BITS(mtr) (MTR_DIMM_RANK(mtr) ? 2 : 1) | ||
289 | #define MTR_DIMM_ROWS(mtr) (((mtr) >> 2) & 0x3) | ||
290 | #define MTR_DIMM_ROWS_ADDR_BITS(mtr) (MTR_DIMM_ROWS(mtr) + 13) | ||
291 | #define MTR_DIMM_COLS(mtr) ((mtr) & 0x3) | ||
292 | #define MTR_DIMM_COLS_ADDR_BITS(mtr) (MTR_DIMM_COLS(mtr) + 10) | ||
293 | |||
294 | /* This applies to FERR_NF_FB-DIMM as well as FERR_FAT_FB-DIMM */ | ||
295 | static inline int extract_fbdchan_indx(u32 x) | ||
296 | { | ||
297 | return (x>>28) & 0x3; | ||
298 | } | ||
299 | |||
300 | #ifdef CONFIG_EDAC_DEBUG | ||
301 | /* MTR NUMROW */ | ||
302 | static const char *numrow_toString[] = { | ||
303 | "8,192 - 13 rows", | ||
304 | "16,384 - 14 rows", | ||
305 | "32,768 - 15 rows", | ||
306 | "65,536 - 16 rows" | ||
307 | }; | ||
308 | |||
309 | /* MTR NUMCOL */ | ||
310 | static const char *numcol_toString[] = { | ||
311 | "1,024 - 10 columns", | ||
312 | "2,048 - 11 columns", | ||
313 | "4,096 - 12 columns", | ||
314 | "reserved" | ||
315 | }; | ||
316 | #endif | ||
317 | |||
318 | /* Device name and register DID (Device ID) */ | ||
319 | struct i5400_dev_info { | ||
320 | const char *ctl_name; /* name for this device */ | ||
321 | u16 fsb_mapping_errors; /* DID for the branchmap,control */ | ||
322 | }; | ||
323 | |||
324 | /* Table of devices attributes supported by this driver */ | ||
325 | static const struct i5400_dev_info i5400_devs[] = { | ||
326 | { | ||
327 | .ctl_name = "I5400", | ||
328 | .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_5400_ERR, | ||
329 | }, | ||
330 | }; | ||
331 | |||
332 | struct i5400_dimm_info { | ||
333 | int megabytes; /* size, 0 means not present */ | ||
334 | int dual_rank; | ||
335 | }; | ||
336 | |||
337 | /* driver private data structure */ | ||
338 | struct i5400_pvt { | ||
339 | struct pci_dev *system_address; /* 16.0 */ | ||
340 | struct pci_dev *branchmap_werrors; /* 16.1 */ | ||
341 | struct pci_dev *fsb_error_regs; /* 16.2 */ | ||
342 | struct pci_dev *branch_0; /* 21.0 */ | ||
343 | struct pci_dev *branch_1; /* 22.0 */ | ||
344 | |||
345 | u16 tolm; /* top of low memory */ | ||
346 | u64 ambase; /* AMB BAR */ | ||
347 | |||
348 | u16 mir0, mir1; | ||
349 | |||
350 | u16 b0_mtr[NUM_MTRS_PER_BRANCH]; /* Memory Technlogy Reg */ | ||
351 | u16 b0_ambpresent0; /* Branch 0, Channel 0 */ | ||
352 | u16 b0_ambpresent1; /* Brnach 0, Channel 1 */ | ||
353 | |||
354 | u16 b1_mtr[NUM_MTRS_PER_BRANCH]; /* Memory Technlogy Reg */ | ||
355 | u16 b1_ambpresent0; /* Branch 1, Channel 8 */ | ||
356 | u16 b1_ambpresent1; /* Branch 1, Channel 1 */ | ||
357 | |||
358 | /* DIMM information matrix, allocating architecture maximums */ | ||
359 | struct i5400_dimm_info dimm_info[MAX_CSROWS][MAX_CHANNELS]; | ||
360 | |||
361 | /* Actual values for this controller */ | ||
362 | int maxch; /* Max channels */ | ||
363 | int maxdimmperch; /* Max DIMMs per channel */ | ||
364 | }; | ||
365 | |||
366 | /* I5400 MCH error information retrieved from Hardware */ | ||
367 | struct i5400_error_info { | ||
368 | /* These registers are always read from the MC */ | ||
369 | u32 ferr_fat_fbd; /* First Errors Fatal */ | ||
370 | u32 nerr_fat_fbd; /* Next Errors Fatal */ | ||
371 | u32 ferr_nf_fbd; /* First Errors Non-Fatal */ | ||
372 | u32 nerr_nf_fbd; /* Next Errors Non-Fatal */ | ||
373 | |||
374 | /* These registers are input ONLY if there was a Recoverable Error */ | ||
375 | u32 redmemb; /* Recoverable Mem Data Error log B */ | ||
376 | u16 recmema; /* Recoverable Mem Error log A */ | ||
377 | u32 recmemb; /* Recoverable Mem Error log B */ | ||
378 | |||
379 | /* These registers are input ONLY if there was a Non-Rec Error */ | ||
380 | u16 nrecmema; /* Non-Recoverable Mem log A */ | ||
381 | u16 nrecmemb; /* Non-Recoverable Mem log B */ | ||
382 | |||
383 | }; | ||
384 | |||
385 | /* note that nrec_rdwr changed from NRECMEMA to NRECMEMB between the 5000 and | ||
386 | 5400 better to use an inline function than a macro in this case */ | ||
387 | static inline int nrec_bank(struct i5400_error_info *info) | ||
388 | { | ||
389 | return ((info->nrecmema) >> 12) & 0x7; | ||
390 | } | ||
391 | static inline int nrec_rank(struct i5400_error_info *info) | ||
392 | { | ||
393 | return ((info->nrecmema) >> 8) & 0xf; | ||
394 | } | ||
395 | static inline int nrec_buf_id(struct i5400_error_info *info) | ||
396 | { | ||
397 | return ((info->nrecmema)) & 0xff; | ||
398 | } | ||
399 | static inline int nrec_rdwr(struct i5400_error_info *info) | ||
400 | { | ||
401 | return (info->nrecmemb) >> 31; | ||
402 | } | ||
403 | /* This applies to both NREC and REC string so it can be used with nrec_rdwr | ||
404 | and rec_rdwr */ | ||
405 | static inline const char *rdwr_str(int rdwr) | ||
406 | { | ||
407 | return rdwr ? "Write" : "Read"; | ||
408 | } | ||
409 | static inline int nrec_cas(struct i5400_error_info *info) | ||
410 | { | ||
411 | return ((info->nrecmemb) >> 16) & 0x1fff; | ||
412 | } | ||
413 | static inline int nrec_ras(struct i5400_error_info *info) | ||
414 | { | ||
415 | return (info->nrecmemb) & 0xffff; | ||
416 | } | ||
417 | static inline int rec_bank(struct i5400_error_info *info) | ||
418 | { | ||
419 | return ((info->recmema) >> 12) & 0x7; | ||
420 | } | ||
421 | static inline int rec_rank(struct i5400_error_info *info) | ||
422 | { | ||
423 | return ((info->recmema) >> 8) & 0xf; | ||
424 | } | ||
425 | static inline int rec_rdwr(struct i5400_error_info *info) | ||
426 | { | ||
427 | return (info->recmemb) >> 31; | ||
428 | } | ||
429 | static inline int rec_cas(struct i5400_error_info *info) | ||
430 | { | ||
431 | return ((info->recmemb) >> 16) & 0x1fff; | ||
432 | } | ||
433 | static inline int rec_ras(struct i5400_error_info *info) | ||
434 | { | ||
435 | return (info->recmemb) & 0xffff; | ||
436 | } | ||
437 | |||
438 | static struct edac_pci_ctl_info *i5400_pci; | ||
439 | |||
440 | /* | ||
441 | * i5400_get_error_info Retrieve the hardware error information from | ||
442 | * the hardware and cache it in the 'info' | ||
443 | * structure | ||
444 | */ | ||
445 | static void i5400_get_error_info(struct mem_ctl_info *mci, | ||
446 | struct i5400_error_info *info) | ||
447 | { | ||
448 | struct i5400_pvt *pvt; | ||
449 | u32 value; | ||
450 | |||
451 | pvt = mci->pvt_info; | ||
452 | |||
453 | /* read in the 1st FATAL error register */ | ||
454 | pci_read_config_dword(pvt->branchmap_werrors, FERR_FAT_FBD, &value); | ||
455 | |||
456 | /* Mask only the bits that the doc says are valid | ||
457 | */ | ||
458 | value &= (FERR_FAT_FBDCHAN | FERR_FAT_MASK); | ||
459 | |||
460 | /* If there is an error, then read in the | ||
461 | NEXT FATAL error register and the Memory Error Log Register A | ||
462 | */ | ||
463 | if (value & FERR_FAT_MASK) { | ||
464 | info->ferr_fat_fbd = value; | ||
465 | |||
466 | /* harvest the various error data we need */ | ||
467 | pci_read_config_dword(pvt->branchmap_werrors, | ||
468 | NERR_FAT_FBD, &info->nerr_fat_fbd); | ||
469 | pci_read_config_word(pvt->branchmap_werrors, | ||
470 | NRECMEMA, &info->nrecmema); | ||
471 | pci_read_config_word(pvt->branchmap_werrors, | ||
472 | NRECMEMB, &info->nrecmemb); | ||
473 | |||
474 | /* Clear the error bits, by writing them back */ | ||
475 | pci_write_config_dword(pvt->branchmap_werrors, | ||
476 | FERR_FAT_FBD, value); | ||
477 | } else { | ||
478 | info->ferr_fat_fbd = 0; | ||
479 | info->nerr_fat_fbd = 0; | ||
480 | info->nrecmema = 0; | ||
481 | info->nrecmemb = 0; | ||
482 | } | ||
483 | |||
484 | /* read in the 1st NON-FATAL error register */ | ||
485 | pci_read_config_dword(pvt->branchmap_werrors, FERR_NF_FBD, &value); | ||
486 | |||
487 | /* If there is an error, then read in the 1st NON-FATAL error | ||
488 | * register as well */ | ||
489 | if (value & FERR_NF_MASK) { | ||
490 | info->ferr_nf_fbd = value; | ||
491 | |||
492 | /* harvest the various error data we need */ | ||
493 | pci_read_config_dword(pvt->branchmap_werrors, | ||
494 | NERR_NF_FBD, &info->nerr_nf_fbd); | ||
495 | pci_read_config_word(pvt->branchmap_werrors, | ||
496 | RECMEMA, &info->recmema); | ||
497 | pci_read_config_dword(pvt->branchmap_werrors, | ||
498 | RECMEMB, &info->recmemb); | ||
499 | pci_read_config_dword(pvt->branchmap_werrors, | ||
500 | REDMEMB, &info->redmemb); | ||
501 | |||
502 | /* Clear the error bits, by writing them back */ | ||
503 | pci_write_config_dword(pvt->branchmap_werrors, | ||
504 | FERR_NF_FBD, value); | ||
505 | } else { | ||
506 | info->ferr_nf_fbd = 0; | ||
507 | info->nerr_nf_fbd = 0; | ||
508 | info->recmema = 0; | ||
509 | info->recmemb = 0; | ||
510 | info->redmemb = 0; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * i5400_proccess_non_recoverable_info(struct mem_ctl_info *mci, | ||
516 | * struct i5400_error_info *info, | ||
517 | * int handle_errors); | ||
518 | * | ||
519 | * handle the Intel FATAL and unrecoverable errors, if any | ||
520 | */ | ||
521 | static void i5400_proccess_non_recoverable_info(struct mem_ctl_info *mci, | ||
522 | struct i5400_error_info *info, | ||
523 | unsigned long allErrors) | ||
524 | { | ||
525 | char msg[EDAC_MC_LABEL_LEN + 1 + 90 + 80]; | ||
526 | int branch; | ||
527 | int channel; | ||
528 | int bank; | ||
529 | int buf_id; | ||
530 | int rank; | ||
531 | int rdwr; | ||
532 | int ras, cas; | ||
533 | int errnum; | ||
534 | char *type = NULL; | ||
535 | |||
536 | if (!allErrors) | ||
537 | return; /* if no error, return now */ | ||
538 | |||
539 | if (allErrors & ERROR_FAT_MASK) | ||
540 | type = "FATAL"; | ||
541 | else if (allErrors & FERR_NF_UNCORRECTABLE) | ||
542 | type = "NON-FATAL uncorrected"; | ||
543 | else | ||
544 | type = "NON-FATAL recoverable"; | ||
545 | |||
546 | /* ONLY ONE of the possible error bits will be set, as per the docs */ | ||
547 | |||
548 | branch = extract_fbdchan_indx(info->ferr_fat_fbd); | ||
549 | channel = branch; | ||
550 | |||
551 | /* Use the NON-Recoverable macros to extract data */ | ||
552 | bank = nrec_bank(info); | ||
553 | rank = nrec_rank(info); | ||
554 | buf_id = nrec_buf_id(info); | ||
555 | rdwr = nrec_rdwr(info); | ||
556 | ras = nrec_ras(info); | ||
557 | cas = nrec_cas(info); | ||
558 | |||
559 | debugf0("\t\tCSROW= %d Channels= %d,%d (Branch= %d " | ||
560 | "DRAM Bank= %d Buffer ID = %d rdwr= %s ras= %d cas= %d)\n", | ||
561 | rank, channel, channel + 1, branch >> 1, bank, | ||
562 | buf_id, rdwr_str(rdwr), ras, cas); | ||
563 | |||
564 | /* Only 1 bit will be on */ | ||
565 | errnum = find_first_bit(&allErrors, ARRAY_SIZE(error_name)); | ||
566 | |||
567 | /* Form out message */ | ||
568 | snprintf(msg, sizeof(msg), | ||
569 | "%s (Branch=%d DRAM-Bank=%d Buffer ID = %d RDWR=%s " | ||
570 | "RAS=%d CAS=%d %s Err=0x%lx (%s))", | ||
571 | type, branch >> 1, bank, buf_id, rdwr_str(rdwr), ras, cas, | ||
572 | type, allErrors, error_name[errnum]); | ||
573 | |||
574 | /* Call the helper to output message */ | ||
575 | edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg); | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * i5400_process_fatal_error_info(struct mem_ctl_info *mci, | ||
580 | * struct i5400_error_info *info, | ||
581 | * int handle_errors); | ||
582 | * | ||
583 | * handle the Intel NON-FATAL errors, if any | ||
584 | */ | ||
585 | static void i5400_process_nonfatal_error_info(struct mem_ctl_info *mci, | ||
586 | struct i5400_error_info *info) | ||
587 | { | ||
588 | char msg[EDAC_MC_LABEL_LEN + 1 + 90 + 80]; | ||
589 | unsigned long allErrors; | ||
590 | int branch; | ||
591 | int channel; | ||
592 | int bank; | ||
593 | int rank; | ||
594 | int rdwr; | ||
595 | int ras, cas; | ||
596 | int errnum; | ||
597 | |||
598 | /* mask off the Error bits that are possible */ | ||
599 | allErrors = from_nf_ferr(info->ferr_nf_fbd & FERR_NF_MASK); | ||
600 | if (!allErrors) | ||
601 | return; /* if no error, return now */ | ||
602 | |||
603 | /* ONLY ONE of the possible error bits will be set, as per the docs */ | ||
604 | |||
605 | if (allErrors & (ERROR_NF_UNCORRECTABLE | ERROR_NF_RECOVERABLE)) { | ||
606 | i5400_proccess_non_recoverable_info(mci, info, allErrors); | ||
607 | return; | ||
608 | } | ||
609 | |||
610 | /* Correctable errors */ | ||
611 | if (allErrors & ERROR_NF_CORRECTABLE) { | ||
612 | debugf0("\tCorrected bits= 0x%lx\n", allErrors); | ||
613 | |||
614 | branch = extract_fbdchan_indx(info->ferr_nf_fbd); | ||
615 | |||
616 | channel = 0; | ||
617 | if (REC_ECC_LOCATOR_ODD(info->redmemb)) | ||
618 | channel = 1; | ||
619 | |||
620 | /* Convert channel to be based from zero, instead of | ||
621 | * from branch base of 0 */ | ||
622 | channel += branch; | ||
623 | |||
624 | bank = rec_bank(info); | ||
625 | rank = rec_rank(info); | ||
626 | rdwr = rec_rdwr(info); | ||
627 | ras = rec_ras(info); | ||
628 | cas = rec_cas(info); | ||
629 | |||
630 | /* Only 1 bit will be on */ | ||
631 | errnum = find_first_bit(&allErrors, ARRAY_SIZE(error_name)); | ||
632 | |||
633 | debugf0("\t\tCSROW= %d Channel= %d (Branch %d " | ||
634 | "DRAM Bank= %d rdwr= %s ras= %d cas= %d)\n", | ||
635 | rank, channel, branch >> 1, bank, | ||
636 | rdwr_str(rdwr), ras, cas); | ||
637 | |||
638 | /* Form out message */ | ||
639 | snprintf(msg, sizeof(msg), | ||
640 | "Corrected error (Branch=%d DRAM-Bank=%d RDWR=%s " | ||
641 | "RAS=%d CAS=%d, CE Err=0x%lx (%s))", | ||
642 | branch >> 1, bank, rdwr_str(rdwr), ras, cas, | ||
643 | allErrors, error_name[errnum]); | ||
644 | |||
645 | /* Call the helper to output message */ | ||
646 | edac_mc_handle_fbd_ce(mci, rank, channel, msg); | ||
647 | |||
648 | return; | ||
649 | } | ||
650 | |||
651 | /* Miscelaneous errors */ | ||
652 | errnum = find_first_bit(&allErrors, ARRAY_SIZE(error_name)); | ||
653 | |||
654 | branch = extract_fbdchan_indx(info->ferr_nf_fbd); | ||
655 | |||
656 | i5400_mc_printk(mci, KERN_EMERG, | ||
657 | "Non-Fatal misc error (Branch=%d Err=%#lx (%s))", | ||
658 | branch >> 1, allErrors, error_name[errnum]); | ||
659 | } | ||
660 | |||
661 | /* | ||
662 | * i5400_process_error_info Process the error info that is | ||
663 | * in the 'info' structure, previously retrieved from hardware | ||
664 | */ | ||
665 | static void i5400_process_error_info(struct mem_ctl_info *mci, | ||
666 | struct i5400_error_info *info) | ||
667 | { u32 allErrors; | ||
668 | |||
669 | /* First handle any fatal errors that occurred */ | ||
670 | allErrors = (info->ferr_fat_fbd & FERR_FAT_MASK); | ||
671 | i5400_proccess_non_recoverable_info(mci, info, allErrors); | ||
672 | |||
673 | /* now handle any non-fatal errors that occurred */ | ||
674 | i5400_process_nonfatal_error_info(mci, info); | ||
675 | } | ||
676 | |||
677 | /* | ||
678 | * i5400_clear_error Retrieve any error from the hardware | ||
679 | * but do NOT process that error. | ||
680 | * Used for 'clearing' out of previous errors | ||
681 | * Called by the Core module. | ||
682 | */ | ||
683 | static void i5400_clear_error(struct mem_ctl_info *mci) | ||
684 | { | ||
685 | struct i5400_error_info info; | ||
686 | |||
687 | i5400_get_error_info(mci, &info); | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * i5400_check_error Retrieve and process errors reported by the | ||
692 | * hardware. Called by the Core module. | ||
693 | */ | ||
694 | static void i5400_check_error(struct mem_ctl_info *mci) | ||
695 | { | ||
696 | struct i5400_error_info info; | ||
697 | debugf4("MC%d: " __FILE__ ": %s()\n", mci->mc_idx, __func__); | ||
698 | i5400_get_error_info(mci, &info); | ||
699 | i5400_process_error_info(mci, &info); | ||
700 | } | ||
701 | |||
702 | /* | ||
703 | * i5400_put_devices 'put' all the devices that we have | ||
704 | * reserved via 'get' | ||
705 | */ | ||
706 | static void i5400_put_devices(struct mem_ctl_info *mci) | ||
707 | { | ||
708 | struct i5400_pvt *pvt; | ||
709 | |||
710 | pvt = mci->pvt_info; | ||
711 | |||
712 | /* Decrement usage count for devices */ | ||
713 | pci_dev_put(pvt->branch_1); | ||
714 | pci_dev_put(pvt->branch_0); | ||
715 | pci_dev_put(pvt->fsb_error_regs); | ||
716 | pci_dev_put(pvt->branchmap_werrors); | ||
717 | } | ||
718 | |||
719 | /* | ||
720 | * i5400_get_devices Find and perform 'get' operation on the MCH's | ||
721 | * device/functions we want to reference for this driver | ||
722 | * | ||
723 | * Need to 'get' device 16 func 1 and func 2 | ||
724 | */ | ||
725 | static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx) | ||
726 | { | ||
727 | struct i5400_pvt *pvt; | ||
728 | struct pci_dev *pdev; | ||
729 | |||
730 | pvt = mci->pvt_info; | ||
731 | pvt->branchmap_werrors = NULL; | ||
732 | pvt->fsb_error_regs = NULL; | ||
733 | pvt->branch_0 = NULL; | ||
734 | pvt->branch_1 = NULL; | ||
735 | |||
736 | /* Attempt to 'get' the MCH register we want */ | ||
737 | pdev = NULL; | ||
738 | while (!pvt->branchmap_werrors || !pvt->fsb_error_regs) { | ||
739 | pdev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
740 | PCI_DEVICE_ID_INTEL_5400_ERR, pdev); | ||
741 | if (!pdev) { | ||
742 | /* End of list, leave */ | ||
743 | i5400_printk(KERN_ERR, | ||
744 | "'system address,Process Bus' " | ||
745 | "device not found:" | ||
746 | "vendor 0x%x device 0x%x ERR funcs " | ||
747 | "(broken BIOS?)\n", | ||
748 | PCI_VENDOR_ID_INTEL, | ||
749 | PCI_DEVICE_ID_INTEL_5400_ERR); | ||
750 | goto error; | ||
751 | } | ||
752 | |||
753 | /* Store device 16 funcs 1 and 2 */ | ||
754 | switch (PCI_FUNC(pdev->devfn)) { | ||
755 | case 1: | ||
756 | pvt->branchmap_werrors = pdev; | ||
757 | break; | ||
758 | case 2: | ||
759 | pvt->fsb_error_regs = pdev; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | |||
764 | debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n", | ||
765 | pci_name(pvt->system_address), | ||
766 | pvt->system_address->vendor, pvt->system_address->device); | ||
767 | debugf1("Branchmap, control and errors - PCI Bus ID: %s %x:%x\n", | ||
768 | pci_name(pvt->branchmap_werrors), | ||
769 | pvt->branchmap_werrors->vendor, pvt->branchmap_werrors->device); | ||
770 | debugf1("FSB Error Regs - PCI Bus ID: %s %x:%x\n", | ||
771 | pci_name(pvt->fsb_error_regs), | ||
772 | pvt->fsb_error_regs->vendor, pvt->fsb_error_regs->device); | ||
773 | |||
774 | pvt->branch_0 = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
775 | PCI_DEVICE_ID_INTEL_5400_FBD0, NULL); | ||
776 | if (!pvt->branch_0) { | ||
777 | i5400_printk(KERN_ERR, | ||
778 | "MC: 'BRANCH 0' device not found:" | ||
779 | "vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n", | ||
780 | PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_FBD0); | ||
781 | goto error; | ||
782 | } | ||
783 | |||
784 | /* If this device claims to have more than 2 channels then | ||
785 | * fetch Branch 1's information | ||
786 | */ | ||
787 | if (pvt->maxch < CHANNELS_PER_BRANCH) | ||
788 | return 0; | ||
789 | |||
790 | pvt->branch_1 = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
791 | PCI_DEVICE_ID_INTEL_5400_FBD1, NULL); | ||
792 | if (!pvt->branch_1) { | ||
793 | i5400_printk(KERN_ERR, | ||
794 | "MC: 'BRANCH 1' device not found:" | ||
795 | "vendor 0x%x device 0x%x Func 0 " | ||
796 | "(broken BIOS?)\n", | ||
797 | PCI_VENDOR_ID_INTEL, | ||
798 | PCI_DEVICE_ID_INTEL_5400_FBD1); | ||
799 | goto error; | ||
800 | } | ||
801 | |||
802 | return 0; | ||
803 | |||
804 | error: | ||
805 | i5400_put_devices(mci); | ||
806 | return -ENODEV; | ||
807 | } | ||
808 | |||
809 | /* | ||
810 | * determine_amb_present | ||
811 | * | ||
812 | * the information is contained in NUM_MTRS_PER_BRANCH different | ||
813 | * registers determining which of the NUM_MTRS_PER_BRANCH requires | ||
814 | * knowing which channel is in question | ||
815 | * | ||
816 | * 2 branches, each with 2 channels | ||
817 | * b0_ambpresent0 for channel '0' | ||
818 | * b0_ambpresent1 for channel '1' | ||
819 | * b1_ambpresent0 for channel '2' | ||
820 | * b1_ambpresent1 for channel '3' | ||
821 | */ | ||
822 | static int determine_amb_present_reg(struct i5400_pvt *pvt, int channel) | ||
823 | { | ||
824 | int amb_present; | ||
825 | |||
826 | if (channel < CHANNELS_PER_BRANCH) { | ||
827 | if (channel & 0x1) | ||
828 | amb_present = pvt->b0_ambpresent1; | ||
829 | else | ||
830 | amb_present = pvt->b0_ambpresent0; | ||
831 | } else { | ||
832 | if (channel & 0x1) | ||
833 | amb_present = pvt->b1_ambpresent1; | ||
834 | else | ||
835 | amb_present = pvt->b1_ambpresent0; | ||
836 | } | ||
837 | |||
838 | return amb_present; | ||
839 | } | ||
840 | |||
841 | /* | ||
842 | * determine_mtr(pvt, csrow, channel) | ||
843 | * | ||
844 | * return the proper MTR register as determine by the csrow and desired channel | ||
845 | */ | ||
846 | static int determine_mtr(struct i5400_pvt *pvt, int csrow, int channel) | ||
847 | { | ||
848 | int mtr; | ||
849 | int n; | ||
850 | |||
851 | /* There is one MTR for each slot pair of FB-DIMMs, | ||
852 | Each slot may have one or two ranks (2 csrows), | ||
853 | Each slot pair may be at branch 0 or branch 1. | ||
854 | So, csrow should be divided by eight | ||
855 | */ | ||
856 | n = csrow >> 3; | ||
857 | |||
858 | if (n >= NUM_MTRS_PER_BRANCH) { | ||
859 | debugf0("ERROR: trying to access an invalid csrow: %d\n", | ||
860 | csrow); | ||
861 | return 0; | ||
862 | } | ||
863 | |||
864 | if (channel < CHANNELS_PER_BRANCH) | ||
865 | mtr = pvt->b0_mtr[n]; | ||
866 | else | ||
867 | mtr = pvt->b1_mtr[n]; | ||
868 | |||
869 | return mtr; | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | */ | ||
874 | static void decode_mtr(int slot_row, u16 mtr) | ||
875 | { | ||
876 | int ans; | ||
877 | |||
878 | ans = MTR_DIMMS_PRESENT(mtr); | ||
879 | |||
880 | debugf2("\tMTR%d=0x%x: DIMMs are %s\n", slot_row, mtr, | ||
881 | ans ? "Present" : "NOT Present"); | ||
882 | if (!ans) | ||
883 | return; | ||
884 | |||
885 | debugf2("\t\tWIDTH: x%d\n", MTR_DRAM_WIDTH(mtr)); | ||
886 | |||
887 | debugf2("\t\tELECTRICAL THROTTLING is %s\n", | ||
888 | MTR_DIMMS_ETHROTTLE(mtr) ? "enabled" : "disabled"); | ||
889 | |||
890 | debugf2("\t\tNUMBANK: %d bank(s)\n", MTR_DRAM_BANKS(mtr)); | ||
891 | debugf2("\t\tNUMRANK: %s\n", MTR_DIMM_RANK(mtr) ? "double" : "single"); | ||
892 | debugf2("\t\tNUMROW: %s\n", numrow_toString[MTR_DIMM_ROWS(mtr)]); | ||
893 | debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]); | ||
894 | } | ||
895 | |||
896 | static void handle_channel(struct i5400_pvt *pvt, int csrow, int channel, | ||
897 | struct i5400_dimm_info *dinfo) | ||
898 | { | ||
899 | int mtr; | ||
900 | int amb_present_reg; | ||
901 | int addrBits; | ||
902 | |||
903 | mtr = determine_mtr(pvt, csrow, channel); | ||
904 | if (MTR_DIMMS_PRESENT(mtr)) { | ||
905 | amb_present_reg = determine_amb_present_reg(pvt, channel); | ||
906 | |||
907 | /* Determine if there is a DIMM present in this DIMM slot */ | ||
908 | if (amb_present_reg & (1 << (csrow >> 1))) { | ||
909 | dinfo->dual_rank = MTR_DIMM_RANK(mtr); | ||
910 | |||
911 | if (!((dinfo->dual_rank == 0) && | ||
912 | ((csrow & 0x1) == 0x1))) { | ||
913 | /* Start with the number of bits for a Bank | ||
914 | * on the DRAM */ | ||
915 | addrBits = MTR_DRAM_BANKS_ADDR_BITS(mtr); | ||
916 | /* Add thenumber of ROW bits */ | ||
917 | addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr); | ||
918 | /* add the number of COLUMN bits */ | ||
919 | addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr); | ||
920 | |||
921 | addrBits += 6; /* add 64 bits per DIMM */ | ||
922 | addrBits -= 20; /* divide by 2^^20 */ | ||
923 | addrBits -= 3; /* 8 bits per bytes */ | ||
924 | |||
925 | dinfo->megabytes = 1 << addrBits; | ||
926 | } | ||
927 | } | ||
928 | } | ||
929 | } | ||
930 | |||
931 | /* | ||
932 | * calculate_dimm_size | ||
933 | * | ||
934 | * also will output a DIMM matrix map, if debug is enabled, for viewing | ||
935 | * how the DIMMs are populated | ||
936 | */ | ||
937 | static void calculate_dimm_size(struct i5400_pvt *pvt) | ||
938 | { | ||
939 | struct i5400_dimm_info *dinfo; | ||
940 | int csrow, max_csrows; | ||
941 | char *p, *mem_buffer; | ||
942 | int space, n; | ||
943 | int channel; | ||
944 | |||
945 | /* ================= Generate some debug output ================= */ | ||
946 | space = PAGE_SIZE; | ||
947 | mem_buffer = p = kmalloc(space, GFP_KERNEL); | ||
948 | if (p == NULL) { | ||
949 | i5400_printk(KERN_ERR, "MC: %s:%s() kmalloc() failed\n", | ||
950 | __FILE__, __func__); | ||
951 | return; | ||
952 | } | ||
953 | |||
954 | /* Scan all the actual CSROWS (which is # of DIMMS * 2) | ||
955 | * and calculate the information for each DIMM | ||
956 | * Start with the highest csrow first, to display it first | ||
957 | * and work toward the 0th csrow | ||
958 | */ | ||
959 | max_csrows = pvt->maxdimmperch * 2; | ||
960 | for (csrow = max_csrows - 1; csrow >= 0; csrow--) { | ||
961 | |||
962 | /* on an odd csrow, first output a 'boundary' marker, | ||
963 | * then reset the message buffer */ | ||
964 | if (csrow & 0x1) { | ||
965 | n = snprintf(p, space, "---------------------------" | ||
966 | "--------------------------------"); | ||
967 | p += n; | ||
968 | space -= n; | ||
969 | debugf2("%s\n", mem_buffer); | ||
970 | p = mem_buffer; | ||
971 | space = PAGE_SIZE; | ||
972 | } | ||
973 | n = snprintf(p, space, "csrow %2d ", csrow); | ||
974 | p += n; | ||
975 | space -= n; | ||
976 | |||
977 | for (channel = 0; channel < pvt->maxch; channel++) { | ||
978 | dinfo = &pvt->dimm_info[csrow][channel]; | ||
979 | handle_channel(pvt, csrow, channel, dinfo); | ||
980 | n = snprintf(p, space, "%4d MB | ", dinfo->megabytes); | ||
981 | p += n; | ||
982 | space -= n; | ||
983 | } | ||
984 | debugf2("%s\n", mem_buffer); | ||
985 | p = mem_buffer; | ||
986 | space = PAGE_SIZE; | ||
987 | } | ||
988 | |||
989 | /* Output the last bottom 'boundary' marker */ | ||
990 | n = snprintf(p, space, "---------------------------" | ||
991 | "--------------------------------"); | ||
992 | p += n; | ||
993 | space -= n; | ||
994 | debugf2("%s\n", mem_buffer); | ||
995 | p = mem_buffer; | ||
996 | space = PAGE_SIZE; | ||
997 | |||
998 | /* now output the 'channel' labels */ | ||
999 | n = snprintf(p, space, " "); | ||
1000 | p += n; | ||
1001 | space -= n; | ||
1002 | for (channel = 0; channel < pvt->maxch; channel++) { | ||
1003 | n = snprintf(p, space, "channel %d | ", channel); | ||
1004 | p += n; | ||
1005 | space -= n; | ||
1006 | } | ||
1007 | |||
1008 | /* output the last message and free buffer */ | ||
1009 | debugf2("%s\n", mem_buffer); | ||
1010 | kfree(mem_buffer); | ||
1011 | } | ||
1012 | |||
1013 | /* | ||
1014 | * i5400_get_mc_regs read in the necessary registers and | ||
1015 | * cache locally | ||
1016 | * | ||
1017 | * Fills in the private data members | ||
1018 | */ | ||
1019 | static void i5400_get_mc_regs(struct mem_ctl_info *mci) | ||
1020 | { | ||
1021 | struct i5400_pvt *pvt; | ||
1022 | u32 actual_tolm; | ||
1023 | u16 limit; | ||
1024 | int slot_row; | ||
1025 | int maxch; | ||
1026 | int maxdimmperch; | ||
1027 | int way0, way1; | ||
1028 | |||
1029 | pvt = mci->pvt_info; | ||
1030 | |||
1031 | pci_read_config_dword(pvt->system_address, AMBASE, | ||
1032 | (u32 *) &pvt->ambase); | ||
1033 | pci_read_config_dword(pvt->system_address, AMBASE + sizeof(u32), | ||
1034 | ((u32 *) &pvt->ambase) + sizeof(u32)); | ||
1035 | |||
1036 | maxdimmperch = pvt->maxdimmperch; | ||
1037 | maxch = pvt->maxch; | ||
1038 | |||
1039 | debugf2("AMBASE= 0x%lx MAXCH= %d MAX-DIMM-Per-CH= %d\n", | ||
1040 | (long unsigned int)pvt->ambase, pvt->maxch, pvt->maxdimmperch); | ||
1041 | |||
1042 | /* Get the Branch Map regs */ | ||
1043 | pci_read_config_word(pvt->branchmap_werrors, TOLM, &pvt->tolm); | ||
1044 | pvt->tolm >>= 12; | ||
1045 | debugf2("\nTOLM (number of 256M regions) =%u (0x%x)\n", pvt->tolm, | ||
1046 | pvt->tolm); | ||
1047 | |||
1048 | actual_tolm = (u32) ((1000l * pvt->tolm) >> (30 - 28)); | ||
1049 | debugf2("Actual TOLM byte addr=%u.%03u GB (0x%x)\n", | ||
1050 | actual_tolm/1000, actual_tolm % 1000, pvt->tolm << 28); | ||
1051 | |||
1052 | pci_read_config_word(pvt->branchmap_werrors, MIR0, &pvt->mir0); | ||
1053 | pci_read_config_word(pvt->branchmap_werrors, MIR1, &pvt->mir1); | ||
1054 | |||
1055 | /* Get the MIR[0-1] regs */ | ||
1056 | limit = (pvt->mir0 >> 4) & 0x0fff; | ||
1057 | way0 = pvt->mir0 & 0x1; | ||
1058 | way1 = pvt->mir0 & 0x2; | ||
1059 | debugf2("MIR0: limit= 0x%x WAY1= %u WAY0= %x\n", limit, way1, way0); | ||
1060 | limit = (pvt->mir1 >> 4) & 0xfff; | ||
1061 | way0 = pvt->mir1 & 0x1; | ||
1062 | way1 = pvt->mir1 & 0x2; | ||
1063 | debugf2("MIR1: limit= 0x%x WAY1= %u WAY0= %x\n", limit, way1, way0); | ||
1064 | |||
1065 | /* Get the set of MTR[0-3] regs by each branch */ | ||
1066 | for (slot_row = 0; slot_row < NUM_MTRS_PER_BRANCH; slot_row++) { | ||
1067 | int where = MTR0 + (slot_row * sizeof(u32)); | ||
1068 | |||
1069 | /* Branch 0 set of MTR registers */ | ||
1070 | pci_read_config_word(pvt->branch_0, where, | ||
1071 | &pvt->b0_mtr[slot_row]); | ||
1072 | |||
1073 | debugf2("MTR%d where=0x%x B0 value=0x%x\n", slot_row, where, | ||
1074 | pvt->b0_mtr[slot_row]); | ||
1075 | |||
1076 | if (pvt->maxch < CHANNELS_PER_BRANCH) { | ||
1077 | pvt->b1_mtr[slot_row] = 0; | ||
1078 | continue; | ||
1079 | } | ||
1080 | |||
1081 | /* Branch 1 set of MTR registers */ | ||
1082 | pci_read_config_word(pvt->branch_1, where, | ||
1083 | &pvt->b1_mtr[slot_row]); | ||
1084 | debugf2("MTR%d where=0x%x B1 value=0x%x\n", slot_row, where, | ||
1085 | pvt->b1_mtr[slot_row]); | ||
1086 | } | ||
1087 | |||
1088 | /* Read and dump branch 0's MTRs */ | ||
1089 | debugf2("\nMemory Technology Registers:\n"); | ||
1090 | debugf2(" Branch 0:\n"); | ||
1091 | for (slot_row = 0; slot_row < NUM_MTRS_PER_BRANCH; slot_row++) | ||
1092 | decode_mtr(slot_row, pvt->b0_mtr[slot_row]); | ||
1093 | |||
1094 | pci_read_config_word(pvt->branch_0, AMBPRESENT_0, | ||
1095 | &pvt->b0_ambpresent0); | ||
1096 | debugf2("\t\tAMB-Branch 0-present0 0x%x:\n", pvt->b0_ambpresent0); | ||
1097 | pci_read_config_word(pvt->branch_0, AMBPRESENT_1, | ||
1098 | &pvt->b0_ambpresent1); | ||
1099 | debugf2("\t\tAMB-Branch 0-present1 0x%x:\n", pvt->b0_ambpresent1); | ||
1100 | |||
1101 | /* Only if we have 2 branchs (4 channels) */ | ||
1102 | if (pvt->maxch < CHANNELS_PER_BRANCH) { | ||
1103 | pvt->b1_ambpresent0 = 0; | ||
1104 | pvt->b1_ambpresent1 = 0; | ||
1105 | } else { | ||
1106 | /* Read and dump branch 1's MTRs */ | ||
1107 | debugf2(" Branch 1:\n"); | ||
1108 | for (slot_row = 0; slot_row < NUM_MTRS_PER_BRANCH; slot_row++) | ||
1109 | decode_mtr(slot_row, pvt->b1_mtr[slot_row]); | ||
1110 | |||
1111 | pci_read_config_word(pvt->branch_1, AMBPRESENT_0, | ||
1112 | &pvt->b1_ambpresent0); | ||
1113 | debugf2("\t\tAMB-Branch 1-present0 0x%x:\n", | ||
1114 | pvt->b1_ambpresent0); | ||
1115 | pci_read_config_word(pvt->branch_1, AMBPRESENT_1, | ||
1116 | &pvt->b1_ambpresent1); | ||
1117 | debugf2("\t\tAMB-Branch 1-present1 0x%x:\n", | ||
1118 | pvt->b1_ambpresent1); | ||
1119 | } | ||
1120 | |||
1121 | /* Go and determine the size of each DIMM and place in an | ||
1122 | * orderly matrix */ | ||
1123 | calculate_dimm_size(pvt); | ||
1124 | } | ||
1125 | |||
1126 | /* | ||
1127 | * i5400_init_csrows Initialize the 'csrows' table within | ||
1128 | * the mci control structure with the | ||
1129 | * addressing of memory. | ||
1130 | * | ||
1131 | * return: | ||
1132 | * 0 success | ||
1133 | * 1 no actual memory found on this MC | ||
1134 | */ | ||
1135 | static int i5400_init_csrows(struct mem_ctl_info *mci) | ||
1136 | { | ||
1137 | struct i5400_pvt *pvt; | ||
1138 | struct csrow_info *p_csrow; | ||
1139 | int empty, channel_count; | ||
1140 | int max_csrows; | ||
1141 | int mtr; | ||
1142 | int csrow_megs; | ||
1143 | int channel; | ||
1144 | int csrow; | ||
1145 | |||
1146 | pvt = mci->pvt_info; | ||
1147 | |||
1148 | channel_count = pvt->maxch; | ||
1149 | max_csrows = pvt->maxdimmperch * 2; | ||
1150 | |||
1151 | empty = 1; /* Assume NO memory */ | ||
1152 | |||
1153 | for (csrow = 0; csrow < max_csrows; csrow++) { | ||
1154 | p_csrow = &mci->csrows[csrow]; | ||
1155 | |||
1156 | p_csrow->csrow_idx = csrow; | ||
1157 | |||
1158 | /* use branch 0 for the basis */ | ||
1159 | mtr = determine_mtr(pvt, csrow, 0); | ||
1160 | |||
1161 | /* if no DIMMS on this row, continue */ | ||
1162 | if (!MTR_DIMMS_PRESENT(mtr)) | ||
1163 | continue; | ||
1164 | |||
1165 | /* FAKE OUT VALUES, FIXME */ | ||
1166 | p_csrow->first_page = 0 + csrow * 20; | ||
1167 | p_csrow->last_page = 9 + csrow * 20; | ||
1168 | p_csrow->page_mask = 0xFFF; | ||
1169 | |||
1170 | p_csrow->grain = 8; | ||
1171 | |||
1172 | csrow_megs = 0; | ||
1173 | for (channel = 0; channel < pvt->maxch; channel++) | ||
1174 | csrow_megs += pvt->dimm_info[csrow][channel].megabytes; | ||
1175 | |||
1176 | p_csrow->nr_pages = csrow_megs << 8; | ||
1177 | |||
1178 | /* Assume DDR2 for now */ | ||
1179 | p_csrow->mtype = MEM_FB_DDR2; | ||
1180 | |||
1181 | /* ask what device type on this row */ | ||
1182 | if (MTR_DRAM_WIDTH(mtr)) | ||
1183 | p_csrow->dtype = DEV_X8; | ||
1184 | else | ||
1185 | p_csrow->dtype = DEV_X4; | ||
1186 | |||
1187 | p_csrow->edac_mode = EDAC_S8ECD8ED; | ||
1188 | |||
1189 | empty = 0; | ||
1190 | } | ||
1191 | |||
1192 | return empty; | ||
1193 | } | ||
1194 | |||
1195 | /* | ||
1196 | * i5400_enable_error_reporting | ||
1197 | * Turn on the memory reporting features of the hardware | ||
1198 | */ | ||
1199 | static void i5400_enable_error_reporting(struct mem_ctl_info *mci) | ||
1200 | { | ||
1201 | struct i5400_pvt *pvt; | ||
1202 | u32 fbd_error_mask; | ||
1203 | |||
1204 | pvt = mci->pvt_info; | ||
1205 | |||
1206 | /* Read the FBD Error Mask Register */ | ||
1207 | pci_read_config_dword(pvt->branchmap_werrors, EMASK_FBD, | ||
1208 | &fbd_error_mask); | ||
1209 | |||
1210 | /* Enable with a '0' */ | ||
1211 | fbd_error_mask &= ~(ENABLE_EMASK_ALL); | ||
1212 | |||
1213 | pci_write_config_dword(pvt->branchmap_werrors, EMASK_FBD, | ||
1214 | fbd_error_mask); | ||
1215 | } | ||
1216 | |||
1217 | /* | ||
1218 | * i5400_get_dimm_and_channel_counts(pdev, &num_csrows, &num_channels) | ||
1219 | * | ||
1220 | * ask the device how many channels are present and how many CSROWS | ||
1221 | * as well | ||
1222 | */ | ||
1223 | static void i5400_get_dimm_and_channel_counts(struct pci_dev *pdev, | ||
1224 | int *num_dimms_per_channel, | ||
1225 | int *num_channels) | ||
1226 | { | ||
1227 | u8 value; | ||
1228 | |||
1229 | /* Need to retrieve just how many channels and dimms per channel are | ||
1230 | * supported on this memory controller | ||
1231 | */ | ||
1232 | pci_read_config_byte(pdev, MAXDIMMPERCH, &value); | ||
1233 | *num_dimms_per_channel = (int)value * 2; | ||
1234 | |||
1235 | pci_read_config_byte(pdev, MAXCH, &value); | ||
1236 | *num_channels = (int)value; | ||
1237 | } | ||
1238 | |||
1239 | /* | ||
1240 | * i5400_probe1 Probe for ONE instance of device to see if it is | ||
1241 | * present. | ||
1242 | * return: | ||
1243 | * 0 for FOUND a device | ||
1244 | * < 0 for error code | ||
1245 | */ | ||
1246 | static int i5400_probe1(struct pci_dev *pdev, int dev_idx) | ||
1247 | { | ||
1248 | struct mem_ctl_info *mci; | ||
1249 | struct i5400_pvt *pvt; | ||
1250 | int num_channels; | ||
1251 | int num_dimms_per_channel; | ||
1252 | int num_csrows; | ||
1253 | |||
1254 | if (dev_idx >= ARRAY_SIZE(i5400_devs)) | ||
1255 | return -EINVAL; | ||
1256 | |||
1257 | debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", | ||
1258 | __func__, | ||
1259 | pdev->bus->number, | ||
1260 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); | ||
1261 | |||
1262 | /* We only are looking for func 0 of the set */ | ||
1263 | if (PCI_FUNC(pdev->devfn) != 0) | ||
1264 | return -ENODEV; | ||
1265 | |||
1266 | /* Ask the devices for the number of CSROWS and CHANNELS so | ||
1267 | * that we can calculate the memory resources, etc | ||
1268 | * | ||
1269 | * The Chipset will report what it can handle which will be greater | ||
1270 | * or equal to what the motherboard manufacturer will implement. | ||
1271 | * | ||
1272 | * As we don't have a motherboard identification routine to determine | ||
1273 | * actual number of slots/dimms per channel, we thus utilize the | ||
1274 | * resource as specified by the chipset. Thus, we might have | ||
1275 | * have more DIMMs per channel than actually on the mobo, but this | ||
1276 | * allows the driver to support upto the chipset max, without | ||
1277 | * some fancy mobo determination. | ||
1278 | */ | ||
1279 | i5400_get_dimm_and_channel_counts(pdev, &num_dimms_per_channel, | ||
1280 | &num_channels); | ||
1281 | num_csrows = num_dimms_per_channel * 2; | ||
1282 | |||
1283 | debugf0("MC: %s(): Number of - Channels= %d DIMMS= %d CSROWS= %d\n", | ||
1284 | __func__, num_channels, num_dimms_per_channel, num_csrows); | ||
1285 | |||
1286 | /* allocate a new MC control structure */ | ||
1287 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); | ||
1288 | |||
1289 | if (mci == NULL) | ||
1290 | return -ENOMEM; | ||
1291 | |||
1292 | debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci); | ||
1293 | |||
1294 | mci->dev = &pdev->dev; /* record ptr to the generic device */ | ||
1295 | |||
1296 | pvt = mci->pvt_info; | ||
1297 | pvt->system_address = pdev; /* Record this device in our private */ | ||
1298 | pvt->maxch = num_channels; | ||
1299 | pvt->maxdimmperch = num_dimms_per_channel; | ||
1300 | |||
1301 | /* 'get' the pci devices we want to reserve for our use */ | ||
1302 | if (i5400_get_devices(mci, dev_idx)) | ||
1303 | goto fail0; | ||
1304 | |||
1305 | /* Time to get serious */ | ||
1306 | i5400_get_mc_regs(mci); /* retrieve the hardware registers */ | ||
1307 | |||
1308 | mci->mc_idx = 0; | ||
1309 | mci->mtype_cap = MEM_FLAG_FB_DDR2; | ||
1310 | mci->edac_ctl_cap = EDAC_FLAG_NONE; | ||
1311 | mci->edac_cap = EDAC_FLAG_NONE; | ||
1312 | mci->mod_name = "i5400_edac.c"; | ||
1313 | mci->mod_ver = I5400_REVISION; | ||
1314 | mci->ctl_name = i5400_devs[dev_idx].ctl_name; | ||
1315 | mci->dev_name = pci_name(pdev); | ||
1316 | mci->ctl_page_to_phys = NULL; | ||
1317 | |||
1318 | /* Set the function pointer to an actual operation function */ | ||
1319 | mci->edac_check = i5400_check_error; | ||
1320 | |||
1321 | /* initialize the MC control structure 'csrows' table | ||
1322 | * with the mapping and control information */ | ||
1323 | if (i5400_init_csrows(mci)) { | ||
1324 | debugf0("MC: Setting mci->edac_cap to EDAC_FLAG_NONE\n" | ||
1325 | " because i5400_init_csrows() returned nonzero " | ||
1326 | "value\n"); | ||
1327 | mci->edac_cap = EDAC_FLAG_NONE; /* no csrows found */ | ||
1328 | } else { | ||
1329 | debugf1("MC: Enable error reporting now\n"); | ||
1330 | i5400_enable_error_reporting(mci); | ||
1331 | } | ||
1332 | |||
1333 | /* add this new MC control structure to EDAC's list of MCs */ | ||
1334 | if (edac_mc_add_mc(mci)) { | ||
1335 | debugf0("MC: " __FILE__ | ||
1336 | ": %s(): failed edac_mc_add_mc()\n", __func__); | ||
1337 | /* FIXME: perhaps some code should go here that disables error | ||
1338 | * reporting if we just enabled it | ||
1339 | */ | ||
1340 | goto fail1; | ||
1341 | } | ||
1342 | |||
1343 | i5400_clear_error(mci); | ||
1344 | |||
1345 | /* allocating generic PCI control info */ | ||
1346 | i5400_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); | ||
1347 | if (!i5400_pci) { | ||
1348 | printk(KERN_WARNING | ||
1349 | "%s(): Unable to create PCI control\n", | ||
1350 | __func__); | ||
1351 | printk(KERN_WARNING | ||
1352 | "%s(): PCI error report via EDAC not setup\n", | ||
1353 | __func__); | ||
1354 | } | ||
1355 | |||
1356 | return 0; | ||
1357 | |||
1358 | /* Error exit unwinding stack */ | ||
1359 | fail1: | ||
1360 | |||
1361 | i5400_put_devices(mci); | ||
1362 | |||
1363 | fail0: | ||
1364 | edac_mc_free(mci); | ||
1365 | return -ENODEV; | ||
1366 | } | ||
1367 | |||
1368 | /* | ||
1369 | * i5400_init_one constructor for one instance of device | ||
1370 | * | ||
1371 | * returns: | ||
1372 | * negative on error | ||
1373 | * count (>= 0) | ||
1374 | */ | ||
1375 | static int __devinit i5400_init_one(struct pci_dev *pdev, | ||
1376 | const struct pci_device_id *id) | ||
1377 | { | ||
1378 | int rc; | ||
1379 | |||
1380 | debugf0("MC: " __FILE__ ": %s()\n", __func__); | ||
1381 | |||
1382 | /* wake up device */ | ||
1383 | rc = pci_enable_device(pdev); | ||
1384 | if (rc == -EIO) | ||
1385 | return rc; | ||
1386 | |||
1387 | /* now probe and enable the device */ | ||
1388 | return i5400_probe1(pdev, id->driver_data); | ||
1389 | } | ||
1390 | |||
1391 | /* | ||
1392 | * i5400_remove_one destructor for one instance of device | ||
1393 | * | ||
1394 | */ | ||
1395 | static void __devexit i5400_remove_one(struct pci_dev *pdev) | ||
1396 | { | ||
1397 | struct mem_ctl_info *mci; | ||
1398 | |||
1399 | debugf0(__FILE__ ": %s()\n", __func__); | ||
1400 | |||
1401 | if (i5400_pci) | ||
1402 | edac_pci_release_generic_ctl(i5400_pci); | ||
1403 | |||
1404 | mci = edac_mc_del_mc(&pdev->dev); | ||
1405 | if (!mci) | ||
1406 | return; | ||
1407 | |||
1408 | /* retrieve references to resources, and free those resources */ | ||
1409 | i5400_put_devices(mci); | ||
1410 | |||
1411 | edac_mc_free(mci); | ||
1412 | } | ||
1413 | |||
1414 | /* | ||
1415 | * pci_device_id table for which devices we are looking for | ||
1416 | * | ||
1417 | * The "E500P" device is the first device supported. | ||
1418 | */ | ||
1419 | static const struct pci_device_id i5400_pci_tbl[] __devinitdata = { | ||
1420 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR)}, | ||
1421 | {0,} /* 0 terminated list. */ | ||
1422 | }; | ||
1423 | |||
1424 | MODULE_DEVICE_TABLE(pci, i5400_pci_tbl); | ||
1425 | |||
1426 | /* | ||
1427 | * i5400_driver pci_driver structure for this module | ||
1428 | * | ||
1429 | */ | ||
1430 | static struct pci_driver i5400_driver = { | ||
1431 | .name = "i5400_edac", | ||
1432 | .probe = i5400_init_one, | ||
1433 | .remove = __devexit_p(i5400_remove_one), | ||
1434 | .id_table = i5400_pci_tbl, | ||
1435 | }; | ||
1436 | |||
1437 | /* | ||
1438 | * i5400_init Module entry function | ||
1439 | * Try to initialize this module for its devices | ||
1440 | */ | ||
1441 | static int __init i5400_init(void) | ||
1442 | { | ||
1443 | int pci_rc; | ||
1444 | |||
1445 | debugf2("MC: " __FILE__ ": %s()\n", __func__); | ||
1446 | |||
1447 | /* Ensure that the OPSTATE is set correctly for POLL or NMI */ | ||
1448 | opstate_init(); | ||
1449 | |||
1450 | pci_rc = pci_register_driver(&i5400_driver); | ||
1451 | |||
1452 | return (pci_rc < 0) ? pci_rc : 0; | ||
1453 | } | ||
1454 | |||
1455 | /* | ||
1456 | * i5400_exit() Module exit function | ||
1457 | * Unregister the driver | ||
1458 | */ | ||
1459 | static void __exit i5400_exit(void) | ||
1460 | { | ||
1461 | debugf2("MC: " __FILE__ ": %s()\n", __func__); | ||
1462 | pci_unregister_driver(&i5400_driver); | ||
1463 | } | ||
1464 | |||
1465 | module_init(i5400_init); | ||
1466 | module_exit(i5400_exit); | ||
1467 | |||
1468 | MODULE_LICENSE("GPL"); | ||
1469 | MODULE_AUTHOR("Ben Woodard <woodard@redhat.com>"); | ||
1470 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
1471 | MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)"); | ||
1472 | MODULE_DESCRIPTION("MC Driver for Intel I5400 memory controllers - " | ||
1473 | I5400_REVISION); | ||
1474 | |||
1475 | module_param(edac_op_state, int, 0444); | ||
1476 | MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); | ||
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index ebb037b78758..b2d83b95033d 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
@@ -311,9 +311,7 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev, | |||
311 | } | 311 | } |
312 | 312 | ||
313 | /* cache is irrelevant for PCI bus reads/writes */ | 313 | /* cache is irrelevant for PCI bus reads/writes */ |
314 | window = ioremap_nocache(pci_resource_start(dev, 0), | 314 | window = pci_ioremap_bar(dev, 0); |
315 | pci_resource_len(dev, 0)); | ||
316 | |||
317 | if (window == NULL) { | 315 | if (window == NULL) { |
318 | i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n", | 316 | i82875p_printk(KERN_ERR, "%s(): Failed to ioremap bar6\n", |
319 | __func__); | 317 | __func__); |
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 0cfcb2d075a0..853ef37ec006 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c | |||
@@ -630,27 +630,22 @@ static int mpc85xx_l2_err_remove(struct of_device *op) | |||
630 | } | 630 | } |
631 | 631 | ||
632 | static struct of_device_id mpc85xx_l2_err_of_match[] = { | 632 | static struct of_device_id mpc85xx_l2_err_of_match[] = { |
633 | { | 633 | /* deprecate the fsl,85.. forms in the future, 2.6.30? */ |
634 | .compatible = "fsl,8540-l2-cache-controller", | 634 | { .compatible = "fsl,8540-l2-cache-controller", }, |
635 | }, | 635 | { .compatible = "fsl,8541-l2-cache-controller", }, |
636 | { | 636 | { .compatible = "fsl,8544-l2-cache-controller", }, |
637 | .compatible = "fsl,8541-l2-cache-controller", | 637 | { .compatible = "fsl,8548-l2-cache-controller", }, |
638 | }, | 638 | { .compatible = "fsl,8555-l2-cache-controller", }, |
639 | { | 639 | { .compatible = "fsl,8568-l2-cache-controller", }, |
640 | .compatible = "fsl,8544-l2-cache-controller", | 640 | { .compatible = "fsl,mpc8536-l2-cache-controller", }, |
641 | }, | 641 | { .compatible = "fsl,mpc8540-l2-cache-controller", }, |
642 | { | 642 | { .compatible = "fsl,mpc8541-l2-cache-controller", }, |
643 | .compatible = "fsl,8548-l2-cache-controller", | 643 | { .compatible = "fsl,mpc8544-l2-cache-controller", }, |
644 | }, | 644 | { .compatible = "fsl,mpc8548-l2-cache-controller", }, |
645 | { | 645 | { .compatible = "fsl,mpc8555-l2-cache-controller", }, |
646 | .compatible = "fsl,8555-l2-cache-controller", | 646 | { .compatible = "fsl,mpc8560-l2-cache-controller", }, |
647 | }, | 647 | { .compatible = "fsl,mpc8568-l2-cache-controller", }, |
648 | { | 648 | { .compatible = "fsl,mpc8572-l2-cache-controller", }, |
649 | .compatible = "fsl,8568-l2-cache-controller", | ||
650 | }, | ||
651 | { | ||
652 | .compatible = "fsl,mpc8572-l2-cache-controller", | ||
653 | }, | ||
654 | {}, | 649 | {}, |
655 | }; | 650 | }; |
656 | 651 | ||
@@ -967,27 +962,22 @@ static int mpc85xx_mc_err_remove(struct of_device *op) | |||
967 | } | 962 | } |
968 | 963 | ||
969 | static struct of_device_id mpc85xx_mc_err_of_match[] = { | 964 | static struct of_device_id mpc85xx_mc_err_of_match[] = { |
970 | { | 965 | /* deprecate the fsl,85.. forms in the future, 2.6.30? */ |
971 | .compatible = "fsl,8540-memory-controller", | 966 | { .compatible = "fsl,8540-memory-controller", }, |
972 | }, | 967 | { .compatible = "fsl,8541-memory-controller", }, |
973 | { | 968 | { .compatible = "fsl,8544-memory-controller", }, |
974 | .compatible = "fsl,8541-memory-controller", | 969 | { .compatible = "fsl,8548-memory-controller", }, |
975 | }, | 970 | { .compatible = "fsl,8555-memory-controller", }, |
976 | { | 971 | { .compatible = "fsl,8568-memory-controller", }, |
977 | .compatible = "fsl,8544-memory-controller", | 972 | { .compatible = "fsl,mpc8536-memory-controller", }, |
978 | }, | 973 | { .compatible = "fsl,mpc8540-memory-controller", }, |
979 | { | 974 | { .compatible = "fsl,mpc8541-memory-controller", }, |
980 | .compatible = "fsl,8548-memory-controller", | 975 | { .compatible = "fsl,mpc8544-memory-controller", }, |
981 | }, | 976 | { .compatible = "fsl,mpc8548-memory-controller", }, |
982 | { | 977 | { .compatible = "fsl,mpc8555-memory-controller", }, |
983 | .compatible = "fsl,8555-memory-controller", | 978 | { .compatible = "fsl,mpc8560-memory-controller", }, |
984 | }, | 979 | { .compatible = "fsl,mpc8568-memory-controller", }, |
985 | { | 980 | { .compatible = "fsl,mpc8572-memory-controller", }, |
986 | .compatible = "fsl,8568-memory-controller", | ||
987 | }, | ||
988 | { | ||
989 | .compatible = "fsl,mpc8572-memory-controller", | ||
990 | }, | ||
991 | {}, | 981 | {}, |
992 | }; | 982 | }; |
993 | 983 | ||
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 78b989d202a3..d76adfea5df7 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c | |||
@@ -468,8 +468,8 @@ const char *dmi_get_system_info(int field) | |||
468 | EXPORT_SYMBOL(dmi_get_system_info); | 468 | EXPORT_SYMBOL(dmi_get_system_info); |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * dmi_name_in_serial - Check if string is in the DMI product serial | 471 | * dmi_name_in_serial - Check if string is in the DMI product serial information |
472 | * information. | 472 | * @str: string to check for |
473 | */ | 473 | */ |
474 | int dmi_name_in_serial(const char *str) | 474 | int dmi_name_in_serial(const char *str) |
475 | { | 475 | { |
@@ -585,6 +585,8 @@ EXPORT_SYMBOL_GPL(dmi_walk); | |||
585 | 585 | ||
586 | /** | 586 | /** |
587 | * dmi_match - compare a string to the dmi field (if exists) | 587 | * dmi_match - compare a string to the dmi field (if exists) |
588 | * @f: DMI field identifier | ||
589 | * @str: string to compare the DMI field to | ||
588 | * | 590 | * |
589 | * Returns true if the requested field equals to the str (including NULL). | 591 | * Returns true if the requested field equals to the str (including NULL). |
590 | */ | 592 | */ |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 48f49d93d249..3d2565441b36 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -95,7 +95,7 @@ config GPIO_MAX732X | |||
95 | number for these GPIOs. | 95 | number for these GPIOs. |
96 | 96 | ||
97 | config GPIO_PCA953X | 97 | config GPIO_PCA953X |
98 | tristate "PCA953x, PCA955x, and MAX7310 I/O ports" | 98 | tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" |
99 | depends on I2C | 99 | depends on I2C |
100 | help | 100 | help |
101 | Say yes here to provide access to several register-oriented | 101 | Say yes here to provide access to several register-oriented |
@@ -104,9 +104,10 @@ config GPIO_PCA953X | |||
104 | 104 | ||
105 | 4 bits: pca9536, pca9537 | 105 | 4 bits: pca9536, pca9537 |
106 | 106 | ||
107 | 8 bits: max7310, pca9534, pca9538, pca9554, pca9557 | 107 | 8 bits: max7310, pca9534, pca9538, pca9554, pca9557, |
108 | tca6408 | ||
108 | 109 | ||
109 | 16 bits: pca9535, pca9539, pca9555 | 110 | 16 bits: pca9535, pca9539, pca9555, tca6416 |
110 | 111 | ||
111 | This driver can also be built as a module. If so, the module | 112 | This driver can also be built as a module. If so, the module |
112 | will be called pca953x. | 113 | will be called pca953x. |
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 9ceeb89f1325..37f35388a2ae 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -33,7 +33,12 @@ static const struct i2c_device_id pca953x_id[] = { | |||
33 | { "pca9554", 8, }, | 33 | { "pca9554", 8, }, |
34 | { "pca9555", 16, }, | 34 | { "pca9555", 16, }, |
35 | { "pca9557", 8, }, | 35 | { "pca9557", 8, }, |
36 | |||
36 | { "max7310", 8, }, | 37 | { "max7310", 8, }, |
38 | { "pca6107", 8, }, | ||
39 | { "tca6408", 8, }, | ||
40 | { "tca6416", 16, }, | ||
41 | /* NYET: { "tca6424", 24, }, */ | ||
37 | { } | 42 | { } |
38 | }; | 43 | }; |
39 | MODULE_DEVICE_TABLE(i2c, pca953x_id); | 44 | MODULE_DEVICE_TABLE(i2c, pca953x_id); |
@@ -47,9 +52,6 @@ struct pca953x_chip { | |||
47 | struct gpio_chip gpio_chip; | 52 | struct gpio_chip gpio_chip; |
48 | }; | 53 | }; |
49 | 54 | ||
50 | /* NOTE: we can't currently rely on fault codes to come from SMBus | ||
51 | * calls, so we map all errors to EIO here and return zero otherwise. | ||
52 | */ | ||
53 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | 55 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) |
54 | { | 56 | { |
55 | int ret; | 57 | int ret; |
@@ -61,7 +63,7 @@ static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | |||
61 | 63 | ||
62 | if (ret < 0) { | 64 | if (ret < 0) { |
63 | dev_err(&chip->client->dev, "failed writing register\n"); | 65 | dev_err(&chip->client->dev, "failed writing register\n"); |
64 | return -EIO; | 66 | return ret; |
65 | } | 67 | } |
66 | 68 | ||
67 | return 0; | 69 | return 0; |
@@ -78,7 +80,7 @@ static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) | |||
78 | 80 | ||
79 | if (ret < 0) { | 81 | if (ret < 0) { |
80 | dev_err(&chip->client->dev, "failed reading register\n"); | 82 | dev_err(&chip->client->dev, "failed reading register\n"); |
81 | return -EIO; | 83 | return ret; |
82 | } | 84 | } |
83 | 85 | ||
84 | *val = (uint16_t)ret; | 86 | *val = (uint16_t)ret; |
diff --git a/drivers/gpio/twl4030-gpio.c b/drivers/gpio/twl4030-gpio.c index 37d3eec8730a..afad14792141 100644 --- a/drivers/gpio/twl4030-gpio.c +++ b/drivers/gpio/twl4030-gpio.c | |||
@@ -202,37 +202,6 @@ static int twl4030_get_gpio_datain(int gpio) | |||
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Configure debounce timing value for a GPIO pin on TWL4030 | ||
207 | */ | ||
208 | int twl4030_set_gpio_debounce(int gpio, int enable) | ||
209 | { | ||
210 | u8 d_bnk = gpio >> 3; | ||
211 | u8 d_msk = BIT(gpio & 0x7); | ||
212 | u8 reg = 0; | ||
213 | u8 base = 0; | ||
214 | int ret = 0; | ||
215 | |||
216 | if (unlikely((gpio >= TWL4030_GPIO_MAX) | ||
217 | || !(gpio_usage_count & BIT(gpio)))) | ||
218 | return -EPERM; | ||
219 | |||
220 | base = REG_GPIO_DEBEN1 + d_bnk; | ||
221 | mutex_lock(&gpio_lock); | ||
222 | ret = gpio_twl4030_read(base); | ||
223 | if (ret >= 0) { | ||
224 | if (enable) | ||
225 | reg = ret | d_msk; | ||
226 | else | ||
227 | reg = ret & ~d_msk; | ||
228 | |||
229 | ret = gpio_twl4030_write(base, reg); | ||
230 | } | ||
231 | mutex_unlock(&gpio_lock); | ||
232 | return ret; | ||
233 | } | ||
234 | EXPORT_SYMBOL(twl4030_set_gpio_debounce); | ||
235 | |||
236 | /*----------------------------------------------------------------------*/ | 205 | /*----------------------------------------------------------------------*/ |
237 | 206 | ||
238 | static int twl_request(struct gpio_chip *chip, unsigned offset) | 207 | static int twl_request(struct gpio_chip *chip, unsigned offset) |
@@ -405,6 +374,23 @@ static int __devinit gpio_twl4030_pulls(u32 ups, u32 downs) | |||
405 | REG_GPIOPUPDCTR1, 5); | 374 | REG_GPIOPUPDCTR1, 5); |
406 | } | 375 | } |
407 | 376 | ||
377 | static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) | ||
378 | { | ||
379 | u8 message[4]; | ||
380 | |||
381 | /* 30 msec of debouncing is always used for MMC card detect, | ||
382 | * and is optional for everything else. | ||
383 | */ | ||
384 | message[1] = (debounce & 0xff) | (mmc_cd & 0x03); | ||
385 | debounce >>= 8; | ||
386 | message[2] = (debounce & 0xff); | ||
387 | debounce >>= 8; | ||
388 | message[3] = (debounce & 0x03); | ||
389 | |||
390 | return twl4030_i2c_write(TWL4030_MODULE_GPIO, message, | ||
391 | REG_GPIO_DEBEN1, 3); | ||
392 | } | ||
393 | |||
408 | static int gpio_twl4030_remove(struct platform_device *pdev); | 394 | static int gpio_twl4030_remove(struct platform_device *pdev); |
409 | 395 | ||
410 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) | 396 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) |
@@ -439,6 +425,12 @@ no_irqs: | |||
439 | pdata->pullups, pdata->pulldowns, | 425 | pdata->pullups, pdata->pulldowns, |
440 | ret); | 426 | ret); |
441 | 427 | ||
428 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
429 | if (ret) | ||
430 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
431 | pdata->debounce, pdata->mmc_cd, | ||
432 | ret); | ||
433 | |||
442 | twl_gpiochip.base = pdata->gpio_base; | 434 | twl_gpiochip.base = pdata->gpio_base; |
443 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; | 435 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; |
444 | twl_gpiochip.dev = &pdev->dev; | 436 | twl_gpiochip.dev = &pdev->dev; |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3733e36d135e..b06a53715853 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -183,6 +183,10 @@ int drm_stub_open(struct inode *inode, struct file *filp) | |||
183 | 183 | ||
184 | old_fops = filp->f_op; | 184 | old_fops = filp->f_op; |
185 | filp->f_op = fops_get(&dev->driver->fops); | 185 | filp->f_op = fops_get(&dev->driver->fops); |
186 | if (filp->f_op == NULL) { | ||
187 | filp->f_op = old_fops; | ||
188 | goto out; | ||
189 | } | ||
186 | if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { | 190 | if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) { |
187 | fops_put(filp->f_op); | 191 | fops_put(filp->f_op); |
188 | filp->f_op = fops_get(old_fops); | 192 | filp->f_op = fops_get(old_fops); |
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c index 66107b4dc12a..1852f27bac51 100644 --- a/drivers/hwmon/adt7462.c +++ b/drivers/hwmon/adt7462.c | |||
@@ -204,8 +204,6 @@ I2C_CLIENT_INSMOD_1(adt7462); | |||
204 | #define MASK_AND_SHIFT(value, prefix) \ | 204 | #define MASK_AND_SHIFT(value, prefix) \ |
205 | (((value) & prefix##_MASK) >> prefix##_SHIFT) | 205 | (((value) & prefix##_MASK) >> prefix##_SHIFT) |
206 | 206 | ||
207 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
208 | |||
209 | struct adt7462_data { | 207 | struct adt7462_data { |
210 | struct device *hwmon_dev; | 208 | struct device *hwmon_dev; |
211 | struct attribute_group attrs; | 209 | struct attribute_group attrs; |
@@ -840,7 +838,7 @@ static ssize_t set_temp_min(struct device *dev, | |||
840 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | 838 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) |
841 | return -EINVAL; | 839 | return -EINVAL; |
842 | 840 | ||
843 | temp = ROUND_DIV(temp, 1000) + 64; | 841 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
844 | temp = SENSORS_LIMIT(temp, 0, 255); | 842 | temp = SENSORS_LIMIT(temp, 0, 255); |
845 | 843 | ||
846 | mutex_lock(&data->lock); | 844 | mutex_lock(&data->lock); |
@@ -878,7 +876,7 @@ static ssize_t set_temp_max(struct device *dev, | |||
878 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | 876 | if (strict_strtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) |
879 | return -EINVAL; | 877 | return -EINVAL; |
880 | 878 | ||
881 | temp = ROUND_DIV(temp, 1000) + 64; | 879 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
882 | temp = SENSORS_LIMIT(temp, 0, 255); | 880 | temp = SENSORS_LIMIT(temp, 0, 255); |
883 | 881 | ||
884 | mutex_lock(&data->lock); | 882 | mutex_lock(&data->lock); |
@@ -943,7 +941,7 @@ static ssize_t set_volt_max(struct device *dev, | |||
943 | return -EINVAL; | 941 | return -EINVAL; |
944 | 942 | ||
945 | temp *= 1000; /* convert mV to uV */ | 943 | temp *= 1000; /* convert mV to uV */ |
946 | temp = ROUND_DIV(temp, x); | 944 | temp = DIV_ROUND_CLOSEST(temp, x); |
947 | temp = SENSORS_LIMIT(temp, 0, 255); | 945 | temp = SENSORS_LIMIT(temp, 0, 255); |
948 | 946 | ||
949 | mutex_lock(&data->lock); | 947 | mutex_lock(&data->lock); |
@@ -985,7 +983,7 @@ static ssize_t set_volt_min(struct device *dev, | |||
985 | return -EINVAL; | 983 | return -EINVAL; |
986 | 984 | ||
987 | temp *= 1000; /* convert mV to uV */ | 985 | temp *= 1000; /* convert mV to uV */ |
988 | temp = ROUND_DIV(temp, x); | 986 | temp = DIV_ROUND_CLOSEST(temp, x); |
989 | temp = SENSORS_LIMIT(temp, 0, 255); | 987 | temp = SENSORS_LIMIT(temp, 0, 255); |
990 | 988 | ||
991 | mutex_lock(&data->lock); | 989 | mutex_lock(&data->lock); |
@@ -1250,7 +1248,7 @@ static ssize_t set_pwm_hyst(struct device *dev, | |||
1250 | if (strict_strtol(buf, 10, &temp)) | 1248 | if (strict_strtol(buf, 10, &temp)) |
1251 | return -EINVAL; | 1249 | return -EINVAL; |
1252 | 1250 | ||
1253 | temp = ROUND_DIV(temp, 1000); | 1251 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
1254 | temp = SENSORS_LIMIT(temp, 0, 15); | 1252 | temp = SENSORS_LIMIT(temp, 0, 15); |
1255 | 1253 | ||
1256 | /* package things up */ | 1254 | /* package things up */ |
@@ -1337,7 +1335,7 @@ static ssize_t set_pwm_tmin(struct device *dev, | |||
1337 | if (strict_strtol(buf, 10, &temp)) | 1335 | if (strict_strtol(buf, 10, &temp)) |
1338 | return -EINVAL; | 1336 | return -EINVAL; |
1339 | 1337 | ||
1340 | temp = ROUND_DIV(temp, 1000) + 64; | 1338 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
1341 | temp = SENSORS_LIMIT(temp, 0, 255); | 1339 | temp = SENSORS_LIMIT(temp, 0, 255); |
1342 | 1340 | ||
1343 | mutex_lock(&data->lock); | 1341 | mutex_lock(&data->lock); |
diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index 1311a595147e..633e1a1e9d79 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/log2.h> | 30 | #include <linux/log2.h> |
31 | #include <linux/kthread.h> | ||
31 | 32 | ||
32 | /* Addresses to scan */ | 33 | /* Addresses to scan */ |
33 | static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; | 34 | static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END }; |
@@ -74,6 +75,7 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
74 | #define ADT7470_REG_PWM12_CFG 0x68 | 75 | #define ADT7470_REG_PWM12_CFG 0x68 |
75 | #define ADT7470_PWM2_AUTO_MASK 0x40 | 76 | #define ADT7470_PWM2_AUTO_MASK 0x40 |
76 | #define ADT7470_PWM1_AUTO_MASK 0x80 | 77 | #define ADT7470_PWM1_AUTO_MASK 0x80 |
78 | #define ADT7470_PWM_AUTO_MASK 0xC0 | ||
77 | #define ADT7470_REG_PWM34_CFG 0x69 | 79 | #define ADT7470_REG_PWM34_CFG 0x69 |
78 | #define ADT7470_PWM3_AUTO_MASK 0x40 | 80 | #define ADT7470_PWM3_AUTO_MASK 0x40 |
79 | #define ADT7470_PWM4_AUTO_MASK 0x80 | 81 | #define ADT7470_PWM4_AUTO_MASK 0x80 |
@@ -128,8 +130,11 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
128 | /* How often do we reread sensor limit values? (In jiffies) */ | 130 | /* How often do we reread sensor limit values? (In jiffies) */ |
129 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | 131 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) |
130 | 132 | ||
131 | /* sleep 1s while gathering temperature data */ | 133 | /* Wait at least 200ms per sensor for 10 sensors */ |
132 | #define TEMP_COLLECTION_TIME 1000 | 134 | #define TEMP_COLLECTION_TIME 2000 |
135 | |||
136 | /* auto update thing won't fire more than every 2s */ | ||
137 | #define AUTO_UPDATE_INTERVAL 2000 | ||
133 | 138 | ||
134 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | 139 | /* datasheet says to divide this number by the fan reading to get fan rpm */ |
135 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | 140 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) |
@@ -137,8 +142,6 @@ I2C_CLIENT_INSMOD_1(adt7470); | |||
137 | #define FAN_PERIOD_INVALID 65535 | 142 | #define FAN_PERIOD_INVALID 65535 |
138 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 143 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
139 | 144 | ||
140 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
141 | |||
142 | struct adt7470_data { | 145 | struct adt7470_data { |
143 | struct device *hwmon_dev; | 146 | struct device *hwmon_dev; |
144 | struct attribute_group attrs; | 147 | struct attribute_group attrs; |
@@ -148,6 +151,9 @@ struct adt7470_data { | |||
148 | unsigned long sensors_last_updated; /* In jiffies */ | 151 | unsigned long sensors_last_updated; /* In jiffies */ |
149 | unsigned long limits_last_updated; /* In jiffies */ | 152 | unsigned long limits_last_updated; /* In jiffies */ |
150 | 153 | ||
154 | int num_temp_sensors; /* -1 = probe */ | ||
155 | int temperatures_probed; | ||
156 | |||
151 | s8 temp[ADT7470_TEMP_COUNT]; | 157 | s8 temp[ADT7470_TEMP_COUNT]; |
152 | s8 temp_min[ADT7470_TEMP_COUNT]; | 158 | s8 temp_min[ADT7470_TEMP_COUNT]; |
153 | s8 temp_max[ADT7470_TEMP_COUNT]; | 159 | s8 temp_max[ADT7470_TEMP_COUNT]; |
@@ -163,6 +169,10 @@ struct adt7470_data { | |||
163 | u8 pwm_min[ADT7470_PWM_COUNT]; | 169 | u8 pwm_min[ADT7470_PWM_COUNT]; |
164 | s8 pwm_tmin[ADT7470_PWM_COUNT]; | 170 | s8 pwm_tmin[ADT7470_PWM_COUNT]; |
165 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; | 171 | u8 pwm_auto_temp[ADT7470_PWM_COUNT]; |
172 | |||
173 | struct task_struct *auto_update; | ||
174 | struct completion auto_update_stop; | ||
175 | unsigned int auto_update_interval; | ||
166 | }; | 176 | }; |
167 | 177 | ||
168 | static int adt7470_probe(struct i2c_client *client, | 178 | static int adt7470_probe(struct i2c_client *client, |
@@ -220,40 +230,126 @@ static void adt7470_init_client(struct i2c_client *client) | |||
220 | } | 230 | } |
221 | } | 231 | } |
222 | 232 | ||
223 | static struct adt7470_data *adt7470_update_device(struct device *dev) | 233 | /* Probe for temperature sensors. Assumes lock is held */ |
234 | static int adt7470_read_temperatures(struct i2c_client *client, | ||
235 | struct adt7470_data *data) | ||
224 | { | 236 | { |
225 | struct i2c_client *client = to_i2c_client(dev); | 237 | unsigned long res; |
226 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
227 | unsigned long local_jiffies = jiffies; | ||
228 | u8 cfg; | ||
229 | int i; | 238 | int i; |
239 | u8 cfg, pwm[4], pwm_cfg[2]; | ||
230 | 240 | ||
231 | mutex_lock(&data->lock); | 241 | /* save pwm[1-4] config register */ |
232 | if (time_before(local_jiffies, data->sensors_last_updated + | 242 | pwm_cfg[0] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(0)); |
233 | SENSOR_REFRESH_INTERVAL) | 243 | pwm_cfg[1] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM_CFG(2)); |
234 | && data->sensors_valid) | 244 | |
235 | goto no_sensor_update; | 245 | /* set manual pwm to whatever it is set to now */ |
246 | for (i = 0; i < ADT7470_FAN_COUNT; i++) | ||
247 | pwm[i] = i2c_smbus_read_byte_data(client, ADT7470_REG_PWM(i)); | ||
248 | |||
249 | /* put pwm in manual mode */ | ||
250 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0), | ||
251 | pwm_cfg[0] & ~(ADT7470_PWM_AUTO_MASK)); | ||
252 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), | ||
253 | pwm_cfg[1] & ~(ADT7470_PWM_AUTO_MASK)); | ||
254 | |||
255 | /* write pwm control to whatever it was */ | ||
256 | for (i = 0; i < ADT7470_FAN_COUNT; i++) | ||
257 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM(i), pwm[i]); | ||
236 | 258 | ||
237 | /* start reading temperature sensors */ | 259 | /* start reading temperature sensors */ |
238 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | 260 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); |
239 | cfg |= 0x80; | 261 | cfg |= 0x80; |
240 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | 262 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); |
241 | 263 | ||
242 | /* | 264 | /* Delay is 200ms * number of temp sensors. */ |
243 | * Delay is 200ms * number of tmp05 sensors. Too bad | 265 | res = msleep_interruptible((data->num_temp_sensors >= 0 ? |
244 | * there's no way to figure out how many are connected. | 266 | data->num_temp_sensors * 200 : |
245 | * For now, assume 1s will work. | 267 | TEMP_COLLECTION_TIME)); |
246 | */ | ||
247 | msleep(TEMP_COLLECTION_TIME); | ||
248 | 268 | ||
249 | /* done reading temperature sensors */ | 269 | /* done reading temperature sensors */ |
250 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); | 270 | cfg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG); |
251 | cfg &= ~0x80; | 271 | cfg &= ~0x80; |
252 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); | 272 | i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, cfg); |
253 | 273 | ||
254 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) | 274 | /* restore pwm[1-4] config registers */ |
275 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(0), pwm_cfg[0]); | ||
276 | i2c_smbus_write_byte_data(client, ADT7470_REG_PWM_CFG(2), pwm_cfg[1]); | ||
277 | |||
278 | if (res) { | ||
279 | printk(KERN_ERR "ha ha, interrupted"); | ||
280 | return -EAGAIN; | ||
281 | } | ||
282 | |||
283 | /* Only count fans if we have to */ | ||
284 | if (data->num_temp_sensors >= 0) | ||
285 | return 0; | ||
286 | |||
287 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) { | ||
255 | data->temp[i] = i2c_smbus_read_byte_data(client, | 288 | data->temp[i] = i2c_smbus_read_byte_data(client, |
256 | ADT7470_TEMP_REG(i)); | 289 | ADT7470_TEMP_REG(i)); |
290 | if (data->temp[i]) | ||
291 | data->num_temp_sensors = i + 1; | ||
292 | } | ||
293 | data->temperatures_probed = 1; | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int adt7470_update_thread(void *p) | ||
298 | { | ||
299 | struct i2c_client *client = p; | ||
300 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
301 | |||
302 | while (!kthread_should_stop()) { | ||
303 | mutex_lock(&data->lock); | ||
304 | adt7470_read_temperatures(client, data); | ||
305 | mutex_unlock(&data->lock); | ||
306 | if (kthread_should_stop()) | ||
307 | break; | ||
308 | msleep_interruptible(data->auto_update_interval); | ||
309 | } | ||
310 | |||
311 | complete_all(&data->auto_update_stop); | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static struct adt7470_data *adt7470_update_device(struct device *dev) | ||
316 | { | ||
317 | struct i2c_client *client = to_i2c_client(dev); | ||
318 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
319 | unsigned long local_jiffies = jiffies; | ||
320 | u8 cfg; | ||
321 | int i; | ||
322 | int need_sensors = 1; | ||
323 | int need_limits = 1; | ||
324 | |||
325 | /* | ||
326 | * Figure out if we need to update the shadow registers. | ||
327 | * Lockless means that we may occasionally report out of | ||
328 | * date data. | ||
329 | */ | ||
330 | if (time_before(local_jiffies, data->sensors_last_updated + | ||
331 | SENSOR_REFRESH_INTERVAL) && | ||
332 | data->sensors_valid) | ||
333 | need_sensors = 0; | ||
334 | |||
335 | if (time_before(local_jiffies, data->limits_last_updated + | ||
336 | LIMIT_REFRESH_INTERVAL) && | ||
337 | data->limits_valid) | ||
338 | need_limits = 0; | ||
339 | |||
340 | if (!need_sensors && !need_limits) | ||
341 | return data; | ||
342 | |||
343 | mutex_lock(&data->lock); | ||
344 | if (!need_sensors) | ||
345 | goto no_sensor_update; | ||
346 | |||
347 | if (!data->temperatures_probed) | ||
348 | adt7470_read_temperatures(client, data); | ||
349 | else | ||
350 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) | ||
351 | data->temp[i] = i2c_smbus_read_byte_data(client, | ||
352 | ADT7470_TEMP_REG(i)); | ||
257 | 353 | ||
258 | for (i = 0; i < ADT7470_FAN_COUNT; i++) | 354 | for (i = 0; i < ADT7470_FAN_COUNT; i++) |
259 | data->fan[i] = adt7470_read_word_data(client, | 355 | data->fan[i] = adt7470_read_word_data(client, |
@@ -302,9 +398,7 @@ static struct adt7470_data *adt7470_update_device(struct device *dev) | |||
302 | data->sensors_valid = 1; | 398 | data->sensors_valid = 1; |
303 | 399 | ||
304 | no_sensor_update: | 400 | no_sensor_update: |
305 | if (time_before(local_jiffies, data->limits_last_updated + | 401 | if (!need_limits) |
306 | LIMIT_REFRESH_INTERVAL) | ||
307 | && data->limits_valid) | ||
308 | goto out; | 402 | goto out; |
309 | 403 | ||
310 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) { | 404 | for (i = 0; i < ADT7470_TEMP_COUNT; i++) { |
@@ -338,6 +432,66 @@ out: | |||
338 | return data; | 432 | return data; |
339 | } | 433 | } |
340 | 434 | ||
435 | static ssize_t show_auto_update_interval(struct device *dev, | ||
436 | struct device_attribute *devattr, | ||
437 | char *buf) | ||
438 | { | ||
439 | struct adt7470_data *data = adt7470_update_device(dev); | ||
440 | return sprintf(buf, "%d\n", data->auto_update_interval); | ||
441 | } | ||
442 | |||
443 | static ssize_t set_auto_update_interval(struct device *dev, | ||
444 | struct device_attribute *devattr, | ||
445 | const char *buf, | ||
446 | size_t count) | ||
447 | { | ||
448 | struct i2c_client *client = to_i2c_client(dev); | ||
449 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
450 | long temp; | ||
451 | |||
452 | if (strict_strtol(buf, 10, &temp)) | ||
453 | return -EINVAL; | ||
454 | |||
455 | temp = SENSORS_LIMIT(temp, 0, 60000); | ||
456 | |||
457 | mutex_lock(&data->lock); | ||
458 | data->auto_update_interval = temp; | ||
459 | mutex_unlock(&data->lock); | ||
460 | |||
461 | return count; | ||
462 | } | ||
463 | |||
464 | static ssize_t show_num_temp_sensors(struct device *dev, | ||
465 | struct device_attribute *devattr, | ||
466 | char *buf) | ||
467 | { | ||
468 | struct adt7470_data *data = adt7470_update_device(dev); | ||
469 | return sprintf(buf, "%d\n", data->num_temp_sensors); | ||
470 | } | ||
471 | |||
472 | static ssize_t set_num_temp_sensors(struct device *dev, | ||
473 | struct device_attribute *devattr, | ||
474 | const char *buf, | ||
475 | size_t count) | ||
476 | { | ||
477 | struct i2c_client *client = to_i2c_client(dev); | ||
478 | struct adt7470_data *data = i2c_get_clientdata(client); | ||
479 | long temp; | ||
480 | |||
481 | if (strict_strtol(buf, 10, &temp)) | ||
482 | return -EINVAL; | ||
483 | |||
484 | temp = SENSORS_LIMIT(temp, -1, 10); | ||
485 | |||
486 | mutex_lock(&data->lock); | ||
487 | data->num_temp_sensors = temp; | ||
488 | if (temp < 0) | ||
489 | data->temperatures_probed = 0; | ||
490 | mutex_unlock(&data->lock); | ||
491 | |||
492 | return count; | ||
493 | } | ||
494 | |||
341 | static ssize_t show_temp_min(struct device *dev, | 495 | static ssize_t show_temp_min(struct device *dev, |
342 | struct device_attribute *devattr, | 496 | struct device_attribute *devattr, |
343 | char *buf) | 497 | char *buf) |
@@ -360,7 +514,7 @@ static ssize_t set_temp_min(struct device *dev, | |||
360 | if (strict_strtol(buf, 10, &temp)) | 514 | if (strict_strtol(buf, 10, &temp)) |
361 | return -EINVAL; | 515 | return -EINVAL; |
362 | 516 | ||
363 | temp = ROUND_DIV(temp, 1000); | 517 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
364 | temp = SENSORS_LIMIT(temp, 0, 255); | 518 | temp = SENSORS_LIMIT(temp, 0, 255); |
365 | 519 | ||
366 | mutex_lock(&data->lock); | 520 | mutex_lock(&data->lock); |
@@ -394,7 +548,7 @@ static ssize_t set_temp_max(struct device *dev, | |||
394 | if (strict_strtol(buf, 10, &temp)) | 548 | if (strict_strtol(buf, 10, &temp)) |
395 | return -EINVAL; | 549 | return -EINVAL; |
396 | 550 | ||
397 | temp = ROUND_DIV(temp, 1000); | 551 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
398 | temp = SENSORS_LIMIT(temp, 0, 255); | 552 | temp = SENSORS_LIMIT(temp, 0, 255); |
399 | 553 | ||
400 | mutex_lock(&data->lock); | 554 | mutex_lock(&data->lock); |
@@ -671,7 +825,7 @@ static ssize_t set_pwm_tmin(struct device *dev, | |||
671 | if (strict_strtol(buf, 10, &temp)) | 825 | if (strict_strtol(buf, 10, &temp)) |
672 | return -EINVAL; | 826 | return -EINVAL; |
673 | 827 | ||
674 | temp = ROUND_DIV(temp, 1000); | 828 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
675 | temp = SENSORS_LIMIT(temp, 0, 255); | 829 | temp = SENSORS_LIMIT(temp, 0, 255); |
676 | 830 | ||
677 | mutex_lock(&data->lock); | 831 | mutex_lock(&data->lock); |
@@ -804,6 +958,10 @@ static ssize_t show_alarm(struct device *dev, | |||
804 | } | 958 | } |
805 | 959 | ||
806 | static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL); | 960 | static DEVICE_ATTR(alarm_mask, S_IRUGO, show_alarm_mask, NULL); |
961 | static DEVICE_ATTR(num_temp_sensors, S_IWUSR | S_IRUGO, show_num_temp_sensors, | ||
962 | set_num_temp_sensors); | ||
963 | static DEVICE_ATTR(auto_update_interval, S_IWUSR | S_IRUGO, | ||
964 | show_auto_update_interval, set_auto_update_interval); | ||
807 | 965 | ||
808 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | 966 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, |
809 | set_temp_max, 0); | 967 | set_temp_max, 0); |
@@ -976,6 +1134,8 @@ static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | |||
976 | static struct attribute *adt7470_attr[] = | 1134 | static struct attribute *adt7470_attr[] = |
977 | { | 1135 | { |
978 | &dev_attr_alarm_mask.attr, | 1136 | &dev_attr_alarm_mask.attr, |
1137 | &dev_attr_num_temp_sensors.attr, | ||
1138 | &dev_attr_auto_update_interval.attr, | ||
979 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 1139 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
980 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 1140 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
981 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 1141 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
@@ -1108,6 +1268,9 @@ static int adt7470_probe(struct i2c_client *client, | |||
1108 | goto exit; | 1268 | goto exit; |
1109 | } | 1269 | } |
1110 | 1270 | ||
1271 | data->num_temp_sensors = -1; | ||
1272 | data->auto_update_interval = AUTO_UPDATE_INTERVAL; | ||
1273 | |||
1111 | i2c_set_clientdata(client, data); | 1274 | i2c_set_clientdata(client, data); |
1112 | mutex_init(&data->lock); | 1275 | mutex_init(&data->lock); |
1113 | 1276 | ||
@@ -1127,8 +1290,16 @@ static int adt7470_probe(struct i2c_client *client, | |||
1127 | goto exit_remove; | 1290 | goto exit_remove; |
1128 | } | 1291 | } |
1129 | 1292 | ||
1293 | init_completion(&data->auto_update_stop); | ||
1294 | data->auto_update = kthread_run(adt7470_update_thread, client, | ||
1295 | dev_name(data->hwmon_dev)); | ||
1296 | if (IS_ERR(data->auto_update)) | ||
1297 | goto exit_unregister; | ||
1298 | |||
1130 | return 0; | 1299 | return 0; |
1131 | 1300 | ||
1301 | exit_unregister: | ||
1302 | hwmon_device_unregister(data->hwmon_dev); | ||
1132 | exit_remove: | 1303 | exit_remove: |
1133 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1304 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1134 | exit_free: | 1305 | exit_free: |
@@ -1141,6 +1312,8 @@ static int adt7470_remove(struct i2c_client *client) | |||
1141 | { | 1312 | { |
1142 | struct adt7470_data *data = i2c_get_clientdata(client); | 1313 | struct adt7470_data *data = i2c_get_clientdata(client); |
1143 | 1314 | ||
1315 | kthread_stop(data->auto_update); | ||
1316 | wait_for_completion(&data->auto_update_stop); | ||
1144 | hwmon_device_unregister(data->hwmon_dev); | 1317 | hwmon_device_unregister(data->hwmon_dev); |
1145 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1318 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1146 | kfree(data); | 1319 | kfree(data); |
diff --git a/drivers/hwmon/adt7473.c b/drivers/hwmon/adt7473.c index 18aa30866a6c..0a6ce2367b42 100644 --- a/drivers/hwmon/adt7473.c +++ b/drivers/hwmon/adt7473.c | |||
@@ -129,8 +129,6 @@ I2C_CLIENT_INSMOD_1(adt7473); | |||
129 | #define FAN_PERIOD_INVALID 65535 | 129 | #define FAN_PERIOD_INVALID 65535 |
130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 130 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
131 | 131 | ||
132 | #define ROUND_DIV(x, divisor) (((x) + ((divisor) / 2)) / (divisor)) | ||
133 | |||
134 | struct adt7473_data { | 132 | struct adt7473_data { |
135 | struct device *hwmon_dev; | 133 | struct device *hwmon_dev; |
136 | struct attribute_group attrs; | 134 | struct attribute_group attrs; |
@@ -459,7 +457,7 @@ static ssize_t set_temp_min(struct device *dev, | |||
459 | if (strict_strtol(buf, 10, &temp)) | 457 | if (strict_strtol(buf, 10, &temp)) |
460 | return -EINVAL; | 458 | return -EINVAL; |
461 | 459 | ||
462 | temp = ROUND_DIV(temp, 1000); | 460 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
463 | temp = encode_temp(data->temp_twos_complement, temp); | 461 | temp = encode_temp(data->temp_twos_complement, temp); |
464 | 462 | ||
465 | mutex_lock(&data->lock); | 463 | mutex_lock(&data->lock); |
@@ -495,7 +493,7 @@ static ssize_t set_temp_max(struct device *dev, | |||
495 | if (strict_strtol(buf, 10, &temp)) | 493 | if (strict_strtol(buf, 10, &temp)) |
496 | return -EINVAL; | 494 | return -EINVAL; |
497 | 495 | ||
498 | temp = ROUND_DIV(temp, 1000); | 496 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
499 | temp = encode_temp(data->temp_twos_complement, temp); | 497 | temp = encode_temp(data->temp_twos_complement, temp); |
500 | 498 | ||
501 | mutex_lock(&data->lock); | 499 | mutex_lock(&data->lock); |
@@ -720,7 +718,7 @@ static ssize_t set_temp_tmax(struct device *dev, | |||
720 | if (strict_strtol(buf, 10, &temp)) | 718 | if (strict_strtol(buf, 10, &temp)) |
721 | return -EINVAL; | 719 | return -EINVAL; |
722 | 720 | ||
723 | temp = ROUND_DIV(temp, 1000); | 721 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
724 | temp = encode_temp(data->temp_twos_complement, temp); | 722 | temp = encode_temp(data->temp_twos_complement, temp); |
725 | 723 | ||
726 | mutex_lock(&data->lock); | 724 | mutex_lock(&data->lock); |
@@ -756,7 +754,7 @@ static ssize_t set_temp_tmin(struct device *dev, | |||
756 | if (strict_strtol(buf, 10, &temp)) | 754 | if (strict_strtol(buf, 10, &temp)) |
757 | return -EINVAL; | 755 | return -EINVAL; |
758 | 756 | ||
759 | temp = ROUND_DIV(temp, 1000); | 757 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
760 | temp = encode_temp(data->temp_twos_complement, temp); | 758 | temp = encode_temp(data->temp_twos_complement, temp); |
761 | 759 | ||
762 | mutex_lock(&data->lock); | 760 | mutex_lock(&data->lock); |
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 086c2a5cef0b..dca47a591baf 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -131,6 +131,10 @@ static const char* temperature_sensors_sets[][36] = { | |||
131 | /* Set 14: iMac 6,1 */ | 131 | /* Set 14: iMac 6,1 */ |
132 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", | 132 | { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P", |
133 | "TO0P", "Tp0P", NULL }, | 133 | "TO0P", "Tp0P", NULL }, |
134 | /* Set 15: MacBook Air 2,1 */ | ||
135 | { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0", | ||
136 | "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P", | ||
137 | "Ts0S", NULL }, | ||
134 | }; | 138 | }; |
135 | 139 | ||
136 | /* List of keys used to read/write fan speeds */ | 140 | /* List of keys used to read/write fan speeds */ |
@@ -1301,11 +1305,17 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1301 | { .accelerometer = 0, .light = 0, .temperature_set = 13 }, | 1305 | { .accelerometer = 0, .light = 0, .temperature_set = 13 }, |
1302 | /* iMac 6: light sensor only, temperature set 14 */ | 1306 | /* iMac 6: light sensor only, temperature set 14 */ |
1303 | { .accelerometer = 0, .light = 0, .temperature_set = 14 }, | 1307 | { .accelerometer = 0, .light = 0, .temperature_set = 14 }, |
1308 | /* MacBook Air 2,1: accelerometer, backlight and temperature set 15 */ | ||
1309 | { .accelerometer = 1, .light = 1, .temperature_set = 15 }, | ||
1304 | }; | 1310 | }; |
1305 | 1311 | ||
1306 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1312 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
1307 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ | 1313 | * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ |
1308 | static __initdata struct dmi_system_id applesmc_whitelist[] = { | 1314 | static __initdata struct dmi_system_id applesmc_whitelist[] = { |
1315 | { applesmc_dmi_match, "Apple MacBook Air 2", { | ||
1316 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | ||
1317 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2") }, | ||
1318 | &applesmc_dmi_data[15]}, | ||
1309 | { applesmc_dmi_match, "Apple MacBook Air", { | 1319 | { applesmc_dmi_match, "Apple MacBook Air", { |
1310 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), | 1320 | DMI_MATCH(DMI_BOARD_VENDOR, "Apple"), |
1311 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, | 1321 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") }, |
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 537d9fb2ff88..a36363312f2f 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | static inline u16 extract_value(const char *data, int offset) | 41 | static inline u16 extract_value(const char *data, int offset) |
42 | { | 42 | { |
43 | return be16_to_cpup((u16 *)&data[offset]); | 43 | return be16_to_cpup((__be16 *)&data[offset]); |
44 | } | 44 | } |
45 | 45 | ||
46 | #define TEMP_SENSOR 1 | 46 | #define TEMP_SENSOR 1 |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 4ee85fcf9aaf..3f9503867e6b 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -511,6 +511,13 @@ config BLK_DEV_PIIX | |||
511 | This allows the kernel to change PIO, DMA and UDMA speeds and to | 511 | This allows the kernel to change PIO, DMA and UDMA speeds and to |
512 | configure the chip to optimum performance. | 512 | configure the chip to optimum performance. |
513 | 513 | ||
514 | config BLK_DEV_IT8172 | ||
515 | tristate "IT8172 IDE support" | ||
516 | select BLK_DEV_IDEDMA_PCI | ||
517 | help | ||
518 | This driver adds support for the IDE controller on the | ||
519 | IT8172 System Controller. | ||
520 | |||
514 | config BLK_DEV_IT8213 | 521 | config BLK_DEV_IT8213 |
515 | tristate "IT8213 IDE support" | 522 | tristate "IT8213 IDE support" |
516 | select BLK_DEV_IDEDMA_PCI | 523 | select BLK_DEV_IDEDMA_PCI |
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 410728992e6a..c2b9c93f0095 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile | |||
@@ -47,6 +47,7 @@ obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o | |||
47 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o | 47 | obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o |
48 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o | 48 | obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o |
49 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o | 49 | obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o |
50 | obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o | ||
50 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o | 51 | obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o |
51 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o | 52 | obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o |
52 | obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o | 53 | obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o |
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 4142c698e0d3..4485b9c6f0e6 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c | |||
@@ -83,7 +83,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr | |||
83 | 83 | ||
84 | static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) | 84 | static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) |
85 | { | 85 | { |
86 | ide_hwif_t *hwif = HWIF(drive); | 86 | ide_hwif_t *hwif = drive->hwif; |
87 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 87 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
88 | struct ide_host *host = pci_get_drvdata(dev); | 88 | struct ide_host *host = pci_get_drvdata(dev); |
89 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; | 89 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; |
@@ -111,7 +111,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) | |||
111 | 111 | ||
112 | static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) | 112 | static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) |
113 | { | 113 | { |
114 | ide_hwif_t *hwif = HWIF(drive); | 114 | ide_hwif_t *hwif = drive->hwif; |
115 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 115 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
116 | struct ide_host *host = pci_get_drvdata(dev); | 116 | struct ide_host *host = pci_get_drvdata(dev); |
117 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; | 117 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; |
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 45d2356bb725..66f43083408b 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c | |||
@@ -68,7 +68,7 @@ static struct pci_dev *isa_dev; | |||
68 | 68 | ||
69 | static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) | 69 | static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) |
70 | { | 70 | { |
71 | ide_hwif_t *hwif = HWIF(drive); | 71 | ide_hwif_t *hwif = drive->hwif; |
72 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 72 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
73 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | 73 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); |
74 | int s_time = t->setup, a_time = t->active, c_time = t->cycle; | 74 | int s_time = t->setup, a_time = t->active, c_time = t->cycle; |
@@ -150,7 +150,7 @@ static u8 ali_udma_filter(ide_drive_t *drive) | |||
150 | 150 | ||
151 | static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) | 151 | static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) |
152 | { | 152 | { |
153 | ide_hwif_t *hwif = HWIF(drive); | 153 | ide_hwif_t *hwif = drive->hwif; |
154 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 154 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
155 | u8 speed1 = speed; | 155 | u8 speed1 = speed; |
156 | u8 unit = drive->dn & 1; | 156 | u8 unit = drive->dn & 1; |
@@ -198,7 +198,7 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
198 | static int ali15x3_dma_setup(ide_drive_t *drive) | 198 | static int ali15x3_dma_setup(ide_drive_t *drive) |
199 | { | 199 | { |
200 | if (m5229_revision < 0xC2 && drive->media != ide_disk) { | 200 | if (m5229_revision < 0xC2 && drive->media != ide_disk) { |
201 | if (rq_data_dir(drive->hwif->hwgroup->rq)) | 201 | if (rq_data_dir(drive->hwif->rq)) |
202 | return 1; /* try PIO instead of DMA */ | 202 | return 1; /* try PIO instead of DMA */ |
203 | } | 203 | } |
204 | return ide_dma_setup(drive); | 204 | return ide_dma_setup(drive); |
@@ -490,8 +490,6 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif, | |||
490 | if (ide_allocate_dma_engine(hwif)) | 490 | if (ide_allocate_dma_engine(hwif)) |
491 | return -1; | 491 | return -1; |
492 | 492 | ||
493 | hwif->dma_ops = &sff_dma_ops; | ||
494 | |||
495 | return 0; | 493 | return 0; |
496 | } | 494 | } |
497 | 495 | ||
@@ -511,6 +509,7 @@ static const struct ide_dma_ops ali_dma_ops = { | |||
511 | .dma_test_irq = ide_dma_test_irq, | 509 | .dma_test_irq = ide_dma_test_irq, |
512 | .dma_lost_irq = ide_dma_lost_irq, | 510 | .dma_lost_irq = ide_dma_lost_irq, |
513 | .dma_timeout = ide_dma_timeout, | 511 | .dma_timeout = ide_dma_timeout, |
512 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
514 | }; | 513 | }; |
515 | 514 | ||
516 | static const struct ide_port_info ali15x3_chipset __devinitdata = { | 515 | static const struct ide_port_info ali15x3_chipset __devinitdata = { |
@@ -519,6 +518,7 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = { | |||
519 | .init_hwif = init_hwif_ali15x3, | 518 | .init_hwif = init_hwif_ali15x3, |
520 | .init_dma = init_dma_ali15x3, | 519 | .init_dma = init_dma_ali15x3, |
521 | .port_ops = &ali_port_ops, | 520 | .port_ops = &ali_port_ops, |
521 | .dma_ops = &sff_dma_ops, | ||
522 | .pio_mask = ATA_PIO5, | 522 | .pio_mask = ATA_PIO5, |
523 | .swdma_mask = ATA_SWDMA2, | 523 | .swdma_mask = ATA_SWDMA2, |
524 | .mwdma_mask = ATA_MWDMA2, | 524 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c index c6bcd3014a29..69660a431cd9 100644 --- a/drivers/ide/amd74xx.c +++ b/drivers/ide/amd74xx.c | |||
@@ -82,7 +82,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) | |||
82 | { | 82 | { |
83 | ide_hwif_t *hwif = drive->hwif; | 83 | ide_hwif_t *hwif = drive->hwif; |
84 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 84 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
85 | ide_drive_t *peer = hwif->drives + (~drive->dn & 1); | 85 | ide_drive_t *peer = ide_get_pair_dev(drive); |
86 | struct ide_timing t, p; | 86 | struct ide_timing t, p; |
87 | int T, UT; | 87 | int T, UT; |
88 | u8 udma_mask = hwif->ultra_mask; | 88 | u8 udma_mask = hwif->ultra_mask; |
@@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed) | |||
92 | 92 | ||
93 | ide_timing_compute(drive, speed, &t, T, UT); | 93 | ide_timing_compute(drive, speed, &t, T, UT); |
94 | 94 | ||
95 | if (peer->dev_flags & IDE_DFLAG_PRESENT) { | 95 | if (peer) { |
96 | ide_timing_compute(peer, peer->current_speed, &p, T, UT); | 96 | ide_timing_compute(peer, peer->current_speed, &p, T, UT); |
97 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); | 97 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); |
98 | } | 98 | } |
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c index 0ec8fd1e4dcb..79a2dfed8eb7 100644 --- a/drivers/ide/au1xxx-ide.c +++ b/drivers/ide/au1xxx-ide.c | |||
@@ -212,8 +212,8 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
212 | static int auide_build_dmatable(ide_drive_t *drive) | 212 | static int auide_build_dmatable(ide_drive_t *drive) |
213 | { | 213 | { |
214 | int i, iswrite, count = 0; | 214 | int i, iswrite, count = 0; |
215 | ide_hwif_t *hwif = HWIF(drive); | 215 | ide_hwif_t *hwif = drive->hwif; |
216 | struct request *rq = HWGROUP(drive)->rq; | 216 | struct request *rq = hwif->rq; |
217 | _auide_hwif *ahwif = &auide_hwif; | 217 | _auide_hwif *ahwif = &auide_hwif; |
218 | struct scatterlist *sg; | 218 | struct scatterlist *sg; |
219 | 219 | ||
@@ -286,7 +286,7 @@ static int auide_build_dmatable(ide_drive_t *drive) | |||
286 | 286 | ||
287 | static int auide_dma_end(ide_drive_t *drive) | 287 | static int auide_dma_end(ide_drive_t *drive) |
288 | { | 288 | { |
289 | ide_hwif_t *hwif = HWIF(drive); | 289 | ide_hwif_t *hwif = drive->hwif; |
290 | 290 | ||
291 | if (hwif->sg_nents) { | 291 | if (hwif->sg_nents) { |
292 | ide_destroy_dmatable(drive); | 292 | ide_destroy_dmatable(drive); |
@@ -309,8 +309,8 @@ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command) | |||
309 | } | 309 | } |
310 | 310 | ||
311 | static int auide_dma_setup(ide_drive_t *drive) | 311 | static int auide_dma_setup(ide_drive_t *drive) |
312 | { | 312 | { |
313 | struct request *rq = HWGROUP(drive)->rq; | 313 | struct request *rq = drive->hwif->rq; |
314 | 314 | ||
315 | if (!auide_build_dmatable(drive)) { | 315 | if (!auide_build_dmatable(drive)) { |
316 | ide_map_sg(drive, rq); | 316 | ide_map_sg(drive, rq); |
@@ -502,7 +502,6 @@ static const struct ide_tp_ops au1xxx_tp_ops = { | |||
502 | .exec_command = ide_exec_command, | 502 | .exec_command = ide_exec_command, |
503 | .read_status = ide_read_status, | 503 | .read_status = ide_read_status, |
504 | .read_altstatus = ide_read_altstatus, | 504 | .read_altstatus = ide_read_altstatus, |
505 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
506 | 505 | ||
507 | .set_irq = ide_set_irq, | 506 | .set_irq = ide_set_irq, |
508 | 507 | ||
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index e4306647d00d..8890276fef7f 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c | |||
@@ -467,11 +467,10 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index) | |||
467 | * so we merge the timings, using the slowest value for each timing. | 467 | * so we merge the timings, using the slowest value for each timing. |
468 | */ | 468 | */ |
469 | if (index > 1) { | 469 | if (index > 1) { |
470 | ide_hwif_t *hwif = drive->hwif; | 470 | ide_drive_t *peer = ide_get_pair_dev(drive); |
471 | ide_drive_t *peer = &hwif->drives[!(drive->dn & 1)]; | ||
472 | unsigned int mate = index ^ 1; | 471 | unsigned int mate = index ^ 1; |
473 | 472 | ||
474 | if (peer->dev_flags & IDE_DFLAG_PRESENT) { | 473 | if (peer) { |
475 | if (setup_count < setup_counts[mate]) | 474 | if (setup_count < setup_counts[mate]) |
476 | setup_count = setup_counts[mate]; | 475 | setup_count = setup_counts[mate]; |
477 | if (active_count < active_counts[mate]) | 476 | if (active_count < active_counts[mate]) |
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 3623bf013bcf..2f9688d87ecd 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c | |||
@@ -115,7 +115,7 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_ | |||
115 | */ | 115 | */ |
116 | static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) | 116 | static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) |
117 | { | 117 | { |
118 | ide_hwif_t *hwif = HWIF(drive); | 118 | ide_hwif_t *hwif = drive->hwif; |
119 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 119 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
120 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | 120 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); |
121 | unsigned int cycle_time; | 121 | unsigned int cycle_time; |
@@ -138,10 +138,12 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) | |||
138 | * the slowest address setup timing ourselves. | 138 | * the slowest address setup timing ourselves. |
139 | */ | 139 | */ |
140 | if (hwif->channel) { | 140 | if (hwif->channel) { |
141 | ide_drive_t *drives = hwif->drives; | 141 | ide_drive_t *pair = ide_get_pair_dev(drive); |
142 | 142 | ||
143 | drive->drive_data = setup_count; | 143 | drive->drive_data = setup_count; |
144 | setup_count = max(drives[0].drive_data, drives[1].drive_data); | 144 | |
145 | if (pair) | ||
146 | setup_count = max_t(u8, setup_count, pair->drive_data); | ||
145 | } | 147 | } |
146 | 148 | ||
147 | if (setup_count > 5) /* shouldn't actually happen... */ | 149 | if (setup_count > 5) /* shouldn't actually happen... */ |
@@ -180,7 +182,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
180 | 182 | ||
181 | static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | 183 | static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) |
182 | { | 184 | { |
183 | ide_hwif_t *hwif = HWIF(drive); | 185 | ide_hwif_t *hwif = drive->hwif; |
184 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 186 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
185 | u8 unit = drive->dn & 0x01; | 187 | u8 unit = drive->dn & 0x01; |
186 | u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; | 188 | u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; |
@@ -226,7 +228,7 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
226 | 228 | ||
227 | static int cmd648_dma_end(ide_drive_t *drive) | 229 | static int cmd648_dma_end(ide_drive_t *drive) |
228 | { | 230 | { |
229 | ide_hwif_t *hwif = HWIF(drive); | 231 | ide_hwif_t *hwif = drive->hwif; |
230 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 232 | unsigned long base = hwif->dma_base - (hwif->channel * 8); |
231 | int err = ide_dma_end(drive); | 233 | int err = ide_dma_end(drive); |
232 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 234 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
@@ -242,7 +244,7 @@ static int cmd648_dma_end(ide_drive_t *drive) | |||
242 | 244 | ||
243 | static int cmd64x_dma_end(ide_drive_t *drive) | 245 | static int cmd64x_dma_end(ide_drive_t *drive) |
244 | { | 246 | { |
245 | ide_hwif_t *hwif = HWIF(drive); | 247 | ide_hwif_t *hwif = drive->hwif; |
246 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 248 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
247 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; | 249 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; |
248 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : | 250 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : |
@@ -259,7 +261,7 @@ static int cmd64x_dma_end(ide_drive_t *drive) | |||
259 | 261 | ||
260 | static int cmd648_dma_test_irq(ide_drive_t *drive) | 262 | static int cmd648_dma_test_irq(ide_drive_t *drive) |
261 | { | 263 | { |
262 | ide_hwif_t *hwif = HWIF(drive); | 264 | ide_hwif_t *hwif = drive->hwif; |
263 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 265 | unsigned long base = hwif->dma_base - (hwif->channel * 8); |
264 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 266 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
265 | MRDMODE_INTR_CH0; | 267 | MRDMODE_INTR_CH0; |
@@ -282,7 +284,7 @@ static int cmd648_dma_test_irq(ide_drive_t *drive) | |||
282 | 284 | ||
283 | static int cmd64x_dma_test_irq(ide_drive_t *drive) | 285 | static int cmd64x_dma_test_irq(ide_drive_t *drive) |
284 | { | 286 | { |
285 | ide_hwif_t *hwif = HWIF(drive); | 287 | ide_hwif_t *hwif = drive->hwif; |
286 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 288 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
287 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; | 289 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; |
288 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : | 290 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : |
@@ -313,7 +315,7 @@ static int cmd64x_dma_test_irq(ide_drive_t *drive) | |||
313 | 315 | ||
314 | static int cmd646_1_dma_end(ide_drive_t *drive) | 316 | static int cmd646_1_dma_end(ide_drive_t *drive) |
315 | { | 317 | { |
316 | ide_hwif_t *hwif = HWIF(drive); | 318 | ide_hwif_t *hwif = drive->hwif; |
317 | u8 dma_stat = 0, dma_cmd = 0; | 319 | u8 dma_stat = 0, dma_cmd = 0; |
318 | 320 | ||
319 | drive->waiting_for_dma = 0; | 321 | drive->waiting_for_dma = 0; |
@@ -383,6 +385,7 @@ static const struct ide_dma_ops cmd64x_dma_ops = { | |||
383 | .dma_test_irq = cmd64x_dma_test_irq, | 385 | .dma_test_irq = cmd64x_dma_test_irq, |
384 | .dma_lost_irq = ide_dma_lost_irq, | 386 | .dma_lost_irq = ide_dma_lost_irq, |
385 | .dma_timeout = ide_dma_timeout, | 387 | .dma_timeout = ide_dma_timeout, |
388 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
386 | }; | 389 | }; |
387 | 390 | ||
388 | static const struct ide_dma_ops cmd646_rev1_dma_ops = { | 391 | static const struct ide_dma_ops cmd646_rev1_dma_ops = { |
@@ -394,6 +397,7 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = { | |||
394 | .dma_test_irq = ide_dma_test_irq, | 397 | .dma_test_irq = ide_dma_test_irq, |
395 | .dma_lost_irq = ide_dma_lost_irq, | 398 | .dma_lost_irq = ide_dma_lost_irq, |
396 | .dma_timeout = ide_dma_timeout, | 399 | .dma_timeout = ide_dma_timeout, |
400 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
397 | }; | 401 | }; |
398 | 402 | ||
399 | static const struct ide_dma_ops cmd648_dma_ops = { | 403 | static const struct ide_dma_ops cmd648_dma_ops = { |
@@ -405,6 +409,7 @@ static const struct ide_dma_ops cmd648_dma_ops = { | |||
405 | .dma_test_irq = cmd648_dma_test_irq, | 409 | .dma_test_irq = cmd648_dma_test_irq, |
406 | .dma_lost_irq = ide_dma_lost_irq, | 410 | .dma_lost_irq = ide_dma_lost_irq, |
407 | .dma_timeout = ide_dma_timeout, | 411 | .dma_timeout = ide_dma_timeout, |
412 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
408 | }; | 413 | }; |
409 | 414 | ||
410 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | 415 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { |
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index 5efb467f8fa0..d003bec56ff9 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c | |||
@@ -59,7 +59,7 @@ static struct pio_clocks cs5520_pio_clocks[]={ | |||
59 | 59 | ||
60 | static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) | 60 | static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio) |
61 | { | 61 | { |
62 | ide_hwif_t *hwif = HWIF(drive); | 62 | ide_hwif_t *hwif = drive->hwif; |
63 | struct pci_dev *pdev = to_pci_dev(hwif->dev); | 63 | struct pci_dev *pdev = to_pci_dev(hwif->dev); |
64 | int controller = drive->dn > 1 ? 1 : 0; | 64 | int controller = drive->dn > 1 ? 1 : 0; |
65 | 65 | ||
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index d37baf8ecc5f..74fc5401f407 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c | |||
@@ -203,7 +203,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
203 | 203 | ||
204 | static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) | 204 | static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio) |
205 | { | 205 | { |
206 | ide_hwif_t *hwif = HWIF(drive); | 206 | ide_hwif_t *hwif = drive->hwif; |
207 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 207 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
208 | pio_clocks_t pclk; | 208 | pio_clocks_t pclk; |
209 | unsigned int addrCtrl; | 209 | unsigned int addrCtrl; |
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c index 39d500d84b07..a5ba820d69bb 100644 --- a/drivers/ide/falconide.c +++ b/drivers/ide/falconide.c | |||
@@ -70,7 +70,6 @@ static const struct ide_tp_ops falconide_tp_ops = { | |||
70 | .exec_command = ide_exec_command, | 70 | .exec_command = ide_exec_command, |
71 | .read_status = ide_read_status, | 71 | .read_status = ide_read_status, |
72 | .read_altstatus = ide_read_altstatus, | 72 | .read_altstatus = ide_read_altstatus, |
73 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
74 | 73 | ||
75 | .set_irq = ide_set_irq, | 74 | .set_irq = ide_set_irq, |
76 | 75 | ||
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index b18e10d99d2e..3eb9b5c63a0f 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c | |||
@@ -626,7 +626,7 @@ static struct hpt_info *hpt3xx_get_info(struct device *dev) | |||
626 | 626 | ||
627 | static u8 hpt3xx_udma_filter(ide_drive_t *drive) | 627 | static u8 hpt3xx_udma_filter(ide_drive_t *drive) |
628 | { | 628 | { |
629 | ide_hwif_t *hwif = HWIF(drive); | 629 | ide_hwif_t *hwif = drive->hwif; |
630 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 630 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
631 | u8 mask = hwif->ultra_mask; | 631 | u8 mask = hwif->ultra_mask; |
632 | 632 | ||
@@ -665,7 +665,7 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive) | |||
665 | 665 | ||
666 | static u8 hpt3xx_mdma_filter(ide_drive_t *drive) | 666 | static u8 hpt3xx_mdma_filter(ide_drive_t *drive) |
667 | { | 667 | { |
668 | ide_hwif_t *hwif = HWIF(drive); | 668 | ide_hwif_t *hwif = drive->hwif; |
669 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 669 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
670 | 670 | ||
671 | switch (info->chip_type) { | 671 | switch (info->chip_type) { |
@@ -743,7 +743,7 @@ static void hpt3xx_quirkproc(ide_drive_t *drive) | |||
743 | 743 | ||
744 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) | 744 | static void hpt3xx_maskproc(ide_drive_t *drive, int mask) |
745 | { | 745 | { |
746 | ide_hwif_t *hwif = HWIF(drive); | 746 | ide_hwif_t *hwif = drive->hwif; |
747 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 747 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
748 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); | 748 | struct hpt_info *info = hpt3xx_get_info(hwif->dev); |
749 | 749 | ||
@@ -788,7 +788,7 @@ static void hpt366_dma_lost_irq(ide_drive_t *drive) | |||
788 | 788 | ||
789 | static void hpt370_clear_engine(ide_drive_t *drive) | 789 | static void hpt370_clear_engine(ide_drive_t *drive) |
790 | { | 790 | { |
791 | ide_hwif_t *hwif = HWIF(drive); | 791 | ide_hwif_t *hwif = drive->hwif; |
792 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 792 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
793 | 793 | ||
794 | pci_write_config_byte(dev, hwif->select_data, 0x37); | 794 | pci_write_config_byte(dev, hwif->select_data, 0x37); |
@@ -797,7 +797,7 @@ static void hpt370_clear_engine(ide_drive_t *drive) | |||
797 | 797 | ||
798 | static void hpt370_irq_timeout(ide_drive_t *drive) | 798 | static void hpt370_irq_timeout(ide_drive_t *drive) |
799 | { | 799 | { |
800 | ide_hwif_t *hwif = HWIF(drive); | 800 | ide_hwif_t *hwif = drive->hwif; |
801 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 801 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
802 | u16 bfifo = 0; | 802 | u16 bfifo = 0; |
803 | u8 dma_cmd; | 803 | u8 dma_cmd; |
@@ -822,7 +822,7 @@ static void hpt370_dma_start(ide_drive_t *drive) | |||
822 | 822 | ||
823 | static int hpt370_dma_end(ide_drive_t *drive) | 823 | static int hpt370_dma_end(ide_drive_t *drive) |
824 | { | 824 | { |
825 | ide_hwif_t *hwif = HWIF(drive); | 825 | ide_hwif_t *hwif = drive->hwif; |
826 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 826 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
827 | 827 | ||
828 | if (dma_stat & 0x01) { | 828 | if (dma_stat & 0x01) { |
@@ -844,7 +844,7 @@ static void hpt370_dma_timeout(ide_drive_t *drive) | |||
844 | /* returns 1 if DMA IRQ issued, 0 otherwise */ | 844 | /* returns 1 if DMA IRQ issued, 0 otherwise */ |
845 | static int hpt374_dma_test_irq(ide_drive_t *drive) | 845 | static int hpt374_dma_test_irq(ide_drive_t *drive) |
846 | { | 846 | { |
847 | ide_hwif_t *hwif = HWIF(drive); | 847 | ide_hwif_t *hwif = drive->hwif; |
848 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 848 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
849 | u16 bfifo = 0; | 849 | u16 bfifo = 0; |
850 | u8 dma_stat; | 850 | u8 dma_stat; |
@@ -865,7 +865,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive) | |||
865 | 865 | ||
866 | static int hpt374_dma_end(ide_drive_t *drive) | 866 | static int hpt374_dma_end(ide_drive_t *drive) |
867 | { | 867 | { |
868 | ide_hwif_t *hwif = HWIF(drive); | 868 | ide_hwif_t *hwif = drive->hwif; |
869 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 869 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
870 | u8 mcr = 0, mcr_addr = hwif->select_data; | 870 | u8 mcr = 0, mcr_addr = hwif->select_data; |
871 | u8 bwsr = 0, mask = hwif->channel ? 0x02 : 0x01; | 871 | u8 bwsr = 0, mask = hwif->channel ? 0x02 : 0x01; |
@@ -927,7 +927,7 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) | |||
927 | 927 | ||
928 | static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq) | 928 | static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq) |
929 | { | 929 | { |
930 | hpt3xxn_set_clock(HWIF(drive), rq_data_dir(rq) ? 0x23 : 0x21); | 930 | hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21); |
931 | } | 931 | } |
932 | 932 | ||
933 | /** | 933 | /** |
@@ -1349,8 +1349,6 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif, | |||
1349 | if (ide_allocate_dma_engine(hwif)) | 1349 | if (ide_allocate_dma_engine(hwif)) |
1350 | return -1; | 1350 | return -1; |
1351 | 1351 | ||
1352 | hwif->dma_ops = &sff_dma_ops; | ||
1353 | |||
1354 | return 0; | 1352 | return 0; |
1355 | } | 1353 | } |
1356 | 1354 | ||
@@ -1426,6 +1424,7 @@ static const struct ide_dma_ops hpt37x_dma_ops = { | |||
1426 | .dma_test_irq = hpt374_dma_test_irq, | 1424 | .dma_test_irq = hpt374_dma_test_irq, |
1427 | .dma_lost_irq = ide_dma_lost_irq, | 1425 | .dma_lost_irq = ide_dma_lost_irq, |
1428 | .dma_timeout = ide_dma_timeout, | 1426 | .dma_timeout = ide_dma_timeout, |
1427 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
1429 | }; | 1428 | }; |
1430 | 1429 | ||
1431 | static const struct ide_dma_ops hpt370_dma_ops = { | 1430 | static const struct ide_dma_ops hpt370_dma_ops = { |
@@ -1437,6 +1436,7 @@ static const struct ide_dma_ops hpt370_dma_ops = { | |||
1437 | .dma_test_irq = ide_dma_test_irq, | 1436 | .dma_test_irq = ide_dma_test_irq, |
1438 | .dma_lost_irq = ide_dma_lost_irq, | 1437 | .dma_lost_irq = ide_dma_lost_irq, |
1439 | .dma_timeout = hpt370_dma_timeout, | 1438 | .dma_timeout = hpt370_dma_timeout, |
1439 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
1440 | }; | 1440 | }; |
1441 | 1441 | ||
1442 | static const struct ide_dma_ops hpt36x_dma_ops = { | 1442 | static const struct ide_dma_ops hpt36x_dma_ops = { |
@@ -1448,6 +1448,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = { | |||
1448 | .dma_test_irq = ide_dma_test_irq, | 1448 | .dma_test_irq = ide_dma_test_irq, |
1449 | .dma_lost_irq = hpt366_dma_lost_irq, | 1449 | .dma_lost_irq = hpt366_dma_lost_irq, |
1450 | .dma_timeout = ide_dma_timeout, | 1450 | .dma_timeout = ide_dma_timeout, |
1451 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
1451 | }; | 1452 | }; |
1452 | 1453 | ||
1453 | static const struct ide_port_info hpt366_chipsets[] __devinitdata = { | 1454 | static const struct ide_port_info hpt366_chipsets[] __devinitdata = { |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 81f70caeb40f..97a35c667aee 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
@@ -166,7 +166,7 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { | |||
166 | */ | 166 | */ |
167 | static void icside_maskproc(ide_drive_t *drive, int mask) | 167 | static void icside_maskproc(ide_drive_t *drive, int mask) |
168 | { | 168 | { |
169 | ide_hwif_t *hwif = HWIF(drive); | 169 | ide_hwif_t *hwif = drive->hwif; |
170 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 170 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
171 | struct icside_state *state = ecard_get_drvdata(ec); | 171 | struct icside_state *state = ecard_get_drvdata(ec); |
172 | unsigned long flags; | 172 | unsigned long flags; |
@@ -284,7 +284,7 @@ static void icside_dma_host_set(ide_drive_t *drive, int on) | |||
284 | 284 | ||
285 | static int icside_dma_end(ide_drive_t *drive) | 285 | static int icside_dma_end(ide_drive_t *drive) |
286 | { | 286 | { |
287 | ide_hwif_t *hwif = HWIF(drive); | 287 | ide_hwif_t *hwif = drive->hwif; |
288 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 288 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
289 | 289 | ||
290 | drive->waiting_for_dma = 0; | 290 | drive->waiting_for_dma = 0; |
@@ -299,7 +299,7 @@ static int icside_dma_end(ide_drive_t *drive) | |||
299 | 299 | ||
300 | static void icside_dma_start(ide_drive_t *drive) | 300 | static void icside_dma_start(ide_drive_t *drive) |
301 | { | 301 | { |
302 | ide_hwif_t *hwif = HWIF(drive); | 302 | ide_hwif_t *hwif = drive->hwif; |
303 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 303 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
304 | 304 | ||
305 | /* We can not enable DMA on both channels simultaneously. */ | 305 | /* We can not enable DMA on both channels simultaneously. */ |
@@ -309,10 +309,10 @@ static void icside_dma_start(ide_drive_t *drive) | |||
309 | 309 | ||
310 | static int icside_dma_setup(ide_drive_t *drive) | 310 | static int icside_dma_setup(ide_drive_t *drive) |
311 | { | 311 | { |
312 | ide_hwif_t *hwif = HWIF(drive); | 312 | ide_hwif_t *hwif = drive->hwif; |
313 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 313 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
314 | struct icside_state *state = ecard_get_drvdata(ec); | 314 | struct icside_state *state = ecard_get_drvdata(ec); |
315 | struct request *rq = hwif->hwgroup->rq; | 315 | struct request *rq = hwif->rq; |
316 | unsigned int dma_mode; | 316 | unsigned int dma_mode; |
317 | 317 | ||
318 | if (rq_data_dir(rq)) | 318 | if (rq_data_dir(rq)) |
@@ -362,7 +362,7 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd) | |||
362 | 362 | ||
363 | static int icside_dma_test_irq(ide_drive_t *drive) | 363 | static int icside_dma_test_irq(ide_drive_t *drive) |
364 | { | 364 | { |
365 | ide_hwif_t *hwif = HWIF(drive); | 365 | ide_hwif_t *hwif = drive->hwif; |
366 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | 366 | struct expansion_card *ec = ECARD_DEV(hwif->dev); |
367 | struct icside_state *state = ecard_get_drvdata(ec); | 367 | struct icside_state *state = ecard_get_drvdata(ec); |
368 | 368 | ||
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index fd4a36433050..2f9e941968d6 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -218,7 +218,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) | |||
218 | */ | 218 | */ |
219 | static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive) | 219 | static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive) |
220 | { | 220 | { |
221 | ide_hwif_t *hwif = HWIF(drive); | 221 | ide_hwif_t *hwif = drive->hwif; |
222 | int port; | 222 | int port; |
223 | acpi_handle drive_handle; | 223 | acpi_handle drive_handle; |
224 | 224 | ||
@@ -263,7 +263,7 @@ static int do_drive_get_GTF(ide_drive_t *drive, | |||
263 | acpi_status status; | 263 | acpi_status status; |
264 | struct acpi_buffer output; | 264 | struct acpi_buffer output; |
265 | union acpi_object *out_obj; | 265 | union acpi_object *out_obj; |
266 | ide_hwif_t *hwif = HWIF(drive); | 266 | ide_hwif_t *hwif = drive->hwif; |
267 | struct device *dev = hwif->gendev.parent; | 267 | struct device *dev = hwif->gendev.parent; |
268 | int err = -ENODEV; | 268 | int err = -ENODEV; |
269 | int port; | 269 | int port; |
@@ -641,7 +641,8 @@ void ide_acpi_push_timing(ide_hwif_t *hwif) | |||
641 | */ | 641 | */ |
642 | void ide_acpi_set_state(ide_hwif_t *hwif, int on) | 642 | void ide_acpi_set_state(ide_hwif_t *hwif, int on) |
643 | { | 643 | { |
644 | int unit; | 644 | ide_drive_t *drive; |
645 | int i; | ||
645 | 646 | ||
646 | if (ide_noacpi || ide_noacpi_psx) | 647 | if (ide_noacpi || ide_noacpi_psx) |
647 | return; | 648 | return; |
@@ -655,9 +656,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on) | |||
655 | /* channel first and then drives for power on and verse versa for power off */ | 656 | /* channel first and then drives for power on and verse versa for power off */ |
656 | if (on) | 657 | if (on) |
657 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); | 658 | acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0); |
658 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
659 | ide_drive_t *drive = &hwif->drives[unit]; | ||
660 | 659 | ||
660 | ide_port_for_each_dev(i, drive, hwif) { | ||
661 | if (!drive->acpidata->obj_handle) | 661 | if (!drive->acpidata->obj_handle) |
662 | drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); | 662 | drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive); |
663 | 663 | ||
@@ -711,15 +711,13 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) | |||
711 | * for both drives, regardless whether they are connected | 711 | * for both drives, regardless whether they are connected |
712 | * or not. | 712 | * or not. |
713 | */ | 713 | */ |
714 | hwif->drives[0].acpidata = &hwif->acpidata->master; | 714 | hwif->devices[0]->acpidata = &hwif->acpidata->master; |
715 | hwif->drives[1].acpidata = &hwif->acpidata->slave; | 715 | hwif->devices[1]->acpidata = &hwif->acpidata->slave; |
716 | 716 | ||
717 | /* | 717 | /* |
718 | * Send IDENTIFY for each drive | 718 | * Send IDENTIFY for each drive |
719 | */ | 719 | */ |
720 | for (i = 0; i < MAX_DRIVES; i++) { | 720 | ide_port_for_each_dev(i, drive, hwif) { |
721 | drive = &hwif->drives[i]; | ||
722 | |||
723 | memset(drive->acpidata, 0, sizeof(*drive->acpidata)); | 721 | memset(drive->acpidata, 0, sizeof(*drive->acpidata)); |
724 | 722 | ||
725 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 723 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
@@ -744,9 +742,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif) | |||
744 | ide_acpi_get_timing(hwif); | 742 | ide_acpi_get_timing(hwif); |
745 | ide_acpi_push_timing(hwif); | 743 | ide_acpi_push_timing(hwif); |
746 | 744 | ||
747 | for (i = 0; i < MAX_DRIVES; i++) { | 745 | ide_port_for_each_dev(i, drive, hwif) { |
748 | drive = &hwif->drives[i]; | ||
749 | |||
750 | if (drive->dev_flags & IDE_DFLAG_PRESENT) | 746 | if (drive->dev_flags & IDE_DFLAG_PRESENT) |
751 | /* Execute ACPI startup code */ | 747 | /* Execute ACPI startup code */ |
752 | ide_acpi_exec_tfs(drive); | 748 | ide_acpi_exec_tfs(drive); |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index e8688c0f8645..e96c01260598 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
@@ -243,7 +243,7 @@ EXPORT_SYMBOL_GPL(ide_retry_pc); | |||
243 | 243 | ||
244 | int ide_cd_expiry(ide_drive_t *drive) | 244 | int ide_cd_expiry(ide_drive_t *drive) |
245 | { | 245 | { |
246 | struct request *rq = HWGROUP(drive)->rq; | 246 | struct request *rq = drive->hwif->rq; |
247 | unsigned long wait = 0; | 247 | unsigned long wait = 0; |
248 | 248 | ||
249 | debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); | 249 | debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]); |
@@ -294,7 +294,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
294 | { | 294 | { |
295 | struct ide_atapi_pc *pc = drive->pc; | 295 | struct ide_atapi_pc *pc = drive->pc; |
296 | ide_hwif_t *hwif = drive->hwif; | 296 | ide_hwif_t *hwif = drive->hwif; |
297 | struct request *rq = hwif->hwgroup->rq; | 297 | struct request *rq = hwif->rq; |
298 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 298 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
299 | xfer_func_t *xferfunc; | 299 | xfer_func_t *xferfunc; |
300 | unsigned int timeout, temp; | 300 | unsigned int timeout, temp; |
@@ -491,7 +491,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | |||
491 | { | 491 | { |
492 | struct ide_atapi_pc *uninitialized_var(pc); | 492 | struct ide_atapi_pc *uninitialized_var(pc); |
493 | ide_hwif_t *hwif = drive->hwif; | 493 | ide_hwif_t *hwif = drive->hwif; |
494 | struct request *rq = hwif->hwgroup->rq; | 494 | struct request *rq = hwif->rq; |
495 | ide_expiry_t *expiry; | 495 | ide_expiry_t *expiry; |
496 | unsigned int timeout; | 496 | unsigned int timeout; |
497 | int cmd_len; | 497 | int cmd_len; |
@@ -549,7 +549,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | |||
549 | } | 549 | } |
550 | 550 | ||
551 | /* Set the interrupt routine */ | 551 | /* Set the interrupt routine */ |
552 | ide_set_handler(drive, ide_pc_intr, timeout, expiry); | 552 | ide_set_handler(drive, |
553 | (dev_is_idecd(drive) ? drive->irq_handler | ||
554 | : ide_pc_intr), | ||
555 | timeout, expiry); | ||
553 | 556 | ||
554 | /* Begin DMA, if necessary */ | 557 | /* Begin DMA, if necessary */ |
555 | if (dev_is_idecd(drive)) { | 558 | if (dev_is_idecd(drive)) { |
@@ -580,7 +583,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive) | |||
580 | 583 | ||
581 | if (dev_is_idecd(drive)) { | 584 | if (dev_is_idecd(drive)) { |
582 | tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; | 585 | tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; |
583 | bcount = ide_cd_get_xferlen(hwif->hwgroup->rq); | 586 | bcount = ide_cd_get_xferlen(hwif->rq); |
584 | expiry = ide_cd_expiry; | 587 | expiry = ide_cd_expiry; |
585 | timeout = ATAPI_WAIT_PC; | 588 | timeout = ATAPI_WAIT_PC; |
586 | 589 | ||
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 1a7410f88249..cae69372cf45 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -239,7 +239,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
239 | 239 | ||
240 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) | 240 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) |
241 | { | 241 | { |
242 | struct request *rq = HWGROUP(drive)->rq; | 242 | struct request *rq = drive->hwif->rq; |
243 | int nsectors = rq->hard_cur_sectors; | 243 | int nsectors = rq->hard_cur_sectors; |
244 | 244 | ||
245 | ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " | 245 | ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " |
@@ -306,8 +306,7 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) | |||
306 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | 306 | static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) |
307 | { | 307 | { |
308 | ide_hwif_t *hwif = drive->hwif; | 308 | ide_hwif_t *hwif = drive->hwif; |
309 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | 309 | struct request *rq = hwif->rq; |
310 | struct request *rq = hwgroup->rq; | ||
311 | int stat, err, sense_key; | 310 | int stat, err, sense_key; |
312 | 311 | ||
313 | /* check for errors */ | 312 | /* check for errors */ |
@@ -502,7 +501,7 @@ end_request: | |||
502 | blkdev_dequeue_request(rq); | 501 | blkdev_dequeue_request(rq); |
503 | spin_unlock_irqrestore(q->queue_lock, flags); | 502 | spin_unlock_irqrestore(q->queue_lock, flags); |
504 | 503 | ||
505 | hwgroup->rq = NULL; | 504 | hwif->rq = NULL; |
506 | 505 | ||
507 | cdrom_queue_request_sense(drive, rq->sense, rq); | 506 | cdrom_queue_request_sense(drive, rq->sense, rq); |
508 | } else | 507 | } else |
@@ -511,106 +510,6 @@ end_request: | |||
511 | return 1; | 510 | return 1; |
512 | } | 511 | } |
513 | 512 | ||
514 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *); | ||
515 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); | ||
516 | |||
517 | /* | ||
518 | * Set up the device registers for transferring a packet command on DEV, | ||
519 | * expecting to later transfer XFERLEN bytes. HANDLER is the routine | ||
520 | * which actually transfers the command to the drive. If this is a | ||
521 | * drq_interrupt device, this routine will arrange for HANDLER to be | ||
522 | * called when the interrupt from the drive arrives. Otherwise, HANDLER | ||
523 | * will be called immediately after the drive is prepared for the transfer. | ||
524 | */ | ||
525 | static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive) | ||
526 | { | ||
527 | ide_hwif_t *hwif = drive->hwif; | ||
528 | struct request *rq = hwif->hwgroup->rq; | ||
529 | int xferlen; | ||
530 | |||
531 | xferlen = ide_cd_get_xferlen(rq); | ||
532 | |||
533 | ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); | ||
534 | |||
535 | /* FIXME: for Virtual DMA we must check harder */ | ||
536 | if (drive->dma) | ||
537 | drive->dma = !hwif->dma_ops->dma_setup(drive); | ||
538 | |||
539 | /* set up the controller registers */ | ||
540 | ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, | ||
541 | xferlen, drive->dma); | ||
542 | |||
543 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | ||
544 | /* waiting for CDB interrupt, not DMA yet. */ | ||
545 | if (drive->dma) | ||
546 | drive->waiting_for_dma = 0; | ||
547 | |||
548 | /* packet command */ | ||
549 | ide_execute_command(drive, ATA_CMD_PACKET, | ||
550 | cdrom_transfer_packet_command, | ||
551 | ATAPI_WAIT_PC, ide_cd_expiry); | ||
552 | return ide_started; | ||
553 | } else { | ||
554 | ide_execute_pkt_cmd(drive); | ||
555 | |||
556 | return cdrom_transfer_packet_command(drive); | ||
557 | } | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device | ||
562 | * registers must have already been prepared by cdrom_start_packet_command. | ||
563 | * HANDLER is the interrupt handler to call when the command completes or | ||
564 | * there's data ready. | ||
565 | */ | ||
566 | #define ATAPI_MIN_CDB_BYTES 12 | ||
567 | static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive) | ||
568 | { | ||
569 | ide_hwif_t *hwif = drive->hwif; | ||
570 | struct request *rq = hwif->hwgroup->rq; | ||
571 | int cmd_len; | ||
572 | ide_startstop_t startstop; | ||
573 | |||
574 | ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__); | ||
575 | |||
576 | if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { | ||
577 | /* | ||
578 | * Here we should have been called after receiving an interrupt | ||
579 | * from the device. DRQ should how be set. | ||
580 | */ | ||
581 | |||
582 | /* check for errors */ | ||
583 | if (cdrom_decode_status(drive, ATA_DRQ, NULL)) | ||
584 | return ide_stopped; | ||
585 | |||
586 | /* ok, next interrupt will be DMA interrupt */ | ||
587 | if (drive->dma) | ||
588 | drive->waiting_for_dma = 1; | ||
589 | } else { | ||
590 | /* otherwise, we must wait for DRQ to get set */ | ||
591 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, | ||
592 | ATA_BUSY, WAIT_READY)) | ||
593 | return startstop; | ||
594 | } | ||
595 | |||
596 | /* arm the interrupt handler */ | ||
597 | ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry); | ||
598 | |||
599 | /* ATAPI commands get padded out to 12 bytes minimum */ | ||
600 | cmd_len = COMMAND_SIZE(rq->cmd[0]); | ||
601 | if (cmd_len < ATAPI_MIN_CDB_BYTES) | ||
602 | cmd_len = ATAPI_MIN_CDB_BYTES; | ||
603 | |||
604 | /* send the command to the device */ | ||
605 | hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); | ||
606 | |||
607 | /* start the DMA if need be */ | ||
608 | if (drive->dma) | ||
609 | hwif->dma_ops->dma_start(drive); | ||
610 | |||
611 | return ide_started; | ||
612 | } | ||
613 | |||
614 | /* | 513 | /* |
615 | * Check the contents of the interrupt reason register from the cdrom | 514 | * Check the contents of the interrupt reason register from the cdrom |
616 | * and attempt to recover if there are problems. Returns 0 if everything's | 515 | * and attempt to recover if there are problems. Returns 0 if everything's |
@@ -854,8 +753,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) | |||
854 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | 753 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) |
855 | { | 754 | { |
856 | ide_hwif_t *hwif = drive->hwif; | 755 | ide_hwif_t *hwif = drive->hwif; |
857 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | 756 | struct request *rq = hwif->rq; |
858 | struct request *rq = hwgroup->rq; | ||
859 | xfer_func_t *xferfunc; | 757 | xfer_func_t *xferfunc; |
860 | ide_expiry_t *expiry = NULL; | 758 | ide_expiry_t *expiry = NULL; |
861 | int dma_error = 0, dma, stat, thislen, uptodate = 0; | 759 | int dma_error = 0, dma, stat, thislen, uptodate = 0; |
@@ -1061,7 +959,7 @@ end_request: | |||
1061 | if (blk_end_request(rq, 0, dlen)) | 959 | if (blk_end_request(rq, 0, dlen)) |
1062 | BUG(); | 960 | BUG(); |
1063 | 961 | ||
1064 | hwgroup->rq = NULL; | 962 | hwif->rq = NULL; |
1065 | } else { | 963 | } else { |
1066 | if (!uptodate) | 964 | if (!uptodate) |
1067 | rq->cmd_flags |= REQ_FAILED; | 965 | rq->cmd_flags |= REQ_FAILED; |
@@ -1183,7 +1081,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
1183 | return ide_stopped; | 1081 | return ide_stopped; |
1184 | } | 1082 | } |
1185 | 1083 | ||
1186 | return cdrom_start_packet_command(drive); | 1084 | return ide_issue_pc(drive); |
1187 | } | 1085 | } |
1188 | 1086 | ||
1189 | /* | 1087 | /* |
@@ -1916,7 +1814,7 @@ static void ide_cd_release(struct kref *kref) | |||
1916 | 1814 | ||
1917 | static int ide_cd_probe(ide_drive_t *); | 1815 | static int ide_cd_probe(ide_drive_t *); |
1918 | 1816 | ||
1919 | static ide_driver_t ide_cdrom_driver = { | 1817 | static struct ide_driver ide_cdrom_driver = { |
1920 | .gen_driver = { | 1818 | .gen_driver = { |
1921 | .owner = THIS_MODULE, | 1819 | .owner = THIS_MODULE, |
1922 | .name = "ide-cdrom", | 1820 | .name = "ide-cdrom", |
@@ -1927,7 +1825,6 @@ static ide_driver_t ide_cdrom_driver = { | |||
1927 | .version = IDECD_VERSION, | 1825 | .version = IDECD_VERSION, |
1928 | .do_request = ide_cd_do_request, | 1826 | .do_request = ide_cd_do_request, |
1929 | .end_request = ide_end_request, | 1827 | .end_request = ide_end_request, |
1930 | .error = __ide_error, | ||
1931 | #ifdef CONFIG_IDE_PROC_FS | 1828 | #ifdef CONFIG_IDE_PROC_FS |
1932 | .proc_entries = ide_cd_proc_entries, | 1829 | .proc_entries = ide_cd_proc_entries, |
1933 | .proc_devsets = ide_cd_proc_devsets, | 1830 | .proc_devsets = ide_cd_proc_devsets, |
@@ -2082,6 +1979,7 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
2082 | } | 1979 | } |
2083 | 1980 | ||
2084 | drive->debug_mask = debug_mask; | 1981 | drive->debug_mask = debug_mask; |
1982 | drive->irq_handler = cdrom_newpc_intr; | ||
2085 | 1983 | ||
2086 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); | 1984 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); |
2087 | if (info == NULL) { | 1985 | if (info == NULL) { |
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index bf676b262181..ac40d6cb90a2 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
@@ -33,33 +33,33 @@ | |||
33 | 33 | ||
34 | /* Structure of a MSF cdrom address. */ | 34 | /* Structure of a MSF cdrom address. */ |
35 | struct atapi_msf { | 35 | struct atapi_msf { |
36 | byte reserved; | 36 | u8 reserved; |
37 | byte minute; | 37 | u8 minute; |
38 | byte second; | 38 | u8 second; |
39 | byte frame; | 39 | u8 frame; |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* Space to hold the disk TOC. */ | 42 | /* Space to hold the disk TOC. */ |
43 | #define MAX_TRACKS 99 | 43 | #define MAX_TRACKS 99 |
44 | struct atapi_toc_header { | 44 | struct atapi_toc_header { |
45 | unsigned short toc_length; | 45 | unsigned short toc_length; |
46 | byte first_track; | 46 | u8 first_track; |
47 | byte last_track; | 47 | u8 last_track; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct atapi_toc_entry { | 50 | struct atapi_toc_entry { |
51 | byte reserved1; | 51 | u8 reserved1; |
52 | #if defined(__BIG_ENDIAN_BITFIELD) | 52 | #if defined(__BIG_ENDIAN_BITFIELD) |
53 | __u8 adr : 4; | 53 | u8 adr : 4; |
54 | __u8 control : 4; | 54 | u8 control : 4; |
55 | #elif defined(__LITTLE_ENDIAN_BITFIELD) | 55 | #elif defined(__LITTLE_ENDIAN_BITFIELD) |
56 | __u8 control : 4; | 56 | u8 control : 4; |
57 | __u8 adr : 4; | 57 | u8 adr : 4; |
58 | #else | 58 | #else |
59 | #error "Please fix <asm/byteorder.h>" | 59 | #error "Please fix <asm/byteorder.h>" |
60 | #endif | 60 | #endif |
61 | byte track; | 61 | u8 track; |
62 | byte reserved2; | 62 | u8 reserved2; |
63 | union { | 63 | union { |
64 | unsigned lba; | 64 | unsigned lba; |
65 | struct atapi_msf msf; | 65 | struct atapi_msf msf; |
@@ -77,10 +77,10 @@ struct atapi_toc { | |||
77 | 77 | ||
78 | /* Extra per-device info for cdrom drives. */ | 78 | /* Extra per-device info for cdrom drives. */ |
79 | struct cdrom_info { | 79 | struct cdrom_info { |
80 | ide_drive_t *drive; | 80 | ide_drive_t *drive; |
81 | ide_driver_t *driver; | 81 | struct ide_driver *driver; |
82 | struct gendisk *disk; | 82 | struct gendisk *disk; |
83 | struct kref kref; | 83 | struct kref kref; |
84 | 84 | ||
85 | /* Buffer for table of contents. NULL if we haven't allocated | 85 | /* Buffer for table of contents. NULL if we haven't allocated |
86 | a TOC buffer for this device yet. */ | 86 | a TOC buffer for this device yet. */ |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index eb9fac4d0f0c..4088a622873e 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -89,7 +89,7 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma) | |||
89 | static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | 89 | static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, |
90 | sector_t block) | 90 | sector_t block) |
91 | { | 91 | { |
92 | ide_hwif_t *hwif = HWIF(drive); | 92 | ide_hwif_t *hwif = drive->hwif; |
93 | u16 nsectors = (u16)rq->nr_sectors; | 93 | u16 nsectors = (u16)rq->nr_sectors; |
94 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); | 94 | u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48); |
95 | u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); | 95 | u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); |
@@ -187,7 +187,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
187 | static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | 187 | static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, |
188 | sector_t block) | 188 | sector_t block) |
189 | { | 189 | { |
190 | ide_hwif_t *hwif = HWIF(drive); | 190 | ide_hwif_t *hwif = drive->hwif; |
191 | 191 | ||
192 | BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); | 192 | BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); |
193 | 193 | ||
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index f6d2d44d8a9a..123d393658af 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c | |||
@@ -50,6 +50,27 @@ int config_drive_for_dma(ide_drive_t *drive) | |||
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
52 | 52 | ||
53 | u8 ide_dma_sff_read_status(ide_hwif_t *hwif) | ||
54 | { | ||
55 | unsigned long addr = hwif->dma_base + ATA_DMA_STATUS; | ||
56 | |||
57 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
58 | return readb((void __iomem *)addr); | ||
59 | else | ||
60 | return inb(addr); | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(ide_dma_sff_read_status); | ||
63 | |||
64 | static void ide_dma_sff_write_status(ide_hwif_t *hwif, u8 val) | ||
65 | { | ||
66 | unsigned long addr = hwif->dma_base + ATA_DMA_STATUS; | ||
67 | |||
68 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
69 | writeb(val, (void __iomem *)addr); | ||
70 | else | ||
71 | outb(val, addr); | ||
72 | } | ||
73 | |||
53 | /** | 74 | /** |
54 | * ide_dma_host_set - Enable/disable DMA on a host | 75 | * ide_dma_host_set - Enable/disable DMA on a host |
55 | * @drive: drive to control | 76 | * @drive: drive to control |
@@ -62,18 +83,14 @@ void ide_dma_host_set(ide_drive_t *drive, int on) | |||
62 | { | 83 | { |
63 | ide_hwif_t *hwif = drive->hwif; | 84 | ide_hwif_t *hwif = drive->hwif; |
64 | u8 unit = drive->dn & 1; | 85 | u8 unit = drive->dn & 1; |
65 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 86 | u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
66 | 87 | ||
67 | if (on) | 88 | if (on) |
68 | dma_stat |= (1 << (5 + unit)); | 89 | dma_stat |= (1 << (5 + unit)); |
69 | else | 90 | else |
70 | dma_stat &= ~(1 << (5 + unit)); | 91 | dma_stat &= ~(1 << (5 + unit)); |
71 | 92 | ||
72 | if (hwif->host_flags & IDE_HFLAG_MMIO) | 93 | ide_dma_sff_write_status(hwif, dma_stat); |
73 | writeb(dma_stat, | ||
74 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
75 | else | ||
76 | outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); | ||
77 | } | 94 | } |
78 | EXPORT_SYMBOL_GPL(ide_dma_host_set); | 95 | EXPORT_SYMBOL_GPL(ide_dma_host_set); |
79 | 96 | ||
@@ -175,7 +192,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); | |||
175 | int ide_dma_setup(ide_drive_t *drive) | 192 | int ide_dma_setup(ide_drive_t *drive) |
176 | { | 193 | { |
177 | ide_hwif_t *hwif = drive->hwif; | 194 | ide_hwif_t *hwif = drive->hwif; |
178 | struct request *rq = hwif->hwgroup->rq; | 195 | struct request *rq = hwif->rq; |
179 | unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; | 196 | unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; |
180 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | 197 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; |
181 | u8 dma_stat; | 198 | u8 dma_stat; |
@@ -187,7 +204,7 @@ int ide_dma_setup(ide_drive_t *drive) | |||
187 | } | 204 | } |
188 | 205 | ||
189 | /* PRD table */ | 206 | /* PRD table */ |
190 | if (hwif->host_flags & IDE_HFLAG_MMIO) | 207 | if (mmio) |
191 | writel(hwif->dmatable_dma, | 208 | writel(hwif->dmatable_dma, |
192 | (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); | 209 | (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); |
193 | else | 210 | else |
@@ -200,15 +217,10 @@ int ide_dma_setup(ide_drive_t *drive) | |||
200 | outb(reading, hwif->dma_base + ATA_DMA_CMD); | 217 | outb(reading, hwif->dma_base + ATA_DMA_CMD); |
201 | 218 | ||
202 | /* read DMA status for INTR & ERROR flags */ | 219 | /* read DMA status for INTR & ERROR flags */ |
203 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 220 | dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
204 | 221 | ||
205 | /* clear INTR & ERROR flags */ | 222 | /* clear INTR & ERROR flags */ |
206 | if (mmio) | 223 | ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); |
207 | writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, | ||
208 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
209 | else | ||
210 | outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, | ||
211 | hwif->dma_base + ATA_DMA_STATUS); | ||
212 | 224 | ||
213 | drive->waiting_for_dma = 1; | 225 | drive->waiting_for_dma = 1; |
214 | return 0; | 226 | return 0; |
@@ -232,7 +244,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup); | |||
232 | static int dma_timer_expiry(ide_drive_t *drive) | 244 | static int dma_timer_expiry(ide_drive_t *drive) |
233 | { | 245 | { |
234 | ide_hwif_t *hwif = drive->hwif; | 246 | ide_hwif_t *hwif = drive->hwif; |
235 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 247 | u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
236 | 248 | ||
237 | printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", | 249 | printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", |
238 | drive->name, __func__, dma_stat); | 250 | drive->name, __func__, dma_stat); |
@@ -240,7 +252,7 @@ static int dma_timer_expiry(ide_drive_t *drive) | |||
240 | if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ | 252 | if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ |
241 | return WAIT_CMD; | 253 | return WAIT_CMD; |
242 | 254 | ||
243 | hwif->hwgroup->expiry = NULL; /* one free ride for now */ | 255 | hwif->expiry = NULL; /* one free ride for now */ |
244 | 256 | ||
245 | if (dma_stat & ATA_DMA_ERR) /* ERROR */ | 257 | if (dma_stat & ATA_DMA_ERR) /* ERROR */ |
246 | return -1; | 258 | return -1; |
@@ -289,13 +301,12 @@ EXPORT_SYMBOL_GPL(ide_dma_start); | |||
289 | int ide_dma_end(ide_drive_t *drive) | 301 | int ide_dma_end(ide_drive_t *drive) |
290 | { | 302 | { |
291 | ide_hwif_t *hwif = drive->hwif; | 303 | ide_hwif_t *hwif = drive->hwif; |
292 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
293 | u8 dma_stat = 0, dma_cmd = 0, mask; | 304 | u8 dma_stat = 0, dma_cmd = 0, mask; |
294 | 305 | ||
295 | drive->waiting_for_dma = 0; | 306 | drive->waiting_for_dma = 0; |
296 | 307 | ||
297 | /* stop DMA */ | 308 | /* stop DMA */ |
298 | if (mmio) { | 309 | if (hwif->host_flags & IDE_HFLAG_MMIO) { |
299 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 310 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
300 | writeb(dma_cmd & ~ATA_DMA_START, | 311 | writeb(dma_cmd & ~ATA_DMA_START, |
301 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 312 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
@@ -305,15 +316,10 @@ int ide_dma_end(ide_drive_t *drive) | |||
305 | } | 316 | } |
306 | 317 | ||
307 | /* get DMA status */ | 318 | /* get DMA status */ |
308 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 319 | dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
309 | 320 | ||
310 | if (mmio) | 321 | /* clear INTR & ERROR bits */ |
311 | /* clear the INTR & ERROR bits */ | 322 | ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR); |
312 | writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, | ||
313 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
314 | else | ||
315 | outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, | ||
316 | hwif->dma_base + ATA_DMA_STATUS); | ||
317 | 323 | ||
318 | /* purge DMA mappings */ | 324 | /* purge DMA mappings */ |
319 | ide_destroy_dmatable(drive); | 325 | ide_destroy_dmatable(drive); |
@@ -331,7 +337,7 @@ EXPORT_SYMBOL_GPL(ide_dma_end); | |||
331 | int ide_dma_test_irq(ide_drive_t *drive) | 337 | int ide_dma_test_irq(ide_drive_t *drive) |
332 | { | 338 | { |
333 | ide_hwif_t *hwif = drive->hwif; | 339 | ide_hwif_t *hwif = drive->hwif; |
334 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 340 | u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
335 | 341 | ||
336 | return (dma_stat & ATA_DMA_INTR) ? 1 : 0; | 342 | return (dma_stat & ATA_DMA_INTR) ? 1 : 0; |
337 | } | 343 | } |
@@ -346,5 +352,6 @@ const struct ide_dma_ops sff_dma_ops = { | |||
346 | .dma_test_irq = ide_dma_test_irq, | 352 | .dma_test_irq = ide_dma_test_irq, |
347 | .dma_timeout = ide_dma_timeout, | 353 | .dma_timeout = ide_dma_timeout, |
348 | .dma_lost_irq = ide_dma_lost_irq, | 354 | .dma_lost_irq = ide_dma_lost_irq, |
355 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
349 | }; | 356 | }; |
350 | EXPORT_SYMBOL_GPL(sff_dma_ops); | 357 | EXPORT_SYMBOL_GPL(sff_dma_ops); |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index fffd11717b2d..72ebab0bc755 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -96,7 +96,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive) | |||
96 | 96 | ||
97 | if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { | 97 | if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { |
98 | if (!dma_stat) { | 98 | if (!dma_stat) { |
99 | struct request *rq = hwif->hwgroup->rq; | 99 | struct request *rq = hwif->rq; |
100 | 100 | ||
101 | task_end_request(drive, rq, stat); | 101 | task_end_request(drive, rq, stat); |
102 | return ide_stopped; | 102 | return ide_stopped; |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0a48e2dc53a2..3eab1c6c9b31 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -71,7 +71,7 @@ | |||
71 | static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) | 71 | static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) |
72 | { | 72 | { |
73 | struct ide_disk_obj *floppy = drive->driver_data; | 73 | struct ide_disk_obj *floppy = drive->driver_data; |
74 | struct request *rq = HWGROUP(drive)->rq; | 74 | struct request *rq = drive->hwif->rq; |
75 | int error; | 75 | int error; |
76 | 76 | ||
77 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); | 77 | ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); |
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index b8078b3231f7..7857b209c6df 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
@@ -149,7 +149,7 @@ static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) | |||
149 | return drive->disk_ops->end_request(drive, uptodate, nrsecs); | 149 | return drive->disk_ops->end_request(drive, uptodate, nrsecs); |
150 | } | 150 | } |
151 | 151 | ||
152 | static ide_driver_t ide_gd_driver = { | 152 | static struct ide_driver ide_gd_driver = { |
153 | .gen_driver = { | 153 | .gen_driver = { |
154 | .owner = THIS_MODULE, | 154 | .owner = THIS_MODULE, |
155 | .name = "ide-gd", | 155 | .name = "ide-gd", |
@@ -162,7 +162,6 @@ static ide_driver_t ide_gd_driver = { | |||
162 | .version = IDE_GD_VERSION, | 162 | .version = IDE_GD_VERSION, |
163 | .do_request = ide_gd_do_request, | 163 | .do_request = ide_gd_do_request, |
164 | .end_request = ide_gd_end_request, | 164 | .end_request = ide_gd_end_request, |
165 | .error = __ide_error, | ||
166 | #ifdef CONFIG_IDE_PROC_FS | 165 | #ifdef CONFIG_IDE_PROC_FS |
167 | .proc_entries = ide_disk_proc_entries, | 166 | .proc_entries = ide_disk_proc_entries, |
168 | .proc_devsets = ide_disk_proc_devsets, | 167 | .proc_devsets = ide_disk_proc_devsets, |
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h index 7d3d101713e0..a86779f0756b 100644 --- a/drivers/ide/ide-gd.h +++ b/drivers/ide/ide-gd.h | |||
@@ -14,11 +14,11 @@ | |||
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | struct ide_disk_obj { | 16 | struct ide_disk_obj { |
17 | ide_drive_t *drive; | 17 | ide_drive_t *drive; |
18 | ide_driver_t *driver; | 18 | struct ide_driver *driver; |
19 | struct gendisk *disk; | 19 | struct gendisk *disk; |
20 | struct kref kref; | 20 | struct kref kref; |
21 | unsigned int openers; /* protected by BKL for now */ | 21 | unsigned int openers; /* protected by BKL for now */ |
22 | 22 | ||
23 | /* Last failed packet command */ | 23 | /* Last failed packet command */ |
24 | struct ide_atapi_pc *failed_pc; | 24 | struct ide_atapi_pc *failed_pc; |
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c index e2cdd2e9cdec..9270d3255ee0 100644 --- a/drivers/ide/ide-h8300.c +++ b/drivers/ide/ide-h8300.c | |||
@@ -159,7 +159,6 @@ static const struct ide_tp_ops h8300_tp_ops = { | |||
159 | .exec_command = ide_exec_command, | 159 | .exec_command = ide_exec_command, |
160 | .read_status = ide_read_status, | 160 | .read_status = ide_read_status, |
161 | .read_altstatus = ide_read_altstatus, | 161 | .read_altstatus = ide_read_altstatus, |
162 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
163 | 162 | ||
164 | .set_irq = ide_set_irq, | 163 | .set_irq = ide_set_irq, |
165 | 164 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1c36a8e83d36..cc163319dfbd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -88,7 +88,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
88 | ret = 0; | 88 | ret = 0; |
89 | 89 | ||
90 | if (ret == 0 && dequeue) | 90 | if (ret == 0 && dequeue) |
91 | drive->hwif->hwgroup->rq = NULL; | 91 | drive->hwif->rq = NULL; |
92 | 92 | ||
93 | return ret; | 93 | return ret; |
94 | } | 94 | } |
@@ -107,7 +107,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, | |||
107 | int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) | 107 | int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) |
108 | { | 108 | { |
109 | unsigned int nr_bytes = nr_sectors << 9; | 109 | unsigned int nr_bytes = nr_sectors << 9; |
110 | struct request *rq = drive->hwif->hwgroup->rq; | 110 | struct request *rq = drive->hwif->rq; |
111 | 111 | ||
112 | if (!nr_bytes) { | 112 | if (!nr_bytes) { |
113 | if (blk_pc_request(rq)) | 113 | if (blk_pc_request(rq)) |
@@ -160,8 +160,8 @@ EXPORT_SYMBOL_GPL(ide_end_dequeued_request); | |||
160 | 160 | ||
161 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | 161 | void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) |
162 | { | 162 | { |
163 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | 163 | ide_hwif_t *hwif = drive->hwif; |
164 | struct request *rq = hwgroup->rq; | 164 | struct request *rq = hwif->rq; |
165 | 165 | ||
166 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 166 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
167 | ide_task_t *task = (ide_task_t *)rq->special; | 167 | ide_task_t *task = (ide_task_t *)rq->special; |
@@ -186,7 +186,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) | |||
186 | return; | 186 | return; |
187 | } | 187 | } |
188 | 188 | ||
189 | hwgroup->rq = NULL; | 189 | hwif->rq = NULL; |
190 | 190 | ||
191 | rq->errors = err; | 191 | rq->errors = err; |
192 | 192 | ||
@@ -199,9 +199,9 @@ EXPORT_SYMBOL(ide_end_drive_cmd); | |||
199 | static void ide_kill_rq(ide_drive_t *drive, struct request *rq) | 199 | static void ide_kill_rq(ide_drive_t *drive, struct request *rq) |
200 | { | 200 | { |
201 | if (rq->rq_disk) { | 201 | if (rq->rq_disk) { |
202 | ide_driver_t *drv; | 202 | struct ide_driver *drv; |
203 | 203 | ||
204 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 204 | drv = *(struct ide_driver **)rq->rq_disk->private_data; |
205 | drv->end_request(drive, 0, 0); | 205 | drv->end_request(drive, 0, 0); |
206 | } else | 206 | } else |
207 | ide_end_request(drive, 0, 0); | 207 | ide_end_request(drive, 0, 0); |
@@ -291,7 +291,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u | |||
291 | return ide_stopped; | 291 | return ide_stopped; |
292 | } | 292 | } |
293 | 293 | ||
294 | ide_startstop_t | 294 | static ide_startstop_t |
295 | __ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | 295 | __ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) |
296 | { | 296 | { |
297 | if (drive->media == ide_disk) | 297 | if (drive->media == ide_disk) |
@@ -299,8 +299,6 @@ __ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | |||
299 | return ide_atapi_error(drive, rq, stat, err); | 299 | return ide_atapi_error(drive, rq, stat, err); |
300 | } | 300 | } |
301 | 301 | ||
302 | EXPORT_SYMBOL_GPL(__ide_error); | ||
303 | |||
304 | /** | 302 | /** |
305 | * ide_error - handle an error on the IDE | 303 | * ide_error - handle an error on the IDE |
306 | * @drive: drive the error occurred on | 304 | * @drive: drive the error occurred on |
@@ -321,7 +319,8 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) | |||
321 | 319 | ||
322 | err = ide_dump_status(drive, msg, stat); | 320 | err = ide_dump_status(drive, msg, stat); |
323 | 321 | ||
324 | if ((rq = HWGROUP(drive)->rq) == NULL) | 322 | rq = drive->hwif->rq; |
323 | if (rq == NULL) | ||
325 | return ide_stopped; | 324 | return ide_stopped; |
326 | 325 | ||
327 | /* retry only "normal" I/O: */ | 326 | /* retry only "normal" I/O: */ |
@@ -331,15 +330,8 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) | |||
331 | return ide_stopped; | 330 | return ide_stopped; |
332 | } | 331 | } |
333 | 332 | ||
334 | if (rq->rq_disk) { | 333 | return __ide_error(drive, rq, stat, err); |
335 | ide_driver_t *drv; | ||
336 | |||
337 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | ||
338 | return drv->error(drive, rq, stat, err); | ||
339 | } else | ||
340 | return __ide_error(drive, rq, stat, err); | ||
341 | } | 334 | } |
342 | |||
343 | EXPORT_SYMBOL_GPL(ide_error); | 335 | EXPORT_SYMBOL_GPL(ide_error); |
344 | 336 | ||
345 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | 337 | static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) |
@@ -462,7 +454,7 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd); | |||
462 | static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | 454 | static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, |
463 | struct request *rq) | 455 | struct request *rq) |
464 | { | 456 | { |
465 | ide_hwif_t *hwif = HWIF(drive); | 457 | ide_hwif_t *hwif = drive->hwif; |
466 | ide_task_t *task = rq->special; | 458 | ide_task_t *task = rq->special; |
467 | 459 | ||
468 | if (task) { | 460 | if (task) { |
@@ -586,7 +578,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
586 | 578 | ||
587 | #ifdef DEBUG | 579 | #ifdef DEBUG |
588 | printk("%s: start_request: current=0x%08lx\n", | 580 | printk("%s: start_request: current=0x%08lx\n", |
589 | HWIF(drive)->name, (unsigned long) rq); | 581 | drive->hwif->name, (unsigned long) rq); |
590 | #endif | 582 | #endif |
591 | 583 | ||
592 | /* bail early if we've exceeded max_failures */ | 584 | /* bail early if we've exceeded max_failures */ |
@@ -605,7 +597,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
605 | return startstop; | 597 | return startstop; |
606 | } | 598 | } |
607 | if (!drive->special.all) { | 599 | if (!drive->special.all) { |
608 | ide_driver_t *drv; | 600 | struct ide_driver *drv; |
609 | 601 | ||
610 | /* | 602 | /* |
611 | * We reset the drive so we need to issue a SETFEATURES. | 603 | * We reset the drive so we need to issue a SETFEATURES. |
@@ -638,7 +630,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) | |||
638 | */ | 630 | */ |
639 | return ide_special_rq(drive, rq); | 631 | return ide_special_rq(drive, rq); |
640 | 632 | ||
641 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 633 | drv = *(struct ide_driver **)rq->rq_disk->private_data; |
642 | 634 | ||
643 | return drv->do_request(drive, rq, rq->sector); | 635 | return drv->do_request(drive, rq, rq->sector); |
644 | } | 636 | } |
@@ -654,7 +646,7 @@ kill_rq: | |||
654 | * @timeout: time to stall for (jiffies) | 646 | * @timeout: time to stall for (jiffies) |
655 | * | 647 | * |
656 | * ide_stall_queue() can be used by a drive to give excess bandwidth back | 648 | * ide_stall_queue() can be used by a drive to give excess bandwidth back |
657 | * to the hwgroup by sleeping for timeout jiffies. | 649 | * to the port by sleeping for timeout jiffies. |
658 | */ | 650 | */ |
659 | 651 | ||
660 | void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) | 652 | void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) |
@@ -666,45 +658,53 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout) | |||
666 | } | 658 | } |
667 | EXPORT_SYMBOL(ide_stall_queue); | 659 | EXPORT_SYMBOL(ide_stall_queue); |
668 | 660 | ||
661 | static inline int ide_lock_port(ide_hwif_t *hwif) | ||
662 | { | ||
663 | if (hwif->busy) | ||
664 | return 1; | ||
665 | |||
666 | hwif->busy = 1; | ||
667 | |||
668 | return 0; | ||
669 | } | ||
670 | |||
671 | static inline void ide_unlock_port(ide_hwif_t *hwif) | ||
672 | { | ||
673 | hwif->busy = 0; | ||
674 | } | ||
675 | |||
676 | static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif) | ||
677 | { | ||
678 | int rc = 0; | ||
679 | |||
680 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { | ||
681 | rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy); | ||
682 | if (rc == 0) { | ||
683 | /* for atari only */ | ||
684 | ide_get_lock(ide_intr, hwif); | ||
685 | } | ||
686 | } | ||
687 | return rc; | ||
688 | } | ||
689 | |||
690 | static inline void ide_unlock_host(struct ide_host *host) | ||
691 | { | ||
692 | if (host->host_flags & IDE_HFLAG_SERIALIZE) { | ||
693 | /* for atari only */ | ||
694 | ide_release_lock(); | ||
695 | clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy); | ||
696 | } | ||
697 | } | ||
698 | |||
669 | /* | 699 | /* |
670 | * Issue a new request to a drive from hwgroup | 700 | * Issue a new request to a device. |
671 | * | ||
672 | * A hwgroup is a serialized group of IDE interfaces. Usually there is | ||
673 | * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) | ||
674 | * may have both interfaces in a single hwgroup to "serialize" access. | ||
675 | * Or possibly multiple ISA interfaces can share a common IRQ by being grouped | ||
676 | * together into one hwgroup for serialized access. | ||
677 | * | ||
678 | * Note also that several hwgroups can end up sharing a single IRQ, | ||
679 | * possibly along with many other devices. This is especially common in | ||
680 | * PCI-based systems with off-board IDE controller cards. | ||
681 | * | ||
682 | * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag. | ||
683 | * | ||
684 | * The first thread into the driver for a particular hwgroup sets the | ||
685 | * hwgroup->busy flag to indicate that this hwgroup is now active, | ||
686 | * and then initiates processing of the top request from the request queue. | ||
687 | * | ||
688 | * Other threads attempting entry notice the busy setting, and will simply | ||
689 | * queue their new requests and exit immediately. Note that hwgroup->busy | ||
690 | * remains set even when the driver is merely awaiting the next interrupt. | ||
691 | * Thus, the meaning is "this hwgroup is busy processing a request". | ||
692 | * | ||
693 | * When processing of a request completes, the completing thread or IRQ-handler | ||
694 | * will start the next request from the queue. If no more work remains, | ||
695 | * the driver will clear the hwgroup->busy flag and exit. | ||
696 | * | ||
697 | * The per-hwgroup spinlock is used to protect all access to the | ||
698 | * hwgroup->busy flag, but is otherwise not needed for most processing in | ||
699 | * the driver. This makes the driver much more friendlier to shared IRQs | ||
700 | * than previous designs, while remaining 100% (?) SMP safe and capable. | ||
701 | */ | 701 | */ |
702 | void do_ide_request(struct request_queue *q) | 702 | void do_ide_request(struct request_queue *q) |
703 | { | 703 | { |
704 | ide_drive_t *drive = q->queuedata; | 704 | ide_drive_t *drive = q->queuedata; |
705 | ide_hwif_t *hwif = drive->hwif; | 705 | ide_hwif_t *hwif = drive->hwif; |
706 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | 706 | struct ide_host *host = hwif->host; |
707 | struct request *rq; | 707 | struct request *rq = NULL; |
708 | ide_startstop_t startstop; | 708 | ide_startstop_t startstop; |
709 | 709 | ||
710 | /* | 710 | /* |
@@ -721,32 +721,40 @@ void do_ide_request(struct request_queue *q) | |||
721 | blk_remove_plug(q); | 721 | blk_remove_plug(q); |
722 | 722 | ||
723 | spin_unlock_irq(q->queue_lock); | 723 | spin_unlock_irq(q->queue_lock); |
724 | spin_lock_irq(&hwgroup->lock); | ||
725 | 724 | ||
726 | if (!ide_lock_hwgroup(hwgroup)) { | 725 | if (ide_lock_host(host, hwif)) |
726 | goto plug_device_2; | ||
727 | |||
728 | spin_lock_irq(&hwif->lock); | ||
729 | |||
730 | if (!ide_lock_port(hwif)) { | ||
731 | ide_hwif_t *prev_port; | ||
727 | repeat: | 732 | repeat: |
728 | hwgroup->rq = NULL; | 733 | prev_port = hwif->host->cur_port; |
734 | hwif->rq = NULL; | ||
729 | 735 | ||
730 | if (drive->dev_flags & IDE_DFLAG_SLEEPING) { | 736 | if (drive->dev_flags & IDE_DFLAG_SLEEPING) { |
731 | if (time_before(drive->sleep, jiffies)) { | 737 | if (time_before(drive->sleep, jiffies)) { |
732 | ide_unlock_hwgroup(hwgroup); | 738 | ide_unlock_port(hwif); |
733 | goto plug_device; | 739 | goto plug_device; |
734 | } | 740 | } |
735 | } | 741 | } |
736 | 742 | ||
737 | if (hwif != hwgroup->hwif) { | 743 | if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) && |
744 | hwif != prev_port) { | ||
738 | /* | 745 | /* |
739 | * set nIEN for previous hwif, drives in the | 746 | * set nIEN for previous port, drives in the |
740 | * quirk_list may not like intr setups/cleanups | 747 | * quirk_list may not like intr setups/cleanups |
741 | */ | 748 | */ |
742 | if (drive->quirk_list == 0) | 749 | if (prev_port && prev_port->cur_dev->quirk_list == 0) |
743 | hwif->tp_ops->set_irq(hwif, 0); | 750 | prev_port->tp_ops->set_irq(prev_port, 0); |
751 | |||
752 | hwif->host->cur_port = hwif; | ||
744 | } | 753 | } |
745 | hwgroup->hwif = hwif; | 754 | hwif->cur_dev = drive; |
746 | hwgroup->drive = drive; | ||
747 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); | 755 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
748 | 756 | ||
749 | spin_unlock_irq(&hwgroup->lock); | 757 | spin_unlock_irq(&hwif->lock); |
750 | spin_lock_irq(q->queue_lock); | 758 | spin_lock_irq(q->queue_lock); |
751 | /* | 759 | /* |
752 | * we know that the queue isn't empty, but this can happen | 760 | * we know that the queue isn't empty, but this can happen |
@@ -754,10 +762,10 @@ repeat: | |||
754 | */ | 762 | */ |
755 | rq = elv_next_request(drive->queue); | 763 | rq = elv_next_request(drive->queue); |
756 | spin_unlock_irq(q->queue_lock); | 764 | spin_unlock_irq(q->queue_lock); |
757 | spin_lock_irq(&hwgroup->lock); | 765 | spin_lock_irq(&hwif->lock); |
758 | 766 | ||
759 | if (!rq) { | 767 | if (!rq) { |
760 | ide_unlock_hwgroup(hwgroup); | 768 | ide_unlock_port(hwif); |
761 | goto out; | 769 | goto out; |
762 | } | 770 | } |
763 | 771 | ||
@@ -778,27 +786,31 @@ repeat: | |||
778 | blk_pm_request(rq) == 0 && | 786 | blk_pm_request(rq) == 0 && |
779 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | 787 | (rq->cmd_flags & REQ_PREEMPT) == 0) { |
780 | /* there should be no pending command at this point */ | 788 | /* there should be no pending command at this point */ |
781 | ide_unlock_hwgroup(hwgroup); | 789 | ide_unlock_port(hwif); |
782 | goto plug_device; | 790 | goto plug_device; |
783 | } | 791 | } |
784 | 792 | ||
785 | hwgroup->rq = rq; | 793 | hwif->rq = rq; |
786 | 794 | ||
787 | spin_unlock_irq(&hwgroup->lock); | 795 | spin_unlock_irq(&hwif->lock); |
788 | startstop = start_request(drive, rq); | 796 | startstop = start_request(drive, rq); |
789 | spin_lock_irq(&hwgroup->lock); | 797 | spin_lock_irq(&hwif->lock); |
790 | 798 | ||
791 | if (startstop == ide_stopped) | 799 | if (startstop == ide_stopped) |
792 | goto repeat; | 800 | goto repeat; |
793 | } else | 801 | } else |
794 | goto plug_device; | 802 | goto plug_device; |
795 | out: | 803 | out: |
796 | spin_unlock_irq(&hwgroup->lock); | 804 | spin_unlock_irq(&hwif->lock); |
805 | if (rq == NULL) | ||
806 | ide_unlock_host(host); | ||
797 | spin_lock_irq(q->queue_lock); | 807 | spin_lock_irq(q->queue_lock); |
798 | return; | 808 | return; |
799 | 809 | ||
800 | plug_device: | 810 | plug_device: |
801 | spin_unlock_irq(&hwgroup->lock); | 811 | spin_unlock_irq(&hwif->lock); |
812 | ide_unlock_host(host); | ||
813 | plug_device_2: | ||
802 | spin_lock_irq(q->queue_lock); | 814 | spin_lock_irq(q->queue_lock); |
803 | 815 | ||
804 | if (!elv_queue_empty(q)) | 816 | if (!elv_queue_empty(q)) |
@@ -806,13 +818,13 @@ plug_device: | |||
806 | } | 818 | } |
807 | 819 | ||
808 | /* | 820 | /* |
809 | * un-busy the hwgroup etc, and clear any pending DMA status. we want to | 821 | * un-busy the port etc, and clear any pending DMA status. we want to |
810 | * retry the current request in pio mode instead of risking tossing it | 822 | * retry the current request in pio mode instead of risking tossing it |
811 | * all away | 823 | * all away |
812 | */ | 824 | */ |
813 | static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | 825 | static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) |
814 | { | 826 | { |
815 | ide_hwif_t *hwif = HWIF(drive); | 827 | ide_hwif_t *hwif = drive->hwif; |
816 | struct request *rq; | 828 | struct request *rq; |
817 | ide_startstop_t ret = ide_stopped; | 829 | ide_startstop_t ret = ide_stopped; |
818 | 830 | ||
@@ -840,15 +852,14 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
840 | ide_dma_off_quietly(drive); | 852 | ide_dma_off_quietly(drive); |
841 | 853 | ||
842 | /* | 854 | /* |
843 | * un-busy drive etc (hwgroup->busy is cleared on return) and | 855 | * un-busy drive etc and make sure request is sane |
844 | * make sure request is sane | ||
845 | */ | 856 | */ |
846 | rq = HWGROUP(drive)->rq; | ||
847 | 857 | ||
858 | rq = hwif->rq; | ||
848 | if (!rq) | 859 | if (!rq) |
849 | goto out; | 860 | goto out; |
850 | 861 | ||
851 | HWGROUP(drive)->rq = NULL; | 862 | hwif->rq = NULL; |
852 | 863 | ||
853 | rq->errors = 0; | 864 | rq->errors = 0; |
854 | 865 | ||
@@ -876,7 +887,7 @@ static void ide_plug_device(ide_drive_t *drive) | |||
876 | 887 | ||
877 | /** | 888 | /** |
878 | * ide_timer_expiry - handle lack of an IDE interrupt | 889 | * ide_timer_expiry - handle lack of an IDE interrupt |
879 | * @data: timer callback magic (hwgroup) | 890 | * @data: timer callback magic (hwif) |
880 | * | 891 | * |
881 | * An IDE command has timed out before the expected drive return | 892 | * An IDE command has timed out before the expected drive return |
882 | * occurred. At this point we attempt to clean up the current | 893 | * occurred. At this point we attempt to clean up the current |
@@ -890,18 +901,18 @@ static void ide_plug_device(ide_drive_t *drive) | |||
890 | 901 | ||
891 | void ide_timer_expiry (unsigned long data) | 902 | void ide_timer_expiry (unsigned long data) |
892 | { | 903 | { |
893 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data; | 904 | ide_hwif_t *hwif = (ide_hwif_t *)data; |
894 | ide_drive_t *uninitialized_var(drive); | 905 | ide_drive_t *uninitialized_var(drive); |
895 | ide_handler_t *handler; | 906 | ide_handler_t *handler; |
896 | ide_expiry_t *expiry; | ||
897 | unsigned long flags; | 907 | unsigned long flags; |
898 | unsigned long wait = -1; | 908 | unsigned long wait = -1; |
899 | int plug_device = 0; | 909 | int plug_device = 0; |
900 | 910 | ||
901 | spin_lock_irqsave(&hwgroup->lock, flags); | 911 | spin_lock_irqsave(&hwif->lock, flags); |
902 | 912 | ||
903 | if (((handler = hwgroup->handler) == NULL) || | 913 | handler = hwif->handler; |
904 | (hwgroup->req_gen != hwgroup->req_gen_timer)) { | 914 | |
915 | if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) { | ||
905 | /* | 916 | /* |
906 | * Either a marginal timeout occurred | 917 | * Either a marginal timeout occurred |
907 | * (got the interrupt just as timer expired), | 918 | * (got the interrupt just as timer expired), |
@@ -909,72 +920,68 @@ void ide_timer_expiry (unsigned long data) | |||
909 | * Either way, we don't really want to complain about anything. | 920 | * Either way, we don't really want to complain about anything. |
910 | */ | 921 | */ |
911 | } else { | 922 | } else { |
912 | drive = hwgroup->drive; | 923 | ide_expiry_t *expiry = hwif->expiry; |
913 | if (!drive) { | 924 | ide_startstop_t startstop = ide_stopped; |
914 | printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); | 925 | |
915 | hwgroup->handler = NULL; | 926 | drive = hwif->cur_dev; |
916 | } else { | 927 | |
917 | ide_hwif_t *hwif; | 928 | if (expiry) { |
918 | ide_startstop_t startstop = ide_stopped; | 929 | wait = expiry(drive); |
919 | 930 | if (wait > 0) { /* continue */ | |
920 | if ((expiry = hwgroup->expiry) != NULL) { | 931 | /* reset timer */ |
921 | /* continue */ | 932 | hwif->timer.expires = jiffies + wait; |
922 | if ((wait = expiry(drive)) > 0) { | 933 | hwif->req_gen_timer = hwif->req_gen; |
923 | /* reset timer */ | 934 | add_timer(&hwif->timer); |
924 | hwgroup->timer.expires = jiffies + wait; | 935 | spin_unlock_irqrestore(&hwif->lock, flags); |
925 | hwgroup->req_gen_timer = hwgroup->req_gen; | 936 | return; |
926 | add_timer(&hwgroup->timer); | ||
927 | spin_unlock_irqrestore(&hwgroup->lock, flags); | ||
928 | return; | ||
929 | } | ||
930 | } | ||
931 | hwgroup->handler = NULL; | ||
932 | /* | ||
933 | * We need to simulate a real interrupt when invoking | ||
934 | * the handler() function, which means we need to | ||
935 | * globally mask the specific IRQ: | ||
936 | */ | ||
937 | spin_unlock(&hwgroup->lock); | ||
938 | hwif = HWIF(drive); | ||
939 | /* disable_irq_nosync ?? */ | ||
940 | disable_irq(hwif->irq); | ||
941 | /* local CPU only, | ||
942 | * as if we were handling an interrupt */ | ||
943 | local_irq_disable(); | ||
944 | if (hwgroup->polling) { | ||
945 | startstop = handler(drive); | ||
946 | } else if (drive_is_ready(drive)) { | ||
947 | if (drive->waiting_for_dma) | ||
948 | hwif->dma_ops->dma_lost_irq(drive); | ||
949 | (void)ide_ack_intr(hwif); | ||
950 | printk(KERN_WARNING "%s: lost interrupt\n", drive->name); | ||
951 | startstop = handler(drive); | ||
952 | } else { | ||
953 | if (drive->waiting_for_dma) { | ||
954 | startstop = ide_dma_timeout_retry(drive, wait); | ||
955 | } else | ||
956 | startstop = | ||
957 | ide_error(drive, "irq timeout", | ||
958 | hwif->tp_ops->read_status(hwif)); | ||
959 | } | ||
960 | spin_lock_irq(&hwgroup->lock); | ||
961 | enable_irq(hwif->irq); | ||
962 | if (startstop == ide_stopped) { | ||
963 | ide_unlock_hwgroup(hwgroup); | ||
964 | plug_device = 1; | ||
965 | } | 937 | } |
966 | } | 938 | } |
939 | hwif->handler = NULL; | ||
940 | /* | ||
941 | * We need to simulate a real interrupt when invoking | ||
942 | * the handler() function, which means we need to | ||
943 | * globally mask the specific IRQ: | ||
944 | */ | ||
945 | spin_unlock(&hwif->lock); | ||
946 | /* disable_irq_nosync ?? */ | ||
947 | disable_irq(hwif->irq); | ||
948 | /* local CPU only, as if we were handling an interrupt */ | ||
949 | local_irq_disable(); | ||
950 | if (hwif->polling) { | ||
951 | startstop = handler(drive); | ||
952 | } else if (drive_is_ready(drive)) { | ||
953 | if (drive->waiting_for_dma) | ||
954 | hwif->dma_ops->dma_lost_irq(drive); | ||
955 | (void)ide_ack_intr(hwif); | ||
956 | printk(KERN_WARNING "%s: lost interrupt\n", | ||
957 | drive->name); | ||
958 | startstop = handler(drive); | ||
959 | } else { | ||
960 | if (drive->waiting_for_dma) | ||
961 | startstop = ide_dma_timeout_retry(drive, wait); | ||
962 | else | ||
963 | startstop = ide_error(drive, "irq timeout", | ||
964 | hwif->tp_ops->read_status(hwif)); | ||
965 | } | ||
966 | spin_lock_irq(&hwif->lock); | ||
967 | enable_irq(hwif->irq); | ||
968 | if (startstop == ide_stopped) { | ||
969 | ide_unlock_port(hwif); | ||
970 | plug_device = 1; | ||
971 | } | ||
967 | } | 972 | } |
968 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 973 | spin_unlock_irqrestore(&hwif->lock, flags); |
969 | 974 | ||
970 | if (plug_device) | 975 | if (plug_device) { |
976 | ide_unlock_host(hwif->host); | ||
971 | ide_plug_device(drive); | 977 | ide_plug_device(drive); |
978 | } | ||
972 | } | 979 | } |
973 | 980 | ||
974 | /** | 981 | /** |
975 | * unexpected_intr - handle an unexpected IDE interrupt | 982 | * unexpected_intr - handle an unexpected IDE interrupt |
976 | * @irq: interrupt line | 983 | * @irq: interrupt line |
977 | * @hwgroup: hwgroup being processed | 984 | * @hwif: port being processed |
978 | * | 985 | * |
979 | * There's nothing really useful we can do with an unexpected interrupt, | 986 | * There's nothing really useful we can do with an unexpected interrupt, |
980 | * other than reading the status register (to clear it), and logging it. | 987 | * other than reading the status register (to clear it), and logging it. |
@@ -998,52 +1005,38 @@ void ide_timer_expiry (unsigned long data) | |||
998 | * before completing the issuance of any new drive command, so we will not | 1005 | * before completing the issuance of any new drive command, so we will not |
999 | * be accidentally invoked as a result of any valid command completion | 1006 | * be accidentally invoked as a result of any valid command completion |
1000 | * interrupt. | 1007 | * interrupt. |
1001 | * | ||
1002 | * Note that we must walk the entire hwgroup here. We know which hwif | ||
1003 | * is doing the current command, but we don't know which hwif burped | ||
1004 | * mysteriously. | ||
1005 | */ | 1008 | */ |
1006 | |||
1007 | static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) | ||
1008 | { | ||
1009 | u8 stat; | ||
1010 | ide_hwif_t *hwif = hwgroup->hwif; | ||
1011 | 1009 | ||
1012 | /* | 1010 | static void unexpected_intr(int irq, ide_hwif_t *hwif) |
1013 | * handle the unexpected interrupt | 1011 | { |
1014 | */ | 1012 | u8 stat = hwif->tp_ops->read_status(hwif); |
1015 | do { | 1013 | |
1016 | if (hwif->irq == irq) { | 1014 | if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { |
1017 | stat = hwif->tp_ops->read_status(hwif); | 1015 | /* Try to not flood the console with msgs */ |
1018 | 1016 | static unsigned long last_msgtime, count; | |
1019 | if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) { | 1017 | ++count; |
1020 | /* Try to not flood the console with msgs */ | 1018 | |
1021 | static unsigned long last_msgtime, count; | 1019 | if (time_after(jiffies, last_msgtime + HZ)) { |
1022 | ++count; | 1020 | last_msgtime = jiffies; |
1023 | if (time_after(jiffies, last_msgtime + HZ)) { | 1021 | printk(KERN_ERR "%s: unexpected interrupt, " |
1024 | last_msgtime = jiffies; | 1022 | "status=0x%02x, count=%ld\n", |
1025 | printk(KERN_ERR "%s%s: unexpected interrupt, " | 1023 | hwif->name, stat, count); |
1026 | "status=0x%02x, count=%ld\n", | ||
1027 | hwif->name, | ||
1028 | (hwif->next==hwgroup->hwif) ? "" : "(?)", stat, count); | ||
1029 | } | ||
1030 | } | ||
1031 | } | 1024 | } |
1032 | } while ((hwif = hwif->next) != hwgroup->hwif); | 1025 | } |
1033 | } | 1026 | } |
1034 | 1027 | ||
1035 | /** | 1028 | /** |
1036 | * ide_intr - default IDE interrupt handler | 1029 | * ide_intr - default IDE interrupt handler |
1037 | * @irq: interrupt number | 1030 | * @irq: interrupt number |
1038 | * @dev_id: hwif group | 1031 | * @dev_id: hwif |
1039 | * @regs: unused weirdness from the kernel irq layer | 1032 | * @regs: unused weirdness from the kernel irq layer |
1040 | * | 1033 | * |
1041 | * This is the default IRQ handler for the IDE layer. You should | 1034 | * This is the default IRQ handler for the IDE layer. You should |
1042 | * not need to override it. If you do be aware it is subtle in | 1035 | * not need to override it. If you do be aware it is subtle in |
1043 | * places | 1036 | * places |
1044 | * | 1037 | * |
1045 | * hwgroup->hwif is the interface in the group currently performing | 1038 | * hwif is the interface in the group currently performing |
1046 | * a command. hwgroup->drive is the drive and hwgroup->handler is | 1039 | * a command. hwif->cur_dev is the drive and hwif->handler is |
1047 | * the IRQ handler to call. As we issue a command the handlers | 1040 | * the IRQ handler to call. As we issue a command the handlers |
1048 | * step through multiple states, reassigning the handler to the | 1041 | * step through multiple states, reassigning the handler to the |
1049 | * next step in the process. Unlike a smart SCSI controller IDE | 1042 | * next step in the process. Unlike a smart SCSI controller IDE |
@@ -1054,26 +1047,32 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup) | |||
1054 | * | 1047 | * |
1055 | * The handler eventually returns ide_stopped to indicate the | 1048 | * The handler eventually returns ide_stopped to indicate the |
1056 | * request completed. At this point we issue the next request | 1049 | * request completed. At this point we issue the next request |
1057 | * on the hwgroup and the process begins again. | 1050 | * on the port and the process begins again. |
1058 | */ | 1051 | */ |
1059 | 1052 | ||
1060 | irqreturn_t ide_intr (int irq, void *dev_id) | 1053 | irqreturn_t ide_intr (int irq, void *dev_id) |
1061 | { | 1054 | { |
1062 | unsigned long flags; | 1055 | ide_hwif_t *hwif = (ide_hwif_t *)dev_id; |
1063 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; | ||
1064 | ide_hwif_t *hwif = hwgroup->hwif; | ||
1065 | ide_drive_t *uninitialized_var(drive); | 1056 | ide_drive_t *uninitialized_var(drive); |
1066 | ide_handler_t *handler; | 1057 | ide_handler_t *handler; |
1058 | unsigned long flags; | ||
1067 | ide_startstop_t startstop; | 1059 | ide_startstop_t startstop; |
1068 | irqreturn_t irq_ret = IRQ_NONE; | 1060 | irqreturn_t irq_ret = IRQ_NONE; |
1069 | int plug_device = 0; | 1061 | int plug_device = 0; |
1070 | 1062 | ||
1071 | spin_lock_irqsave(&hwgroup->lock, flags); | 1063 | if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) { |
1064 | if (hwif != hwif->host->cur_port) | ||
1065 | goto out_early; | ||
1066 | } | ||
1067 | |||
1068 | spin_lock_irqsave(&hwif->lock, flags); | ||
1072 | 1069 | ||
1073 | if (!ide_ack_intr(hwif)) | 1070 | if (!ide_ack_intr(hwif)) |
1074 | goto out; | 1071 | goto out; |
1075 | 1072 | ||
1076 | if ((handler = hwgroup->handler) == NULL || hwgroup->polling) { | 1073 | handler = hwif->handler; |
1074 | |||
1075 | if (handler == NULL || hwif->polling) { | ||
1077 | /* | 1076 | /* |
1078 | * Not expecting an interrupt from this drive. | 1077 | * Not expecting an interrupt from this drive. |
1079 | * That means this could be: | 1078 | * That means this could be: |
@@ -1097,7 +1096,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1097 | * Probably not a shared PCI interrupt, | 1096 | * Probably not a shared PCI interrupt, |
1098 | * so we can safely try to do something about it: | 1097 | * so we can safely try to do something about it: |
1099 | */ | 1098 | */ |
1100 | unexpected_intr(irq, hwgroup); | 1099 | unexpected_intr(irq, hwif); |
1101 | #ifdef CONFIG_BLK_DEV_IDEPCI | 1100 | #ifdef CONFIG_BLK_DEV_IDEPCI |
1102 | } else { | 1101 | } else { |
1103 | /* | 1102 | /* |
@@ -1110,16 +1109,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1110 | goto out; | 1109 | goto out; |
1111 | } | 1110 | } |
1112 | 1111 | ||
1113 | drive = hwgroup->drive; | 1112 | drive = hwif->cur_dev; |
1114 | if (!drive) { | ||
1115 | /* | ||
1116 | * This should NEVER happen, and there isn't much | ||
1117 | * we could do about it here. | ||
1118 | * | ||
1119 | * [Note - this can occur if the drive is hot unplugged] | ||
1120 | */ | ||
1121 | goto out_handled; | ||
1122 | } | ||
1123 | 1113 | ||
1124 | if (!drive_is_ready(drive)) | 1114 | if (!drive_is_ready(drive)) |
1125 | /* | 1115 | /* |
@@ -1131,10 +1121,10 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1131 | */ | 1121 | */ |
1132 | goto out; | 1122 | goto out; |
1133 | 1123 | ||
1134 | hwgroup->handler = NULL; | 1124 | hwif->handler = NULL; |
1135 | hwgroup->req_gen++; | 1125 | hwif->req_gen++; |
1136 | del_timer(&hwgroup->timer); | 1126 | del_timer(&hwif->timer); |
1137 | spin_unlock(&hwgroup->lock); | 1127 | spin_unlock(&hwif->lock); |
1138 | 1128 | ||
1139 | if (hwif->port_ops && hwif->port_ops->clear_irq) | 1129 | if (hwif->port_ops && hwif->port_ops->clear_irq) |
1140 | hwif->port_ops->clear_irq(drive); | 1130 | hwif->port_ops->clear_irq(drive); |
@@ -1145,7 +1135,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1145 | /* service this interrupt, may set handler for next interrupt */ | 1135 | /* service this interrupt, may set handler for next interrupt */ |
1146 | startstop = handler(drive); | 1136 | startstop = handler(drive); |
1147 | 1137 | ||
1148 | spin_lock_irq(&hwgroup->lock); | 1138 | spin_lock_irq(&hwif->lock); |
1149 | /* | 1139 | /* |
1150 | * Note that handler() may have set things up for another | 1140 | * Note that handler() may have set things up for another |
1151 | * interrupt to occur soon, but it cannot happen until | 1141 | * interrupt to occur soon, but it cannot happen until |
@@ -1154,20 +1144,18 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1154 | * won't allow another of the same (on any CPU) until we return. | 1144 | * won't allow another of the same (on any CPU) until we return. |
1155 | */ | 1145 | */ |
1156 | if (startstop == ide_stopped) { | 1146 | if (startstop == ide_stopped) { |
1157 | if (hwgroup->handler == NULL) { /* paranoia */ | 1147 | BUG_ON(hwif->handler); |
1158 | ide_unlock_hwgroup(hwgroup); | 1148 | ide_unlock_port(hwif); |
1159 | plug_device = 1; | 1149 | plug_device = 1; |
1160 | } else | ||
1161 | printk(KERN_ERR "%s: %s: huh? expected NULL handler " | ||
1162 | "on exit\n", __func__, drive->name); | ||
1163 | } | 1150 | } |
1164 | out_handled: | ||
1165 | irq_ret = IRQ_HANDLED; | 1151 | irq_ret = IRQ_HANDLED; |
1166 | out: | 1152 | out: |
1167 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1153 | spin_unlock_irqrestore(&hwif->lock, flags); |
1168 | 1154 | out_early: | |
1169 | if (plug_device) | 1155 | if (plug_device) { |
1156 | ide_unlock_host(hwif->host); | ||
1170 | ide_plug_device(drive); | 1157 | ide_plug_device(drive); |
1158 | } | ||
1171 | 1159 | ||
1172 | return irq_ret; | 1160 | return irq_ret; |
1173 | } | 1161 | } |
@@ -1189,15 +1177,13 @@ out: | |||
1189 | 1177 | ||
1190 | void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) | 1178 | void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) |
1191 | { | 1179 | { |
1192 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
1193 | struct request_queue *q = drive->queue; | 1180 | struct request_queue *q = drive->queue; |
1194 | unsigned long flags; | 1181 | unsigned long flags; |
1195 | 1182 | ||
1196 | hwgroup->rq = NULL; | 1183 | drive->hwif->rq = NULL; |
1197 | 1184 | ||
1198 | spin_lock_irqsave(q->queue_lock, flags); | 1185 | spin_lock_irqsave(q->queue_lock, flags); |
1199 | __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); | 1186 | __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); |
1200 | blk_start_queueing(q); | ||
1201 | spin_unlock_irqrestore(q->queue_lock, flags); | 1187 | spin_unlock_irqrestore(q->queue_lock, flags); |
1202 | } | 1188 | } |
1203 | EXPORT_SYMBOL(ide_do_drive_cmd); | 1189 | EXPORT_SYMBOL(ide_do_drive_cmd); |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index ad8bd6539283..e728cfe7273f 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -105,15 +105,6 @@ u8 ide_read_altstatus(ide_hwif_t *hwif) | |||
105 | } | 105 | } |
106 | EXPORT_SYMBOL_GPL(ide_read_altstatus); | 106 | EXPORT_SYMBOL_GPL(ide_read_altstatus); |
107 | 107 | ||
108 | u8 ide_read_sff_dma_status(ide_hwif_t *hwif) | ||
109 | { | ||
110 | if (hwif->host_flags & IDE_HFLAG_MMIO) | ||
111 | return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
112 | else | ||
113 | return inb(hwif->dma_base + ATA_DMA_STATUS); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(ide_read_sff_dma_status); | ||
116 | |||
117 | void ide_set_irq(ide_hwif_t *hwif, int on) | 108 | void ide_set_irq(ide_hwif_t *hwif, int on) |
118 | { | 109 | { |
119 | u8 ctl = ATA_DEVCTL_OBS; | 110 | u8 ctl = ATA_DEVCTL_OBS; |
@@ -388,7 +379,6 @@ const struct ide_tp_ops default_tp_ops = { | |||
388 | .exec_command = ide_exec_command, | 379 | .exec_command = ide_exec_command, |
389 | .read_status = ide_read_status, | 380 | .read_status = ide_read_status, |
390 | .read_altstatus = ide_read_altstatus, | 381 | .read_altstatus = ide_read_altstatus, |
391 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
392 | 382 | ||
393 | .set_irq = ide_set_irq, | 383 | .set_irq = ide_set_irq, |
394 | 384 | ||
@@ -451,7 +441,7 @@ EXPORT_SYMBOL(ide_fixstring); | |||
451 | */ | 441 | */ |
452 | int drive_is_ready (ide_drive_t *drive) | 442 | int drive_is_ready (ide_drive_t *drive) |
453 | { | 443 | { |
454 | ide_hwif_t *hwif = HWIF(drive); | 444 | ide_hwif_t *hwif = drive->hwif; |
455 | u8 stat = 0; | 445 | u8 stat = 0; |
456 | 446 | ||
457 | if (drive->waiting_for_dma) | 447 | if (drive->waiting_for_dma) |
@@ -503,7 +493,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
503 | stat = tp_ops->read_status(hwif); | 493 | stat = tp_ops->read_status(hwif); |
504 | 494 | ||
505 | if (stat & ATA_BUSY) { | 495 | if (stat & ATA_BUSY) { |
506 | local_irq_set(flags); | 496 | local_irq_save(flags); |
497 | local_irq_enable_in_hardirq(); | ||
507 | timeout += jiffies; | 498 | timeout += jiffies; |
508 | while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { | 499 | while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) { |
509 | if (time_after(jiffies, timeout)) { | 500 | if (time_after(jiffies, timeout)) { |
@@ -822,25 +813,25 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
822 | static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, | 813 | static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, |
823 | unsigned int timeout, ide_expiry_t *expiry) | 814 | unsigned int timeout, ide_expiry_t *expiry) |
824 | { | 815 | { |
825 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 816 | ide_hwif_t *hwif = drive->hwif; |
826 | 817 | ||
827 | BUG_ON(hwgroup->handler); | 818 | BUG_ON(hwif->handler); |
828 | hwgroup->handler = handler; | 819 | hwif->handler = handler; |
829 | hwgroup->expiry = expiry; | 820 | hwif->expiry = expiry; |
830 | hwgroup->timer.expires = jiffies + timeout; | 821 | hwif->timer.expires = jiffies + timeout; |
831 | hwgroup->req_gen_timer = hwgroup->req_gen; | 822 | hwif->req_gen_timer = hwif->req_gen; |
832 | add_timer(&hwgroup->timer); | 823 | add_timer(&hwif->timer); |
833 | } | 824 | } |
834 | 825 | ||
835 | void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, | 826 | void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, |
836 | unsigned int timeout, ide_expiry_t *expiry) | 827 | unsigned int timeout, ide_expiry_t *expiry) |
837 | { | 828 | { |
838 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | 829 | ide_hwif_t *hwif = drive->hwif; |
839 | unsigned long flags; | 830 | unsigned long flags; |
840 | 831 | ||
841 | spin_lock_irqsave(&hwgroup->lock, flags); | 832 | spin_lock_irqsave(&hwif->lock, flags); |
842 | __ide_set_handler(drive, handler, timeout, expiry); | 833 | __ide_set_handler(drive, handler, timeout, expiry); |
843 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 834 | spin_unlock_irqrestore(&hwif->lock, flags); |
844 | } | 835 | } |
845 | 836 | ||
846 | EXPORT_SYMBOL(ide_set_handler); | 837 | EXPORT_SYMBOL(ide_set_handler); |
@@ -863,10 +854,9 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, | |||
863 | unsigned timeout, ide_expiry_t *expiry) | 854 | unsigned timeout, ide_expiry_t *expiry) |
864 | { | 855 | { |
865 | ide_hwif_t *hwif = drive->hwif; | 856 | ide_hwif_t *hwif = drive->hwif; |
866 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
867 | unsigned long flags; | 857 | unsigned long flags; |
868 | 858 | ||
869 | spin_lock_irqsave(&hwgroup->lock, flags); | 859 | spin_lock_irqsave(&hwif->lock, flags); |
870 | __ide_set_handler(drive, handler, timeout, expiry); | 860 | __ide_set_handler(drive, handler, timeout, expiry); |
871 | hwif->tp_ops->exec_command(hwif, cmd); | 861 | hwif->tp_ops->exec_command(hwif, cmd); |
872 | /* | 862 | /* |
@@ -876,26 +866,25 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, | |||
876 | * FIXME: we could skip this delay with care on non shared devices | 866 | * FIXME: we could skip this delay with care on non shared devices |
877 | */ | 867 | */ |
878 | ndelay(400); | 868 | ndelay(400); |
879 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 869 | spin_unlock_irqrestore(&hwif->lock, flags); |
880 | } | 870 | } |
881 | EXPORT_SYMBOL(ide_execute_command); | 871 | EXPORT_SYMBOL(ide_execute_command); |
882 | 872 | ||
883 | void ide_execute_pkt_cmd(ide_drive_t *drive) | 873 | void ide_execute_pkt_cmd(ide_drive_t *drive) |
884 | { | 874 | { |
885 | ide_hwif_t *hwif = drive->hwif; | 875 | ide_hwif_t *hwif = drive->hwif; |
886 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
887 | unsigned long flags; | 876 | unsigned long flags; |
888 | 877 | ||
889 | spin_lock_irqsave(&hwgroup->lock, flags); | 878 | spin_lock_irqsave(&hwif->lock, flags); |
890 | hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET); | 879 | hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET); |
891 | ndelay(400); | 880 | ndelay(400); |
892 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 881 | spin_unlock_irqrestore(&hwif->lock, flags); |
893 | } | 882 | } |
894 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); | 883 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); |
895 | 884 | ||
896 | static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) | 885 | static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) |
897 | { | 886 | { |
898 | struct request *rq = drive->hwif->hwgroup->rq; | 887 | struct request *rq = drive->hwif->rq; |
899 | 888 | ||
900 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) | 889 | if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) |
901 | ide_end_request(drive, err ? err : 1, 0); | 890 | ide_end_request(drive, err ? err : 1, 0); |
@@ -913,7 +902,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int); | |||
913 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | 902 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) |
914 | { | 903 | { |
915 | ide_hwif_t *hwif = drive->hwif; | 904 | ide_hwif_t *hwif = drive->hwif; |
916 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
917 | u8 stat; | 905 | u8 stat; |
918 | 906 | ||
919 | SELECT_DRIVE(drive); | 907 | SELECT_DRIVE(drive); |
@@ -923,20 +911,20 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | |||
923 | if (OK_STAT(stat, 0, ATA_BUSY)) | 911 | if (OK_STAT(stat, 0, ATA_BUSY)) |
924 | printk("%s: ATAPI reset complete\n", drive->name); | 912 | printk("%s: ATAPI reset complete\n", drive->name); |
925 | else { | 913 | else { |
926 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 914 | if (time_before(jiffies, hwif->poll_timeout)) { |
927 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | 915 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); |
928 | /* continue polling */ | 916 | /* continue polling */ |
929 | return ide_started; | 917 | return ide_started; |
930 | } | 918 | } |
931 | /* end of polling */ | 919 | /* end of polling */ |
932 | hwgroup->polling = 0; | 920 | hwif->polling = 0; |
933 | printk("%s: ATAPI reset timed-out, status=0x%02x\n", | 921 | printk("%s: ATAPI reset timed-out, status=0x%02x\n", |
934 | drive->name, stat); | 922 | drive->name, stat); |
935 | /* do it the old fashioned way */ | 923 | /* do it the old fashioned way */ |
936 | return do_reset1(drive, 1); | 924 | return do_reset1(drive, 1); |
937 | } | 925 | } |
938 | /* done polling */ | 926 | /* done polling */ |
939 | hwgroup->polling = 0; | 927 | hwif->polling = 0; |
940 | ide_complete_drive_reset(drive, 0); | 928 | ide_complete_drive_reset(drive, 0); |
941 | return ide_stopped; | 929 | return ide_stopped; |
942 | } | 930 | } |
@@ -968,8 +956,7 @@ static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) | |||
968 | */ | 956 | */ |
969 | static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | 957 | static ide_startstop_t reset_pollfunc (ide_drive_t *drive) |
970 | { | 958 | { |
971 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 959 | ide_hwif_t *hwif = drive->hwif; |
972 | ide_hwif_t *hwif = HWIF(drive); | ||
973 | const struct ide_port_ops *port_ops = hwif->port_ops; | 960 | const struct ide_port_ops *port_ops = hwif->port_ops; |
974 | u8 tmp; | 961 | u8 tmp; |
975 | int err = 0; | 962 | int err = 0; |
@@ -986,7 +973,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
986 | tmp = hwif->tp_ops->read_status(hwif); | 973 | tmp = hwif->tp_ops->read_status(hwif); |
987 | 974 | ||
988 | if (!OK_STAT(tmp, 0, ATA_BUSY)) { | 975 | if (!OK_STAT(tmp, 0, ATA_BUSY)) { |
989 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 976 | if (time_before(jiffies, hwif->poll_timeout)) { |
990 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | 977 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); |
991 | /* continue polling */ | 978 | /* continue polling */ |
992 | return ide_started; | 979 | return ide_started; |
@@ -1007,7 +994,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
1007 | } | 994 | } |
1008 | } | 995 | } |
1009 | out: | 996 | out: |
1010 | hwgroup->polling = 0; /* done polling */ | 997 | hwif->polling = 0; /* done polling */ |
1011 | ide_complete_drive_reset(drive, err); | 998 | ide_complete_drive_reset(drive, err); |
1012 | return ide_stopped; | 999 | return ide_stopped; |
1013 | } | 1000 | } |
@@ -1081,18 +1068,18 @@ static void pre_reset(ide_drive_t *drive) | |||
1081 | static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | 1068 | static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) |
1082 | { | 1069 | { |
1083 | ide_hwif_t *hwif = drive->hwif; | 1070 | ide_hwif_t *hwif = drive->hwif; |
1084 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
1085 | struct ide_io_ports *io_ports = &hwif->io_ports; | 1071 | struct ide_io_ports *io_ports = &hwif->io_ports; |
1086 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 1072 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
1087 | const struct ide_port_ops *port_ops; | 1073 | const struct ide_port_ops *port_ops; |
1074 | ide_drive_t *tdrive; | ||
1088 | unsigned long flags, timeout; | 1075 | unsigned long flags, timeout; |
1089 | unsigned int unit; | 1076 | int i; |
1090 | DEFINE_WAIT(wait); | 1077 | DEFINE_WAIT(wait); |
1091 | 1078 | ||
1092 | spin_lock_irqsave(&hwgroup->lock, flags); | 1079 | spin_lock_irqsave(&hwif->lock, flags); |
1093 | 1080 | ||
1094 | /* We must not reset with running handlers */ | 1081 | /* We must not reset with running handlers */ |
1095 | BUG_ON(hwgroup->handler != NULL); | 1082 | BUG_ON(hwif->handler != NULL); |
1096 | 1083 | ||
1097 | /* For an ATAPI device, first try an ATAPI SRST. */ | 1084 | /* For an ATAPI device, first try an ATAPI SRST. */ |
1098 | if (drive->media != ide_disk && !do_not_try_atapi) { | 1085 | if (drive->media != ide_disk && !do_not_try_atapi) { |
@@ -1101,10 +1088,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1101 | udelay (20); | 1088 | udelay (20); |
1102 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); | 1089 | tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET); |
1103 | ndelay(400); | 1090 | ndelay(400); |
1104 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1091 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; |
1105 | hwgroup->polling = 1; | 1092 | hwif->polling = 1; |
1106 | __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | 1093 | __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); |
1107 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1094 | spin_unlock_irqrestore(&hwif->lock, flags); |
1108 | return ide_started; | 1095 | return ide_started; |
1109 | } | 1096 | } |
1110 | 1097 | ||
@@ -1114,9 +1101,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1114 | 1101 | ||
1115 | prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); | 1102 | prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); |
1116 | timeout = jiffies; | 1103 | timeout = jiffies; |
1117 | for (unit = 0; unit < MAX_DRIVES; unit++) { | 1104 | ide_port_for_each_dev(i, tdrive, hwif) { |
1118 | ide_drive_t *tdrive = &hwif->drives[unit]; | ||
1119 | |||
1120 | if (tdrive->dev_flags & IDE_DFLAG_PRESENT && | 1105 | if (tdrive->dev_flags & IDE_DFLAG_PRESENT && |
1121 | tdrive->dev_flags & IDE_DFLAG_PARKED && | 1106 | tdrive->dev_flags & IDE_DFLAG_PARKED && |
1122 | time_after(tdrive->sleep, timeout)) | 1107 | time_after(tdrive->sleep, timeout)) |
@@ -1127,9 +1112,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1127 | if (time_before_eq(timeout, now)) | 1112 | if (time_before_eq(timeout, now)) |
1128 | break; | 1113 | break; |
1129 | 1114 | ||
1130 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1115 | spin_unlock_irqrestore(&hwif->lock, flags); |
1131 | timeout = schedule_timeout_uninterruptible(timeout - now); | 1116 | timeout = schedule_timeout_uninterruptible(timeout - now); |
1132 | spin_lock_irqsave(&hwgroup->lock, flags); | 1117 | spin_lock_irqsave(&hwif->lock, flags); |
1133 | } while (timeout); | 1118 | } while (timeout); |
1134 | finish_wait(&ide_park_wq, &wait); | 1119 | finish_wait(&ide_park_wq, &wait); |
1135 | 1120 | ||
@@ -1137,11 +1122,11 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1137 | * First, reset any device state data we were maintaining | 1122 | * First, reset any device state data we were maintaining |
1138 | * for any of the drives on this interface. | 1123 | * for any of the drives on this interface. |
1139 | */ | 1124 | */ |
1140 | for (unit = 0; unit < MAX_DRIVES; ++unit) | 1125 | ide_port_for_each_dev(i, tdrive, hwif) |
1141 | pre_reset(&hwif->drives[unit]); | 1126 | pre_reset(tdrive); |
1142 | 1127 | ||
1143 | if (io_ports->ctl_addr == 0) { | 1128 | if (io_ports->ctl_addr == 0) { |
1144 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1129 | spin_unlock_irqrestore(&hwif->lock, flags); |
1145 | ide_complete_drive_reset(drive, -ENXIO); | 1130 | ide_complete_drive_reset(drive, -ENXIO); |
1146 | return ide_stopped; | 1131 | return ide_stopped; |
1147 | } | 1132 | } |
@@ -1164,8 +1149,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1164 | tp_ops->set_irq(hwif, drive->quirk_list == 2); | 1149 | tp_ops->set_irq(hwif, drive->quirk_list == 2); |
1165 | /* more than enough time */ | 1150 | /* more than enough time */ |
1166 | udelay(10); | 1151 | udelay(10); |
1167 | hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE; | 1152 | hwif->poll_timeout = jiffies + WAIT_WORSTCASE; |
1168 | hwgroup->polling = 1; | 1153 | hwif->polling = 1; |
1169 | __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | 1154 | __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); |
1170 | 1155 | ||
1171 | /* | 1156 | /* |
@@ -1177,7 +1162,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1177 | if (port_ops && port_ops->resetproc) | 1162 | if (port_ops && port_ops->resetproc) |
1178 | port_ops->resetproc(drive); | 1163 | port_ops->resetproc(drive); |
1179 | 1164 | ||
1180 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 1165 | spin_unlock_irqrestore(&hwif->lock, flags); |
1181 | return ide_started; | 1166 | return ide_started; |
1182 | } | 1167 | } |
1183 | 1168 | ||
@@ -1221,6 +1206,3 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
1221 | } | 1206 | } |
1222 | return -EBUSY; | 1207 | return -EBUSY; |
1223 | } | 1208 | } |
1224 | |||
1225 | EXPORT_SYMBOL_GPL(ide_wait_not_busy); | ||
1226 | |||
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 9f6e33d8a8b2..09526a0de734 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -273,7 +273,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | |||
273 | 273 | ||
274 | static void ide_dump_opcode(ide_drive_t *drive) | 274 | static void ide_dump_opcode(ide_drive_t *drive) |
275 | { | 275 | { |
276 | struct request *rq = drive->hwif->hwgroup->rq; | 276 | struct request *rq = drive->hwif->rq; |
277 | ide_task_t *task = NULL; | 277 | ide_task_t *task = NULL; |
278 | 278 | ||
279 | if (!rq) | 279 | if (!rq) |
@@ -346,10 +346,13 @@ static void ide_dump_ata_error(ide_drive_t *drive, u8 err) | |||
346 | printk(KERN_CONT "}"); | 346 | printk(KERN_CONT "}"); |
347 | if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK || | 347 | if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK || |
348 | (err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) { | 348 | (err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) { |
349 | struct request *rq = drive->hwif->rq; | ||
350 | |||
349 | ide_dump_sector(drive); | 351 | ide_dump_sector(drive); |
350 | if (HWGROUP(drive) && HWGROUP(drive)->rq) | 352 | |
353 | if (rq) | ||
351 | printk(KERN_CONT ", sector=%llu", | 354 | printk(KERN_CONT ", sector=%llu", |
352 | (unsigned long long)HWGROUP(drive)->rq->sector); | 355 | (unsigned long long)rq->sector); |
353 | } | 356 | } |
354 | printk(KERN_CONT "\n"); | 357 | printk(KERN_CONT "\n"); |
355 | } | 358 | } |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 678454ac2483..c875a957596c 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
@@ -7,22 +7,22 @@ DECLARE_WAIT_QUEUE_HEAD(ide_park_wq); | |||
7 | 7 | ||
8 | static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) | 8 | static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) |
9 | { | 9 | { |
10 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | 10 | ide_hwif_t *hwif = drive->hwif; |
11 | struct request_queue *q = drive->queue; | 11 | struct request_queue *q = drive->queue; |
12 | struct request *rq; | 12 | struct request *rq; |
13 | int rc; | 13 | int rc; |
14 | 14 | ||
15 | timeout += jiffies; | 15 | timeout += jiffies; |
16 | spin_lock_irq(&hwgroup->lock); | 16 | spin_lock_irq(&hwif->lock); |
17 | if (drive->dev_flags & IDE_DFLAG_PARKED) { | 17 | if (drive->dev_flags & IDE_DFLAG_PARKED) { |
18 | int reset_timer = time_before(timeout, drive->sleep); | 18 | int reset_timer = time_before(timeout, drive->sleep); |
19 | int start_queue = 0; | 19 | int start_queue = 0; |
20 | 20 | ||
21 | drive->sleep = timeout; | 21 | drive->sleep = timeout; |
22 | wake_up_all(&ide_park_wq); | 22 | wake_up_all(&ide_park_wq); |
23 | if (reset_timer && del_timer(&hwgroup->timer)) | 23 | if (reset_timer && del_timer(&hwif->timer)) |
24 | start_queue = 1; | 24 | start_queue = 1; |
25 | spin_unlock_irq(&hwgroup->lock); | 25 | spin_unlock_irq(&hwif->lock); |
26 | 26 | ||
27 | if (start_queue) { | 27 | if (start_queue) { |
28 | spin_lock_irq(q->queue_lock); | 28 | spin_lock_irq(q->queue_lock); |
@@ -31,7 +31,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) | |||
31 | } | 31 | } |
32 | return; | 32 | return; |
33 | } | 33 | } |
34 | spin_unlock_irq(&hwgroup->lock); | 34 | spin_unlock_irq(&hwif->lock); |
35 | 35 | ||
36 | rq = blk_get_request(q, READ, __GFP_WAIT); | 36 | rq = blk_get_request(q, READ, __GFP_WAIT); |
37 | rq->cmd[0] = REQ_PARK_HEADS; | 37 | rq->cmd[0] = REQ_PARK_HEADS; |
@@ -64,21 +64,21 @@ ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, | |||
64 | char *buf) | 64 | char *buf) |
65 | { | 65 | { |
66 | ide_drive_t *drive = to_ide_device(dev); | 66 | ide_drive_t *drive = to_ide_device(dev); |
67 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | 67 | ide_hwif_t *hwif = drive->hwif; |
68 | unsigned long now; | 68 | unsigned long now; |
69 | unsigned int msecs; | 69 | unsigned int msecs; |
70 | 70 | ||
71 | if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) | 71 | if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD) |
72 | return -EOPNOTSUPP; | 72 | return -EOPNOTSUPP; |
73 | 73 | ||
74 | spin_lock_irq(&hwgroup->lock); | 74 | spin_lock_irq(&hwif->lock); |
75 | now = jiffies; | 75 | now = jiffies; |
76 | if (drive->dev_flags & IDE_DFLAG_PARKED && | 76 | if (drive->dev_flags & IDE_DFLAG_PARKED && |
77 | time_after(drive->sleep, now)) | 77 | time_after(drive->sleep, now)) |
78 | msecs = jiffies_to_msecs(drive->sleep - now); | 78 | msecs = jiffies_to_msecs(drive->sleep - now); |
79 | else | 79 | else |
80 | msecs = 0; | 80 | msecs = 0; |
81 | spin_unlock_irq(&hwgroup->lock); | 81 | spin_unlock_irq(&hwif->lock); |
82 | 82 | ||
83 | return snprintf(buf, 20, "%u\n", msecs); | 83 | return snprintf(buf, 20, "%u\n", msecs); |
84 | } | 84 | } |
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 8282c6086e6a..4b3bf6a06b70 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c | |||
@@ -5,7 +5,7 @@ | |||
5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) | 5 | int generic_ide_suspend(struct device *dev, pm_message_t mesg) |
6 | { | 6 | { |
7 | ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); | 7 | ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); |
8 | ide_hwif_t *hwif = HWIF(drive); | 8 | ide_hwif_t *hwif = drive->hwif; |
9 | struct request *rq; | 9 | struct request *rq; |
10 | struct request_pm_state rqpm; | 10 | struct request_pm_state rqpm; |
11 | ide_task_t args; | 11 | ide_task_t args; |
@@ -39,7 +39,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg) | |||
39 | int generic_ide_resume(struct device *dev) | 39 | int generic_ide_resume(struct device *dev) |
40 | { | 40 | { |
41 | ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); | 41 | ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive); |
42 | ide_hwif_t *hwif = HWIF(drive); | 42 | ide_hwif_t *hwif = drive->hwif; |
43 | struct request *rq; | 43 | struct request *rq; |
44 | struct request_pm_state rqpm; | 44 | struct request_pm_state rqpm; |
45 | ide_task_t args; | 45 | ide_task_t args; |
@@ -67,7 +67,7 @@ int generic_ide_resume(struct device *dev) | |||
67 | blk_put_request(rq); | 67 | blk_put_request(rq); |
68 | 68 | ||
69 | if (err == 0 && dev->driver) { | 69 | if (err == 0 && dev->driver) { |
70 | ide_driver_t *drv = to_ide_driver(dev->driver); | 70 | struct ide_driver *drv = to_ide_driver(dev->driver); |
71 | 71 | ||
72 | if (drv->resume) | 72 | if (drv->resume) |
73 | drv->resume(drive); | 73 | drv->resume(drive); |
@@ -194,7 +194,7 @@ void ide_complete_pm_request(ide_drive_t *drive, struct request *rq) | |||
194 | } | 194 | } |
195 | spin_unlock_irqrestore(q->queue_lock, flags); | 195 | spin_unlock_irqrestore(q->queue_lock, flags); |
196 | 196 | ||
197 | drive->hwif->hwgroup->rq = NULL; | 197 | drive->hwif->rq = NULL; |
198 | 198 | ||
199 | if (blk_end_request(rq, 0, 0)) | 199 | if (blk_end_request(rq, 0, 0)) |
200 | BUG(); | 200 | BUG(); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index c5adb7b9c5b5..0ccbb4459fb9 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -189,7 +189,7 @@ static void ide_classify_atapi_dev(ide_drive_t *drive) | |||
189 | 189 | ||
190 | static void do_identify(ide_drive_t *drive, u8 cmd) | 190 | static void do_identify(ide_drive_t *drive, u8 cmd) |
191 | { | 191 | { |
192 | ide_hwif_t *hwif = HWIF(drive); | 192 | ide_hwif_t *hwif = drive->hwif; |
193 | u16 *id = drive->id; | 193 | u16 *id = drive->id; |
194 | char *m = (char *)&id[ATA_ID_PROD]; | 194 | char *m = (char *)&id[ATA_ID_PROD]; |
195 | unsigned long flags; | 195 | unsigned long flags; |
@@ -266,7 +266,7 @@ err_misc: | |||
266 | 266 | ||
267 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | 267 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) |
268 | { | 268 | { |
269 | ide_hwif_t *hwif = HWIF(drive); | 269 | ide_hwif_t *hwif = drive->hwif; |
270 | struct ide_io_ports *io_ports = &hwif->io_ports; | 270 | struct ide_io_ports *io_ports = &hwif->io_ports; |
271 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 271 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
272 | int use_altstatus = 0, rc; | 272 | int use_altstatus = 0, rc; |
@@ -341,7 +341,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
341 | 341 | ||
342 | static int try_to_identify (ide_drive_t *drive, u8 cmd) | 342 | static int try_to_identify (ide_drive_t *drive, u8 cmd) |
343 | { | 343 | { |
344 | ide_hwif_t *hwif = HWIF(drive); | 344 | ide_hwif_t *hwif = drive->hwif; |
345 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 345 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
346 | int retval; | 346 | int retval; |
347 | int autoprobe = 0; | 347 | int autoprobe = 0; |
@@ -438,7 +438,7 @@ static u8 ide_read_device(ide_drive_t *drive) | |||
438 | 438 | ||
439 | static int do_probe (ide_drive_t *drive, u8 cmd) | 439 | static int do_probe (ide_drive_t *drive, u8 cmd) |
440 | { | 440 | { |
441 | ide_hwif_t *hwif = HWIF(drive); | 441 | ide_hwif_t *hwif = drive->hwif; |
442 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 442 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
443 | int rc; | 443 | int rc; |
444 | u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; | 444 | u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat; |
@@ -463,7 +463,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
463 | if (ide_read_device(drive) != drive->select && present == 0) { | 463 | if (ide_read_device(drive) != drive->select && present == 0) { |
464 | if (drive->dn & 1) { | 464 | if (drive->dn & 1) { |
465 | /* exit with drive0 selected */ | 465 | /* exit with drive0 selected */ |
466 | SELECT_DRIVE(&hwif->drives[0]); | 466 | SELECT_DRIVE(hwif->devices[0]); |
467 | /* allow ATA_BUSY to assert & clear */ | 467 | /* allow ATA_BUSY to assert & clear */ |
468 | msleep(50); | 468 | msleep(50); |
469 | } | 469 | } |
@@ -509,7 +509,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
509 | } | 509 | } |
510 | if (drive->dn & 1) { | 510 | if (drive->dn & 1) { |
511 | /* exit with drive0 selected */ | 511 | /* exit with drive0 selected */ |
512 | SELECT_DRIVE(&hwif->drives[0]); | 512 | SELECT_DRIVE(hwif->devices[0]); |
513 | msleep(50); | 513 | msleep(50); |
514 | /* ensure drive irq is clear */ | 514 | /* ensure drive irq is clear */ |
515 | (void)tp_ops->read_status(hwif); | 515 | (void)tp_ops->read_status(hwif); |
@@ -522,7 +522,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
522 | */ | 522 | */ |
523 | static void enable_nest (ide_drive_t *drive) | 523 | static void enable_nest (ide_drive_t *drive) |
524 | { | 524 | { |
525 | ide_hwif_t *hwif = HWIF(drive); | 525 | ide_hwif_t *hwif = drive->hwif; |
526 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 526 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
527 | u8 stat; | 527 | u8 stat; |
528 | 528 | ||
@@ -697,7 +697,8 @@ out: | |||
697 | 697 | ||
698 | static int ide_port_wait_ready(ide_hwif_t *hwif) | 698 | static int ide_port_wait_ready(ide_hwif_t *hwif) |
699 | { | 699 | { |
700 | int unit, rc; | 700 | ide_drive_t *drive; |
701 | int i, rc; | ||
701 | 702 | ||
702 | printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name); | 703 | printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name); |
703 | 704 | ||
@@ -714,9 +715,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) | |||
714 | return rc; | 715 | return rc; |
715 | 716 | ||
716 | /* Now make sure both master & slave are ready */ | 717 | /* Now make sure both master & slave are ready */ |
717 | for (unit = 0; unit < MAX_DRIVES; unit++) { | 718 | ide_port_for_each_dev(i, drive, hwif) { |
718 | ide_drive_t *drive = &hwif->drives[unit]; | ||
719 | |||
720 | /* Ignore disks that we will not probe for later. */ | 719 | /* Ignore disks that we will not probe for later. */ |
721 | if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || | 720 | if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 || |
722 | (drive->dev_flags & IDE_DFLAG_PRESENT)) { | 721 | (drive->dev_flags & IDE_DFLAG_PRESENT)) { |
@@ -732,8 +731,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) | |||
732 | } | 731 | } |
733 | out: | 732 | out: |
734 | /* Exit function with master reselected (let's be sane) */ | 733 | /* Exit function with master reselected (let's be sane) */ |
735 | if (unit) | 734 | if (i) |
736 | SELECT_DRIVE(&hwif->drives[0]); | 735 | SELECT_DRIVE(hwif->devices[0]); |
737 | 736 | ||
738 | return rc; | 737 | return rc; |
739 | } | 738 | } |
@@ -749,7 +748,7 @@ out: | |||
749 | 748 | ||
750 | void ide_undecoded_slave(ide_drive_t *dev1) | 749 | void ide_undecoded_slave(ide_drive_t *dev1) |
751 | { | 750 | { |
752 | ide_drive_t *dev0 = &dev1->hwif->drives[0]; | 751 | ide_drive_t *dev0 = dev1->hwif->devices[0]; |
753 | 752 | ||
754 | if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0) | 753 | if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0) |
755 | return; | 754 | return; |
@@ -778,14 +777,15 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave); | |||
778 | 777 | ||
779 | static int ide_probe_port(ide_hwif_t *hwif) | 778 | static int ide_probe_port(ide_hwif_t *hwif) |
780 | { | 779 | { |
780 | ide_drive_t *drive; | ||
781 | unsigned long flags; | 781 | unsigned long flags; |
782 | unsigned int irqd; | 782 | unsigned int irqd; |
783 | int unit, rc = -ENODEV; | 783 | int i, rc = -ENODEV; |
784 | 784 | ||
785 | BUG_ON(hwif->present); | 785 | BUG_ON(hwif->present); |
786 | 786 | ||
787 | if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) && | 787 | if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) && |
788 | (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE)) | 788 | (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE)) |
789 | return -EACCES; | 789 | return -EACCES; |
790 | 790 | ||
791 | /* | 791 | /* |
@@ -796,7 +796,8 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
796 | if (irqd) | 796 | if (irqd) |
797 | disable_irq(hwif->irq); | 797 | disable_irq(hwif->irq); |
798 | 798 | ||
799 | local_irq_set(flags); | 799 | local_irq_save(flags); |
800 | local_irq_enable_in_hardirq(); | ||
800 | 801 | ||
801 | if (ide_port_wait_ready(hwif) == -EBUSY) | 802 | if (ide_port_wait_ready(hwif) == -EBUSY) |
802 | printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); | 803 | printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name); |
@@ -805,9 +806,7 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
805 | * Second drive should only exist if first drive was found, | 806 | * Second drive should only exist if first drive was found, |
806 | * but a lot of cdrom drives are configured as single slaves. | 807 | * but a lot of cdrom drives are configured as single slaves. |
807 | */ | 808 | */ |
808 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 809 | ide_port_for_each_dev(i, drive, hwif) { |
809 | ide_drive_t *drive = &hwif->drives[unit]; | ||
810 | |||
811 | (void) probe_for_drive(drive); | 810 | (void) probe_for_drive(drive); |
812 | if (drive->dev_flags & IDE_DFLAG_PRESENT) | 811 | if (drive->dev_flags & IDE_DFLAG_PRESENT) |
813 | rc = 0; | 812 | rc = 0; |
@@ -828,20 +827,17 @@ static int ide_probe_port(ide_hwif_t *hwif) | |||
828 | static void ide_port_tune_devices(ide_hwif_t *hwif) | 827 | static void ide_port_tune_devices(ide_hwif_t *hwif) |
829 | { | 828 | { |
830 | const struct ide_port_ops *port_ops = hwif->port_ops; | 829 | const struct ide_port_ops *port_ops = hwif->port_ops; |
831 | int unit; | 830 | ide_drive_t *drive; |
832 | 831 | int i; | |
833 | for (unit = 0; unit < MAX_DRIVES; unit++) { | ||
834 | ide_drive_t *drive = &hwif->drives[unit]; | ||
835 | 832 | ||
833 | ide_port_for_each_dev(i, drive, hwif) { | ||
836 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | 834 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { |
837 | if (port_ops && port_ops->quirkproc) | 835 | if (port_ops && port_ops->quirkproc) |
838 | port_ops->quirkproc(drive); | 836 | port_ops->quirkproc(drive); |
839 | } | 837 | } |
840 | } | 838 | } |
841 | 839 | ||
842 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 840 | ide_port_for_each_dev(i, drive, hwif) { |
843 | ide_drive_t *drive = &hwif->drives[unit]; | ||
844 | |||
845 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | 841 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { |
846 | ide_set_max_pio(drive); | 842 | ide_set_max_pio(drive); |
847 | 843 | ||
@@ -852,11 +848,8 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) | |||
852 | } | 848 | } |
853 | } | 849 | } |
854 | 850 | ||
855 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 851 | ide_port_for_each_dev(i, drive, hwif) { |
856 | ide_drive_t *drive = &hwif->drives[unit]; | 852 | if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) |
857 | |||
858 | if ((hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) || | ||
859 | drive->id[ATA_ID_DWORD_IO]) | ||
860 | drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; | 853 | drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT; |
861 | else | 854 | else |
862 | drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; | 855 | drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT; |
@@ -869,7 +862,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif) | |||
869 | static int ide_init_queue(ide_drive_t *drive) | 862 | static int ide_init_queue(ide_drive_t *drive) |
870 | { | 863 | { |
871 | struct request_queue *q; | 864 | struct request_queue *q; |
872 | ide_hwif_t *hwif = HWIF(drive); | 865 | ide_hwif_t *hwif = drive->hwif; |
873 | int max_sectors = 256; | 866 | int max_sectors = 256; |
874 | int max_sg_entries = PRD_ENTRIES; | 867 | int max_sg_entries = PRD_ENTRIES; |
875 | 868 | ||
@@ -918,36 +911,19 @@ static int ide_init_queue(ide_drive_t *drive) | |||
918 | return 0; | 911 | return 0; |
919 | } | 912 | } |
920 | 913 | ||
921 | static void ide_add_drive_to_hwgroup(ide_drive_t *drive) | 914 | static DEFINE_MUTEX(ide_cfg_mtx); |
922 | { | ||
923 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
924 | |||
925 | spin_lock_irq(&hwgroup->lock); | ||
926 | if (!hwgroup->drive) { | ||
927 | /* first drive for hwgroup. */ | ||
928 | drive->next = drive; | ||
929 | hwgroup->drive = drive; | ||
930 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
931 | } else { | ||
932 | drive->next = hwgroup->drive->next; | ||
933 | hwgroup->drive->next = drive; | ||
934 | } | ||
935 | spin_unlock_irq(&hwgroup->lock); | ||
936 | } | ||
937 | 915 | ||
938 | /* | 916 | /* |
939 | * For any present drive: | 917 | * For any present drive: |
940 | * - allocate the block device queue | 918 | * - allocate the block device queue |
941 | * - link drive into the hwgroup | ||
942 | */ | 919 | */ |
943 | static int ide_port_setup_devices(ide_hwif_t *hwif) | 920 | static int ide_port_setup_devices(ide_hwif_t *hwif) |
944 | { | 921 | { |
922 | ide_drive_t *drive; | ||
945 | int i, j = 0; | 923 | int i, j = 0; |
946 | 924 | ||
947 | mutex_lock(&ide_cfg_mtx); | 925 | mutex_lock(&ide_cfg_mtx); |
948 | for (i = 0; i < MAX_DRIVES; i++) { | 926 | ide_port_for_each_dev(i, drive, hwif) { |
949 | ide_drive_t *drive = &hwif->drives[i]; | ||
950 | |||
951 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 927 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
952 | continue; | 928 | continue; |
953 | 929 | ||
@@ -961,139 +937,39 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) | |||
961 | } | 937 | } |
962 | 938 | ||
963 | j++; | 939 | j++; |
964 | |||
965 | ide_add_drive_to_hwgroup(drive); | ||
966 | } | 940 | } |
967 | mutex_unlock(&ide_cfg_mtx); | 941 | mutex_unlock(&ide_cfg_mtx); |
968 | 942 | ||
969 | return j; | 943 | return j; |
970 | } | 944 | } |
971 | 945 | ||
972 | static ide_hwif_t *ide_ports[MAX_HWIFS]; | ||
973 | |||
974 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | ||
975 | { | ||
976 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
977 | |||
978 | ide_ports[hwif->index] = NULL; | ||
979 | |||
980 | spin_lock_irq(&hwgroup->lock); | ||
981 | /* | ||
982 | * Remove us from the hwgroup, and free | ||
983 | * the hwgroup if we were the only member | ||
984 | */ | ||
985 | if (hwif->next == hwif) { | ||
986 | BUG_ON(hwgroup->hwif != hwif); | ||
987 | kfree(hwgroup); | ||
988 | } else { | ||
989 | /* There is another interface in hwgroup. | ||
990 | * Unlink us, and set hwgroup->drive and ->hwif to | ||
991 | * something sane. | ||
992 | */ | ||
993 | ide_hwif_t *g = hwgroup->hwif; | ||
994 | |||
995 | while (g->next != hwif) | ||
996 | g = g->next; | ||
997 | g->next = hwif->next; | ||
998 | if (hwgroup->hwif == hwif) { | ||
999 | /* Chose a random hwif for hwgroup->hwif. | ||
1000 | * It's guaranteed that there are no drives | ||
1001 | * left in the hwgroup. | ||
1002 | */ | ||
1003 | BUG_ON(hwgroup->drive != NULL); | ||
1004 | hwgroup->hwif = g; | ||
1005 | } | ||
1006 | BUG_ON(hwgroup->hwif == hwif); | ||
1007 | } | ||
1008 | spin_unlock_irq(&hwgroup->lock); | ||
1009 | } | ||
1010 | |||
1011 | /* | 946 | /* |
1012 | * This routine sets up the irq for an ide interface, and creates a new | 947 | * This routine sets up the IRQ for an IDE interface. |
1013 | * hwgroup for the irq/hwif if none was previously assigned. | ||
1014 | * | ||
1015 | * Much of the code is for correctly detecting/handling irq sharing | ||
1016 | * and irq serialization situations. This is somewhat complex because | ||
1017 | * it handles static as well as dynamic (PCMCIA) IDE interfaces. | ||
1018 | */ | 948 | */ |
1019 | static int init_irq (ide_hwif_t *hwif) | 949 | static int init_irq (ide_hwif_t *hwif) |
1020 | { | 950 | { |
1021 | struct ide_io_ports *io_ports = &hwif->io_ports; | 951 | struct ide_io_ports *io_ports = &hwif->io_ports; |
1022 | unsigned int index; | 952 | int sa = 0; |
1023 | ide_hwgroup_t *hwgroup; | ||
1024 | ide_hwif_t *match = NULL; | ||
1025 | 953 | ||
1026 | mutex_lock(&ide_cfg_mtx); | 954 | mutex_lock(&ide_cfg_mtx); |
1027 | hwif->hwgroup = NULL; | 955 | spin_lock_init(&hwif->lock); |
1028 | 956 | ||
1029 | for (index = 0; index < MAX_HWIFS; index++) { | 957 | init_timer(&hwif->timer); |
1030 | ide_hwif_t *h = ide_ports[index]; | 958 | hwif->timer.function = &ide_timer_expiry; |
959 | hwif->timer.data = (unsigned long)hwif; | ||
1031 | 960 | ||
1032 | if (h && h->hwgroup) { /* scan only initialized ports */ | ||
1033 | if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) { | ||
1034 | if (hwif->host == h->host) | ||
1035 | match = h; | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | /* | ||
1041 | * If we are still without a hwgroup, then form a new one | ||
1042 | */ | ||
1043 | if (match) { | ||
1044 | hwgroup = match->hwgroup; | ||
1045 | hwif->hwgroup = hwgroup; | ||
1046 | /* | ||
1047 | * Link us into the hwgroup. | ||
1048 | * This must be done early, do ensure that unexpected_intr | ||
1049 | * can find the hwif and prevent irq storms. | ||
1050 | * No drives are attached to the new hwif, choose_drive | ||
1051 | * can't do anything stupid (yet). | ||
1052 | * Add ourself as the 2nd entry to the hwgroup->hwif | ||
1053 | * linked list, the first entry is the hwif that owns | ||
1054 | * hwgroup->handler - do not change that. | ||
1055 | */ | ||
1056 | spin_lock_irq(&hwgroup->lock); | ||
1057 | hwif->next = hwgroup->hwif->next; | ||
1058 | hwgroup->hwif->next = hwif; | ||
1059 | BUG_ON(hwif->next == hwif); | ||
1060 | spin_unlock_irq(&hwgroup->lock); | ||
1061 | } else { | ||
1062 | hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, | ||
1063 | hwif_to_node(hwif)); | ||
1064 | if (hwgroup == NULL) | ||
1065 | goto out_up; | ||
1066 | |||
1067 | spin_lock_init(&hwgroup->lock); | ||
1068 | |||
1069 | hwif->hwgroup = hwgroup; | ||
1070 | hwgroup->hwif = hwif->next = hwif; | ||
1071 | |||
1072 | init_timer(&hwgroup->timer); | ||
1073 | hwgroup->timer.function = &ide_timer_expiry; | ||
1074 | hwgroup->timer.data = (unsigned long) hwgroup; | ||
1075 | } | ||
1076 | |||
1077 | ide_ports[hwif->index] = hwif; | ||
1078 | |||
1079 | /* | ||
1080 | * Allocate the irq, if not already obtained for another hwif | ||
1081 | */ | ||
1082 | if (!match || match->irq != hwif->irq) { | ||
1083 | int sa = 0; | ||
1084 | #if defined(__mc68000__) | 961 | #if defined(__mc68000__) |
1085 | sa = IRQF_SHARED; | 962 | sa = IRQF_SHARED; |
1086 | #endif /* __mc68000__ */ | 963 | #endif /* __mc68000__ */ |
1087 | 964 | ||
1088 | if (hwif->chipset == ide_pci) | 965 | if (hwif->chipset == ide_pci) |
1089 | sa = IRQF_SHARED; | 966 | sa = IRQF_SHARED; |
1090 | 967 | ||
1091 | if (io_ports->ctl_addr) | 968 | if (io_ports->ctl_addr) |
1092 | hwif->tp_ops->set_irq(hwif, 1); | 969 | hwif->tp_ops->set_irq(hwif, 1); |
1093 | 970 | ||
1094 | if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) | 971 | if (request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwif)) |
1095 | goto out_unlink; | 972 | goto out_up; |
1096 | } | ||
1097 | 973 | ||
1098 | if (!hwif->rqsize) { | 974 | if (!hwif->rqsize) { |
1099 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || | 975 | if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || |
@@ -1111,14 +987,12 @@ static int init_irq (ide_hwif_t *hwif) | |||
1111 | printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name, | 987 | printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name, |
1112 | io_ports->data_addr, hwif->irq); | 988 | io_ports->data_addr, hwif->irq); |
1113 | #endif /* __mc68000__ */ | 989 | #endif /* __mc68000__ */ |
1114 | if (match) | 990 | if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) |
1115 | printk(KERN_CONT " (serialized with %s)", match->name); | 991 | printk(KERN_CONT " (serialized)"); |
1116 | printk(KERN_CONT "\n"); | 992 | printk(KERN_CONT "\n"); |
1117 | 993 | ||
1118 | mutex_unlock(&ide_cfg_mtx); | 994 | mutex_unlock(&ide_cfg_mtx); |
1119 | return 0; | 995 | return 0; |
1120 | out_unlink: | ||
1121 | ide_remove_port_from_hwgroup(hwif); | ||
1122 | out_up: | 996 | out_up: |
1123 | mutex_unlock(&ide_cfg_mtx); | 997 | mutex_unlock(&ide_cfg_mtx); |
1124 | return 1; | 998 | return 1; |
@@ -1134,7 +1008,7 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) | |||
1134 | { | 1008 | { |
1135 | ide_hwif_t *hwif = data; | 1009 | ide_hwif_t *hwif = data; |
1136 | int unit = *part >> PARTN_BITS; | 1010 | int unit = *part >> PARTN_BITS; |
1137 | ide_drive_t *drive = &hwif->drives[unit]; | 1011 | ide_drive_t *drive = hwif->devices[unit]; |
1138 | 1012 | ||
1139 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) | 1013 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0) |
1140 | return NULL; | 1014 | return NULL; |
@@ -1196,47 +1070,23 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) | |||
1196 | 1070 | ||
1197 | EXPORT_SYMBOL_GPL(ide_init_disk); | 1071 | EXPORT_SYMBOL_GPL(ide_init_disk); |
1198 | 1072 | ||
1199 | static void ide_remove_drive_from_hwgroup(ide_drive_t *drive) | ||
1200 | { | ||
1201 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
1202 | |||
1203 | if (drive == drive->next) { | ||
1204 | /* special case: last drive from hwgroup. */ | ||
1205 | BUG_ON(hwgroup->drive != drive); | ||
1206 | hwgroup->drive = NULL; | ||
1207 | } else { | ||
1208 | ide_drive_t *walk; | ||
1209 | |||
1210 | walk = hwgroup->drive; | ||
1211 | while (walk->next != drive) | ||
1212 | walk = walk->next; | ||
1213 | walk->next = drive->next; | ||
1214 | if (hwgroup->drive == drive) { | ||
1215 | hwgroup->drive = drive->next; | ||
1216 | hwgroup->hwif = hwgroup->drive->hwif; | ||
1217 | } | ||
1218 | } | ||
1219 | BUG_ON(hwgroup->drive == drive); | ||
1220 | } | ||
1221 | |||
1222 | static void drive_release_dev (struct device *dev) | 1073 | static void drive_release_dev (struct device *dev) |
1223 | { | 1074 | { |
1224 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); | 1075 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
1225 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | 1076 | ide_hwif_t *hwif = drive->hwif; |
1226 | 1077 | ||
1227 | ide_proc_unregister_device(drive); | 1078 | ide_proc_unregister_device(drive); |
1228 | 1079 | ||
1229 | spin_lock_irq(&hwgroup->lock); | 1080 | spin_lock_irq(&hwif->lock); |
1230 | ide_remove_drive_from_hwgroup(drive); | ||
1231 | kfree(drive->id); | 1081 | kfree(drive->id); |
1232 | drive->id = NULL; | 1082 | drive->id = NULL; |
1233 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; | 1083 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
1234 | /* Messed up locking ... */ | 1084 | /* Messed up locking ... */ |
1235 | spin_unlock_irq(&hwgroup->lock); | 1085 | spin_unlock_irq(&hwif->lock); |
1236 | blk_cleanup_queue(drive->queue); | 1086 | blk_cleanup_queue(drive->queue); |
1237 | spin_lock_irq(&hwgroup->lock); | 1087 | spin_lock_irq(&hwif->lock); |
1238 | drive->queue = NULL; | 1088 | drive->queue = NULL; |
1239 | spin_unlock_irq(&hwgroup->lock); | 1089 | spin_unlock_irq(&hwif->lock); |
1240 | 1090 | ||
1241 | complete(&drive->gendev_rel_comp); | 1091 | complete(&drive->gendev_rel_comp); |
1242 | } | 1092 | } |
@@ -1302,10 +1152,10 @@ out: | |||
1302 | 1152 | ||
1303 | static void hwif_register_devices(ide_hwif_t *hwif) | 1153 | static void hwif_register_devices(ide_hwif_t *hwif) |
1304 | { | 1154 | { |
1155 | ide_drive_t *drive; | ||
1305 | unsigned int i; | 1156 | unsigned int i; |
1306 | 1157 | ||
1307 | for (i = 0; i < MAX_DRIVES; i++) { | 1158 | ide_port_for_each_dev(i, drive, hwif) { |
1308 | ide_drive_t *drive = &hwif->drives[i]; | ||
1309 | struct device *dev = &drive->gendev; | 1159 | struct device *dev = &drive->gendev; |
1310 | int ret; | 1160 | int ret; |
1311 | 1161 | ||
@@ -1328,11 +1178,10 @@ static void hwif_register_devices(ide_hwif_t *hwif) | |||
1328 | static void ide_port_init_devices(ide_hwif_t *hwif) | 1178 | static void ide_port_init_devices(ide_hwif_t *hwif) |
1329 | { | 1179 | { |
1330 | const struct ide_port_ops *port_ops = hwif->port_ops; | 1180 | const struct ide_port_ops *port_ops = hwif->port_ops; |
1181 | ide_drive_t *drive; | ||
1331 | int i; | 1182 | int i; |
1332 | 1183 | ||
1333 | for (i = 0; i < MAX_DRIVES; i++) { | 1184 | ide_port_for_each_dev(i, drive, hwif) { |
1334 | ide_drive_t *drive = &hwif->drives[i]; | ||
1335 | |||
1336 | drive->dn = i + hwif->channel * 2; | 1185 | drive->dn = i + hwif->channel * 2; |
1337 | 1186 | ||
1338 | if (hwif->host_flags & IDE_HFLAG_IO_32BIT) | 1187 | if (hwif->host_flags & IDE_HFLAG_IO_32BIT) |
@@ -1380,6 +1229,8 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1380 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { | 1229 | if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { |
1381 | int rc; | 1230 | int rc; |
1382 | 1231 | ||
1232 | hwif->dma_ops = d->dma_ops; | ||
1233 | |||
1383 | if (d->init_dma) | 1234 | if (d->init_dma) |
1384 | rc = d->init_dma(hwif, d); | 1235 | rc = d->init_dma(hwif, d); |
1385 | else | 1236 | else |
@@ -1387,12 +1238,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1387 | 1238 | ||
1388 | if (rc < 0) { | 1239 | if (rc < 0) { |
1389 | printk(KERN_INFO "%s: DMA disabled\n", hwif->name); | 1240 | printk(KERN_INFO "%s: DMA disabled\n", hwif->name); |
1241 | |||
1242 | hwif->dma_ops = NULL; | ||
1390 | hwif->dma_base = 0; | 1243 | hwif->dma_base = 0; |
1391 | hwif->swdma_mask = 0; | 1244 | hwif->swdma_mask = 0; |
1392 | hwif->mwdma_mask = 0; | 1245 | hwif->mwdma_mask = 0; |
1393 | hwif->ultra_mask = 0; | 1246 | hwif->ultra_mask = 0; |
1394 | } else if (d->dma_ops) | 1247 | } |
1395 | hwif->dma_ops = d->dma_ops; | ||
1396 | } | 1248 | } |
1397 | 1249 | ||
1398 | if ((d->host_flags & IDE_HFLAG_SERIALIZE) || | 1250 | if ((d->host_flags & IDE_HFLAG_SERIALIZE) || |
@@ -1417,6 +1269,66 @@ static void ide_port_cable_detect(ide_hwif_t *hwif) | |||
1417 | } | 1269 | } |
1418 | } | 1270 | } |
1419 | 1271 | ||
1272 | static const u8 ide_hwif_to_major[] = | ||
1273 | { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR, | ||
1274 | IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR }; | ||
1275 | |||
1276 | static void ide_port_init_devices_data(ide_hwif_t *hwif) | ||
1277 | { | ||
1278 | ide_drive_t *drive; | ||
1279 | int i; | ||
1280 | |||
1281 | ide_port_for_each_dev(i, drive, hwif) { | ||
1282 | u8 j = (hwif->index * MAX_DRIVES) + i; | ||
1283 | |||
1284 | memset(drive, 0, sizeof(*drive)); | ||
1285 | |||
1286 | drive->media = ide_disk; | ||
1287 | drive->select = (i << 4) | ATA_DEVICE_OBS; | ||
1288 | drive->hwif = hwif; | ||
1289 | drive->ready_stat = ATA_DRDY; | ||
1290 | drive->bad_wstat = BAD_W_STAT; | ||
1291 | drive->special.b.recalibrate = 1; | ||
1292 | drive->special.b.set_geometry = 1; | ||
1293 | drive->name[0] = 'h'; | ||
1294 | drive->name[1] = 'd'; | ||
1295 | drive->name[2] = 'a' + j; | ||
1296 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | ||
1297 | |||
1298 | INIT_LIST_HEAD(&drive->list); | ||
1299 | init_completion(&drive->gendev_rel_comp); | ||
1300 | } | ||
1301 | } | ||
1302 | |||
1303 | static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | ||
1304 | { | ||
1305 | /* fill in any non-zero initial values */ | ||
1306 | hwif->index = index; | ||
1307 | hwif->major = ide_hwif_to_major[index]; | ||
1308 | |||
1309 | hwif->name[0] = 'i'; | ||
1310 | hwif->name[1] = 'd'; | ||
1311 | hwif->name[2] = 'e'; | ||
1312 | hwif->name[3] = '0' + index; | ||
1313 | |||
1314 | init_completion(&hwif->gendev_rel_comp); | ||
1315 | |||
1316 | hwif->tp_ops = &default_tp_ops; | ||
1317 | |||
1318 | ide_port_init_devices_data(hwif); | ||
1319 | } | ||
1320 | |||
1321 | static void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | ||
1322 | { | ||
1323 | memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); | ||
1324 | hwif->irq = hw->irq; | ||
1325 | hwif->chipset = hw->chipset; | ||
1326 | hwif->dev = hw->dev; | ||
1327 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; | ||
1328 | hwif->ack_intr = hw->ack_intr; | ||
1329 | hwif->config_data = hw->config; | ||
1330 | } | ||
1331 | |||
1420 | static unsigned int ide_indexes; | 1332 | static unsigned int ide_indexes; |
1421 | 1333 | ||
1422 | /** | 1334 | /** |
@@ -1466,12 +1378,43 @@ static void ide_free_port_slot(int idx) | |||
1466 | mutex_unlock(&ide_cfg_mtx); | 1378 | mutex_unlock(&ide_cfg_mtx); |
1467 | } | 1379 | } |
1468 | 1380 | ||
1381 | static void ide_port_free_devices(ide_hwif_t *hwif) | ||
1382 | { | ||
1383 | ide_drive_t *drive; | ||
1384 | int i; | ||
1385 | |||
1386 | ide_port_for_each_dev(i, drive, hwif) | ||
1387 | kfree(drive); | ||
1388 | } | ||
1389 | |||
1390 | static int ide_port_alloc_devices(ide_hwif_t *hwif, int node) | ||
1391 | { | ||
1392 | int i; | ||
1393 | |||
1394 | for (i = 0; i < MAX_DRIVES; i++) { | ||
1395 | ide_drive_t *drive; | ||
1396 | |||
1397 | drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node); | ||
1398 | if (drive == NULL) | ||
1399 | goto out_nomem; | ||
1400 | |||
1401 | hwif->devices[i] = drive; | ||
1402 | } | ||
1403 | return 0; | ||
1404 | |||
1405 | out_nomem: | ||
1406 | ide_port_free_devices(hwif); | ||
1407 | return -ENOMEM; | ||
1408 | } | ||
1409 | |||
1469 | struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) | 1410 | struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) |
1470 | { | 1411 | { |
1471 | struct ide_host *host; | 1412 | struct ide_host *host; |
1413 | struct device *dev = hws[0] ? hws[0]->dev : NULL; | ||
1414 | int node = dev ? dev_to_node(dev) : -1; | ||
1472 | int i; | 1415 | int i; |
1473 | 1416 | ||
1474 | host = kzalloc(sizeof(*host), GFP_KERNEL); | 1417 | host = kzalloc_node(sizeof(*host), GFP_KERNEL, node); |
1475 | if (host == NULL) | 1418 | if (host == NULL) |
1476 | return NULL; | 1419 | return NULL; |
1477 | 1420 | ||
@@ -1482,10 +1425,15 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) | |||
1482 | if (hws[i] == NULL) | 1425 | if (hws[i] == NULL) |
1483 | continue; | 1426 | continue; |
1484 | 1427 | ||
1485 | hwif = kzalloc(sizeof(*hwif), GFP_KERNEL); | 1428 | hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node); |
1486 | if (hwif == NULL) | 1429 | if (hwif == NULL) |
1487 | continue; | 1430 | continue; |
1488 | 1431 | ||
1432 | if (ide_port_alloc_devices(hwif, node) < 0) { | ||
1433 | kfree(hwif); | ||
1434 | continue; | ||
1435 | } | ||
1436 | |||
1489 | idx = ide_find_port_slot(d); | 1437 | idx = ide_find_port_slot(d); |
1490 | if (idx < 0) { | 1438 | if (idx < 0) { |
1491 | printk(KERN_ERR "%s: no free slot for interface\n", | 1439 | printk(KERN_ERR "%s: no free slot for interface\n", |
@@ -1507,8 +1455,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) | |||
1507 | return NULL; | 1455 | return NULL; |
1508 | } | 1456 | } |
1509 | 1457 | ||
1510 | if (hws[0]) | 1458 | host->dev[0] = dev; |
1511 | host->dev[0] = hws[0]->dev; | ||
1512 | 1459 | ||
1513 | if (d) { | 1460 | if (d) { |
1514 | host->init_chipset = d->init_chipset; | 1461 | host->init_chipset = d->init_chipset; |
@@ -1525,9 +1472,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1525 | ide_hwif_t *hwif, *mate = NULL; | 1472 | ide_hwif_t *hwif, *mate = NULL; |
1526 | int i, j = 0; | 1473 | int i, j = 0; |
1527 | 1474 | ||
1528 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1475 | ide_host_for_each_port(i, hwif, host) { |
1529 | hwif = host->ports[i]; | ||
1530 | |||
1531 | if (hwif == NULL) { | 1476 | if (hwif == NULL) { |
1532 | mate = NULL; | 1477 | mate = NULL; |
1533 | continue; | 1478 | continue; |
@@ -1553,9 +1498,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1553 | ide_port_init_devices(hwif); | 1498 | ide_port_init_devices(hwif); |
1554 | } | 1499 | } |
1555 | 1500 | ||
1556 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1501 | ide_host_for_each_port(i, hwif, host) { |
1557 | hwif = host->ports[i]; | ||
1558 | |||
1559 | if (hwif == NULL) | 1502 | if (hwif == NULL) |
1560 | continue; | 1503 | continue; |
1561 | 1504 | ||
@@ -1570,9 +1513,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1570 | ide_port_tune_devices(hwif); | 1513 | ide_port_tune_devices(hwif); |
1571 | } | 1514 | } |
1572 | 1515 | ||
1573 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1516 | ide_host_for_each_port(i, hwif, host) { |
1574 | hwif = host->ports[i]; | ||
1575 | |||
1576 | if (hwif == NULL) | 1517 | if (hwif == NULL) |
1577 | continue; | 1518 | continue; |
1578 | 1519 | ||
@@ -1597,9 +1538,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1597 | ide_acpi_port_init_devices(hwif); | 1538 | ide_acpi_port_init_devices(hwif); |
1598 | } | 1539 | } |
1599 | 1540 | ||
1600 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1541 | ide_host_for_each_port(i, hwif, host) { |
1601 | hwif = host->ports[i]; | ||
1602 | |||
1603 | if (hwif == NULL) | 1542 | if (hwif == NULL) |
1604 | continue; | 1543 | continue; |
1605 | 1544 | ||
@@ -1607,9 +1546,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1607 | hwif_register_devices(hwif); | 1546 | hwif_register_devices(hwif); |
1608 | } | 1547 | } |
1609 | 1548 | ||
1610 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1549 | ide_host_for_each_port(i, hwif, host) { |
1611 | hwif = host->ports[i]; | ||
1612 | |||
1613 | if (hwif == NULL) | 1550 | if (hwif == NULL) |
1614 | continue; | 1551 | continue; |
1615 | 1552 | ||
@@ -1647,17 +1584,85 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws, | |||
1647 | } | 1584 | } |
1648 | EXPORT_SYMBOL_GPL(ide_host_add); | 1585 | EXPORT_SYMBOL_GPL(ide_host_add); |
1649 | 1586 | ||
1587 | static void __ide_port_unregister_devices(ide_hwif_t *hwif) | ||
1588 | { | ||
1589 | ide_drive_t *drive; | ||
1590 | int i; | ||
1591 | |||
1592 | ide_port_for_each_dev(i, drive, hwif) { | ||
1593 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | ||
1594 | device_unregister(&drive->gendev); | ||
1595 | wait_for_completion(&drive->gendev_rel_comp); | ||
1596 | } | ||
1597 | } | ||
1598 | } | ||
1599 | |||
1600 | void ide_port_unregister_devices(ide_hwif_t *hwif) | ||
1601 | { | ||
1602 | mutex_lock(&ide_cfg_mtx); | ||
1603 | __ide_port_unregister_devices(hwif); | ||
1604 | hwif->present = 0; | ||
1605 | ide_port_init_devices_data(hwif); | ||
1606 | mutex_unlock(&ide_cfg_mtx); | ||
1607 | } | ||
1608 | EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | ||
1609 | |||
1610 | /** | ||
1611 | * ide_unregister - free an IDE interface | ||
1612 | * @hwif: IDE interface | ||
1613 | * | ||
1614 | * Perform the final unregister of an IDE interface. | ||
1615 | * | ||
1616 | * Locking: | ||
1617 | * The caller must not hold the IDE locks. | ||
1618 | * | ||
1619 | * It is up to the caller to be sure there is no pending I/O here, | ||
1620 | * and that the interface will not be reopened (present/vanishing | ||
1621 | * locking isn't yet done BTW). | ||
1622 | */ | ||
1623 | |||
1624 | static void ide_unregister(ide_hwif_t *hwif) | ||
1625 | { | ||
1626 | BUG_ON(in_interrupt()); | ||
1627 | BUG_ON(irqs_disabled()); | ||
1628 | |||
1629 | mutex_lock(&ide_cfg_mtx); | ||
1630 | |||
1631 | if (hwif->present) { | ||
1632 | __ide_port_unregister_devices(hwif); | ||
1633 | hwif->present = 0; | ||
1634 | } | ||
1635 | |||
1636 | ide_proc_unregister_port(hwif); | ||
1637 | |||
1638 | free_irq(hwif->irq, hwif); | ||
1639 | |||
1640 | device_unregister(hwif->portdev); | ||
1641 | device_unregister(&hwif->gendev); | ||
1642 | wait_for_completion(&hwif->gendev_rel_comp); | ||
1643 | |||
1644 | /* | ||
1645 | * Remove us from the kernel's knowledge | ||
1646 | */ | ||
1647 | blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); | ||
1648 | kfree(hwif->sg_table); | ||
1649 | unregister_blkdev(hwif->major, hwif->name); | ||
1650 | |||
1651 | ide_release_dma_engine(hwif); | ||
1652 | |||
1653 | mutex_unlock(&ide_cfg_mtx); | ||
1654 | } | ||
1655 | |||
1650 | void ide_host_free(struct ide_host *host) | 1656 | void ide_host_free(struct ide_host *host) |
1651 | { | 1657 | { |
1652 | ide_hwif_t *hwif; | 1658 | ide_hwif_t *hwif; |
1653 | int i; | 1659 | int i; |
1654 | 1660 | ||
1655 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1661 | ide_host_for_each_port(i, hwif, host) { |
1656 | hwif = host->ports[i]; | ||
1657 | |||
1658 | if (hwif == NULL) | 1662 | if (hwif == NULL) |
1659 | continue; | 1663 | continue; |
1660 | 1664 | ||
1665 | ide_port_free_devices(hwif); | ||
1661 | ide_free_port_slot(hwif->index); | 1666 | ide_free_port_slot(hwif->index); |
1662 | kfree(hwif); | 1667 | kfree(hwif); |
1663 | } | 1668 | } |
@@ -1668,11 +1673,12 @@ EXPORT_SYMBOL_GPL(ide_host_free); | |||
1668 | 1673 | ||
1669 | void ide_host_remove(struct ide_host *host) | 1674 | void ide_host_remove(struct ide_host *host) |
1670 | { | 1675 | { |
1676 | ide_hwif_t *hwif; | ||
1671 | int i; | 1677 | int i; |
1672 | 1678 | ||
1673 | for (i = 0; i < MAX_HOST_PORTS; i++) { | 1679 | ide_host_for_each_port(i, hwif, host) { |
1674 | if (host->ports[i]) | 1680 | if (hwif) |
1675 | ide_unregister(host->ports[i]); | 1681 | ide_unregister(hwif); |
1676 | } | 1682 | } |
1677 | 1683 | ||
1678 | ide_host_free(host); | 1684 | ide_host_free(host); |
@@ -1691,8 +1697,8 @@ void ide_port_scan(ide_hwif_t *hwif) | |||
1691 | hwif->present = 1; | 1697 | hwif->present = 1; |
1692 | 1698 | ||
1693 | ide_port_tune_devices(hwif); | 1699 | ide_port_tune_devices(hwif); |
1694 | ide_acpi_port_init_devices(hwif); | ||
1695 | ide_port_setup_devices(hwif); | 1700 | ide_port_setup_devices(hwif); |
1701 | ide_acpi_port_init_devices(hwif); | ||
1696 | hwif_register_devices(hwif); | 1702 | hwif_register_devices(hwif); |
1697 | ide_proc_port_register_devices(hwif); | 1703 | ide_proc_port_register_devices(hwif); |
1698 | } | 1704 | } |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index a14e2938e4f3..1d8978b3314a 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -439,13 +439,13 @@ static int proc_ide_read_dmodel | |||
439 | static int proc_ide_read_driver | 439 | static int proc_ide_read_driver |
440 | (char *page, char **start, off_t off, int count, int *eof, void *data) | 440 | (char *page, char **start, off_t off, int count, int *eof, void *data) |
441 | { | 441 | { |
442 | ide_drive_t *drive = (ide_drive_t *) data; | 442 | ide_drive_t *drive = (ide_drive_t *)data; |
443 | struct device *dev = &drive->gendev; | 443 | struct device *dev = &drive->gendev; |
444 | ide_driver_t *ide_drv; | 444 | struct ide_driver *ide_drv; |
445 | int len; | 445 | int len; |
446 | 446 | ||
447 | if (dev->driver) { | 447 | if (dev->driver) { |
448 | ide_drv = container_of(dev->driver, ide_driver_t, gen_driver); | 448 | ide_drv = to_ide_driver(dev->driver); |
449 | len = sprintf(page, "%s version %s\n", | 449 | len = sprintf(page, "%s version %s\n", |
450 | dev->driver->name, ide_drv->version); | 450 | dev->driver->name, ide_drv->version); |
451 | } else | 451 | } else |
@@ -555,7 +555,7 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t | |||
555 | } | 555 | } |
556 | } | 556 | } |
557 | 557 | ||
558 | void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) | 558 | void ide_proc_register_driver(ide_drive_t *drive, struct ide_driver *driver) |
559 | { | 559 | { |
560 | mutex_lock(&ide_setting_mtx); | 560 | mutex_lock(&ide_setting_mtx); |
561 | drive->settings = driver->proc_devsets(drive); | 561 | drive->settings = driver->proc_devsets(drive); |
@@ -577,7 +577,7 @@ EXPORT_SYMBOL(ide_proc_register_driver); | |||
577 | * Takes ide_setting_mtx. | 577 | * Takes ide_setting_mtx. |
578 | */ | 578 | */ |
579 | 579 | ||
580 | void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) | 580 | void ide_proc_unregister_driver(ide_drive_t *drive, struct ide_driver *driver) |
581 | { | 581 | { |
582 | ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); | 582 | ide_remove_proc_entries(drive->proc, driver->proc_entries(drive)); |
583 | 583 | ||
@@ -593,14 +593,13 @@ EXPORT_SYMBOL(ide_proc_unregister_driver); | |||
593 | 593 | ||
594 | void ide_proc_port_register_devices(ide_hwif_t *hwif) | 594 | void ide_proc_port_register_devices(ide_hwif_t *hwif) |
595 | { | 595 | { |
596 | int d; | ||
597 | struct proc_dir_entry *ent; | 596 | struct proc_dir_entry *ent; |
598 | struct proc_dir_entry *parent = hwif->proc; | 597 | struct proc_dir_entry *parent = hwif->proc; |
598 | ide_drive_t *drive; | ||
599 | char name[64]; | 599 | char name[64]; |
600 | int i; | ||
600 | 601 | ||
601 | for (d = 0; d < MAX_DRIVES; d++) { | 602 | ide_port_for_each_dev(i, drive, hwif) { |
602 | ide_drive_t *drive = &hwif->drives[d]; | ||
603 | |||
604 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc) | 603 | if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc) |
605 | continue; | 604 | continue; |
606 | 605 | ||
@@ -653,7 +652,7 @@ void ide_proc_unregister_port(ide_hwif_t *hwif) | |||
653 | 652 | ||
654 | static int proc_print_driver(struct device_driver *drv, void *data) | 653 | static int proc_print_driver(struct device_driver *drv, void *data) |
655 | { | 654 | { |
656 | ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver); | 655 | struct ide_driver *ide_drv = to_ide_driver(drv); |
657 | struct seq_file *s = data; | 656 | struct seq_file *s = data; |
658 | 657 | ||
659 | seq_printf(s, "%s version %s\n", drv->name, ide_drv->version); | 658 | seq_printf(s, "%s version %s\n", drv->name, ide_drv->version); |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 5d2aa22cd6e4..d7ecd3c79757 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -166,10 +166,10 @@ struct idetape_bh { | |||
166 | * to an interrupt or a timer event is stored in the struct defined below. | 166 | * to an interrupt or a timer event is stored in the struct defined below. |
167 | */ | 167 | */ |
168 | typedef struct ide_tape_obj { | 168 | typedef struct ide_tape_obj { |
169 | ide_drive_t *drive; | 169 | ide_drive_t *drive; |
170 | ide_driver_t *driver; | 170 | struct ide_driver *driver; |
171 | struct gendisk *disk; | 171 | struct gendisk *disk; |
172 | struct kref kref; | 172 | struct kref kref; |
173 | 173 | ||
174 | /* | 174 | /* |
175 | * failed_pc points to the last failed packet command, or contains | 175 | * failed_pc points to the last failed packet command, or contains |
@@ -479,7 +479,7 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape) | |||
479 | 479 | ||
480 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | 480 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) |
481 | { | 481 | { |
482 | struct request *rq = HWGROUP(drive)->rq; | 482 | struct request *rq = drive->hwif->rq; |
483 | idetape_tape_t *tape = drive->driver_data; | 483 | idetape_tape_t *tape = drive->driver_data; |
484 | unsigned long flags; | 484 | unsigned long flags; |
485 | int error; | 485 | int error; |
@@ -531,7 +531,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc) | |||
531 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " | 531 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " |
532 | "itself - Aborting request!\n"); | 532 | "itself - Aborting request!\n"); |
533 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { | 533 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { |
534 | struct request *rq = drive->hwif->hwgroup->rq; | 534 | struct request *rq = drive->hwif->rq; |
535 | int blocks = pc->xferred / tape->blk_size; | 535 | int blocks = pc->xferred / tape->blk_size; |
536 | 536 | ||
537 | tape->avg_size += blocks * tape->blk_size; | 537 | tape->avg_size += blocks * tape->blk_size; |
@@ -576,7 +576,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc) | |||
576 | 576 | ||
577 | /* | 577 | /* |
578 | * Postpone the current request so that ide.c will be able to service requests | 578 | * Postpone the current request so that ide.c will be able to service requests |
579 | * from another device on the same hwgroup while we are polling for DSC. | 579 | * from another device on the same port while we are polling for DSC. |
580 | */ | 580 | */ |
581 | static void idetape_postpone_request(ide_drive_t *drive) | 581 | static void idetape_postpone_request(ide_drive_t *drive) |
582 | { | 582 | { |
@@ -584,7 +584,8 @@ static void idetape_postpone_request(ide_drive_t *drive) | |||
584 | 584 | ||
585 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 585 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
586 | 586 | ||
587 | tape->postponed_rq = HWGROUP(drive)->rq; | 587 | tape->postponed_rq = drive->hwif->rq; |
588 | |||
588 | ide_stall_queue(drive, tape->dsc_poll_freq); | 589 | ide_stall_queue(drive, tape->dsc_poll_freq); |
589 | } | 590 | } |
590 | 591 | ||
@@ -2312,7 +2313,7 @@ static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive) | |||
2312 | 2313 | ||
2313 | static int ide_tape_probe(ide_drive_t *); | 2314 | static int ide_tape_probe(ide_drive_t *); |
2314 | 2315 | ||
2315 | static ide_driver_t idetape_driver = { | 2316 | static struct ide_driver idetape_driver = { |
2316 | .gen_driver = { | 2317 | .gen_driver = { |
2317 | .owner = THIS_MODULE, | 2318 | .owner = THIS_MODULE, |
2318 | .name = "ide-tape", | 2319 | .name = "ide-tape", |
@@ -2323,7 +2324,6 @@ static ide_driver_t idetape_driver = { | |||
2323 | .version = IDETAPE_VERSION, | 2324 | .version = IDETAPE_VERSION, |
2324 | .do_request = idetape_do_request, | 2325 | .do_request = idetape_do_request, |
2325 | .end_request = idetape_end_request, | 2326 | .end_request = idetape_end_request, |
2326 | .error = __ide_error, | ||
2327 | #ifdef CONFIG_IDE_PROC_FS | 2327 | #ifdef CONFIG_IDE_PROC_FS |
2328 | .proc_entries = ide_tape_proc_entries, | 2328 | .proc_entries = ide_tape_proc_entries, |
2329 | .proc_devsets = ide_tape_proc_devsets, | 2329 | .proc_devsets = ide_tape_proc_devsets, |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index bf4fb9d8d176..16138bce84a7 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -58,7 +58,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *); | |||
58 | 58 | ||
59 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | 59 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) |
60 | { | 60 | { |
61 | ide_hwif_t *hwif = HWIF(drive); | 61 | ide_hwif_t *hwif = drive->hwif; |
62 | struct ide_taskfile *tf = &task->tf; | 62 | struct ide_taskfile *tf = &task->tf; |
63 | ide_handler_t *handler = NULL; | 63 | ide_handler_t *handler = NULL; |
64 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 64 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
@@ -309,9 +309,9 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | |||
309 | } | 309 | } |
310 | 310 | ||
311 | if (sectors > 0) { | 311 | if (sectors > 0) { |
312 | ide_driver_t *drv; | 312 | struct ide_driver *drv; |
313 | 313 | ||
314 | drv = *(ide_driver_t **)rq->rq_disk->private_data; | 314 | drv = *(struct ide_driver **)rq->rq_disk->private_data; |
315 | drv->end_request(drive, 1, sectors); | 315 | drv->end_request(drive, 1, sectors); |
316 | } | 316 | } |
317 | } | 317 | } |
@@ -328,9 +328,9 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | if (rq->rq_disk) { | 330 | if (rq->rq_disk) { |
331 | ide_driver_t *drv; | 331 | struct ide_driver *drv; |
332 | 332 | ||
333 | drv = *(ide_driver_t **)rq->rq_disk->private_data;; | 333 | drv = *(struct ide_driver **)rq->rq_disk->private_data;; |
334 | drv->end_request(drive, 1, rq->nr_sectors); | 334 | drv->end_request(drive, 1, rq->nr_sectors); |
335 | } else | 335 | } else |
336 | ide_end_request(drive, 1, rq->nr_sectors); | 336 | ide_end_request(drive, 1, rq->nr_sectors); |
@@ -361,7 +361,7 @@ static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq | |||
361 | static ide_startstop_t task_in_intr(ide_drive_t *drive) | 361 | static ide_startstop_t task_in_intr(ide_drive_t *drive) |
362 | { | 362 | { |
363 | ide_hwif_t *hwif = drive->hwif; | 363 | ide_hwif_t *hwif = drive->hwif; |
364 | struct request *rq = hwif->hwgroup->rq; | 364 | struct request *rq = hwif->rq; |
365 | u8 stat = hwif->tp_ops->read_status(hwif); | 365 | u8 stat = hwif->tp_ops->read_status(hwif); |
366 | 366 | ||
367 | /* Error? */ | 367 | /* Error? */ |
@@ -395,7 +395,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) | |||
395 | static ide_startstop_t task_out_intr (ide_drive_t *drive) | 395 | static ide_startstop_t task_out_intr (ide_drive_t *drive) |
396 | { | 396 | { |
397 | ide_hwif_t *hwif = drive->hwif; | 397 | ide_hwif_t *hwif = drive->hwif; |
398 | struct request *rq = HWGROUP(drive)->rq; | 398 | struct request *rq = hwif->rq; |
399 | u8 stat = hwif->tp_ops->read_status(hwif); | 399 | u8 stat = hwif->tp_ops->read_status(hwif); |
400 | 400 | ||
401 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) | 401 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 46a2d4ca812b..258805da15c3 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -60,179 +60,8 @@ | |||
60 | #include <linux/completion.h> | 60 | #include <linux/completion.h> |
61 | #include <linux/device.h> | 61 | #include <linux/device.h> |
62 | 62 | ||
63 | |||
64 | /* default maximum number of failures */ | ||
65 | #define IDE_DEFAULT_MAX_FAILURES 1 | ||
66 | |||
67 | struct class *ide_port_class; | 63 | struct class *ide_port_class; |
68 | 64 | ||
69 | static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, | ||
70 | IDE2_MAJOR, IDE3_MAJOR, | ||
71 | IDE4_MAJOR, IDE5_MAJOR, | ||
72 | IDE6_MAJOR, IDE7_MAJOR, | ||
73 | IDE8_MAJOR, IDE9_MAJOR }; | ||
74 | |||
75 | DEFINE_MUTEX(ide_cfg_mtx); | ||
76 | |||
77 | static void ide_port_init_devices_data(ide_hwif_t *); | ||
78 | |||
79 | /* | ||
80 | * Do not even *think* about calling this! | ||
81 | */ | ||
82 | void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | ||
83 | { | ||
84 | /* bulk initialize hwif & drive info with zeros */ | ||
85 | memset(hwif, 0, sizeof(ide_hwif_t)); | ||
86 | |||
87 | /* fill in any non-zero initial values */ | ||
88 | hwif->index = index; | ||
89 | hwif->major = ide_hwif_to_major[index]; | ||
90 | |||
91 | hwif->name[0] = 'i'; | ||
92 | hwif->name[1] = 'd'; | ||
93 | hwif->name[2] = 'e'; | ||
94 | hwif->name[3] = '0' + index; | ||
95 | |||
96 | init_completion(&hwif->gendev_rel_comp); | ||
97 | |||
98 | hwif->tp_ops = &default_tp_ops; | ||
99 | |||
100 | ide_port_init_devices_data(hwif); | ||
101 | } | ||
102 | |||
103 | static void ide_port_init_devices_data(ide_hwif_t *hwif) | ||
104 | { | ||
105 | int unit; | ||
106 | |||
107 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | ||
108 | ide_drive_t *drive = &hwif->drives[unit]; | ||
109 | u8 j = (hwif->index * MAX_DRIVES) + unit; | ||
110 | |||
111 | memset(drive, 0, sizeof(*drive)); | ||
112 | |||
113 | drive->media = ide_disk; | ||
114 | drive->select = (unit << 4) | ATA_DEVICE_OBS; | ||
115 | drive->hwif = hwif; | ||
116 | drive->ready_stat = ATA_DRDY; | ||
117 | drive->bad_wstat = BAD_W_STAT; | ||
118 | drive->special.b.recalibrate = 1; | ||
119 | drive->special.b.set_geometry = 1; | ||
120 | drive->name[0] = 'h'; | ||
121 | drive->name[1] = 'd'; | ||
122 | drive->name[2] = 'a' + j; | ||
123 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | ||
124 | |||
125 | INIT_LIST_HEAD(&drive->list); | ||
126 | init_completion(&drive->gendev_rel_comp); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | static void __ide_port_unregister_devices(ide_hwif_t *hwif) | ||
131 | { | ||
132 | int i; | ||
133 | |||
134 | for (i = 0; i < MAX_DRIVES; i++) { | ||
135 | ide_drive_t *drive = &hwif->drives[i]; | ||
136 | |||
137 | if (drive->dev_flags & IDE_DFLAG_PRESENT) { | ||
138 | device_unregister(&drive->gendev); | ||
139 | wait_for_completion(&drive->gendev_rel_comp); | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | void ide_port_unregister_devices(ide_hwif_t *hwif) | ||
145 | { | ||
146 | mutex_lock(&ide_cfg_mtx); | ||
147 | __ide_port_unregister_devices(hwif); | ||
148 | hwif->present = 0; | ||
149 | ide_port_init_devices_data(hwif); | ||
150 | mutex_unlock(&ide_cfg_mtx); | ||
151 | } | ||
152 | EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | ||
153 | |||
154 | /** | ||
155 | * ide_unregister - free an IDE interface | ||
156 | * @hwif: IDE interface | ||
157 | * | ||
158 | * Perform the final unregister of an IDE interface. At the moment | ||
159 | * we don't refcount interfaces so this will also get split up. | ||
160 | * | ||
161 | * Locking: | ||
162 | * The caller must not hold the IDE locks | ||
163 | * The drive present/vanishing is not yet properly locked | ||
164 | * Take care with the callbacks. These have been split to avoid | ||
165 | * deadlocking the IDE layer. The shutdown callback is called | ||
166 | * before we take the lock and free resources. It is up to the | ||
167 | * caller to be sure there is no pending I/O here, and that | ||
168 | * the interface will not be reopened (present/vanishing locking | ||
169 | * isn't yet done BTW). After we commit to the final kill we | ||
170 | * call the cleanup callback with the ide locks held. | ||
171 | * | ||
172 | * Unregister restores the hwif structures to the default state. | ||
173 | * This is raving bonkers. | ||
174 | */ | ||
175 | |||
176 | void ide_unregister(ide_hwif_t *hwif) | ||
177 | { | ||
178 | ide_hwif_t *g; | ||
179 | ide_hwgroup_t *hwgroup; | ||
180 | int irq_count = 0; | ||
181 | |||
182 | BUG_ON(in_interrupt()); | ||
183 | BUG_ON(irqs_disabled()); | ||
184 | |||
185 | mutex_lock(&ide_cfg_mtx); | ||
186 | |||
187 | if (hwif->present) { | ||
188 | __ide_port_unregister_devices(hwif); | ||
189 | hwif->present = 0; | ||
190 | } | ||
191 | |||
192 | ide_proc_unregister_port(hwif); | ||
193 | |||
194 | hwgroup = hwif->hwgroup; | ||
195 | /* | ||
196 | * free the irq if we were the only hwif using it | ||
197 | */ | ||
198 | g = hwgroup->hwif; | ||
199 | do { | ||
200 | if (g->irq == hwif->irq) | ||
201 | ++irq_count; | ||
202 | g = g->next; | ||
203 | } while (g != hwgroup->hwif); | ||
204 | if (irq_count == 1) | ||
205 | free_irq(hwif->irq, hwgroup); | ||
206 | |||
207 | ide_remove_port_from_hwgroup(hwif); | ||
208 | |||
209 | device_unregister(hwif->portdev); | ||
210 | device_unregister(&hwif->gendev); | ||
211 | wait_for_completion(&hwif->gendev_rel_comp); | ||
212 | |||
213 | /* | ||
214 | * Remove us from the kernel's knowledge | ||
215 | */ | ||
216 | blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); | ||
217 | kfree(hwif->sg_table); | ||
218 | unregister_blkdev(hwif->major, hwif->name); | ||
219 | |||
220 | ide_release_dma_engine(hwif); | ||
221 | |||
222 | mutex_unlock(&ide_cfg_mtx); | ||
223 | } | ||
224 | |||
225 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | ||
226 | { | ||
227 | memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); | ||
228 | hwif->irq = hw->irq; | ||
229 | hwif->chipset = hw->chipset; | ||
230 | hwif->dev = hw->dev; | ||
231 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; | ||
232 | hwif->ack_intr = hw->ack_intr; | ||
233 | hwif->config_data = hw->config; | ||
234 | } | ||
235 | |||
236 | /* | 65 | /* |
237 | * Locks for IDE setting functionality | 66 | * Locks for IDE setting functionality |
238 | */ | 67 | */ |
@@ -330,7 +159,6 @@ static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio) | |||
330 | static int set_pio_mode(ide_drive_t *drive, int arg) | 159 | static int set_pio_mode(ide_drive_t *drive, int arg) |
331 | { | 160 | { |
332 | ide_hwif_t *hwif = drive->hwif; | 161 | ide_hwif_t *hwif = drive->hwif; |
333 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | ||
334 | const struct ide_port_ops *port_ops = hwif->port_ops; | 162 | const struct ide_port_ops *port_ops = hwif->port_ops; |
335 | 163 | ||
336 | if (arg < 0 || arg > 255) | 164 | if (arg < 0 || arg > 255) |
@@ -345,9 +173,9 @@ static int set_pio_mode(ide_drive_t *drive, int arg) | |||
345 | unsigned long flags; | 173 | unsigned long flags; |
346 | 174 | ||
347 | /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ | 175 | /* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */ |
348 | spin_lock_irqsave(&hwgroup->lock, flags); | 176 | spin_lock_irqsave(&hwif->lock, flags); |
349 | port_ops->set_pio_mode(drive, arg); | 177 | port_ops->set_pio_mode(drive, arg); |
350 | spin_unlock_irqrestore(&hwgroup->lock, flags); | 178 | spin_unlock_irqrestore(&hwif->lock, flags); |
351 | } else | 179 | } else |
352 | port_ops->set_pio_mode(drive, arg); | 180 | port_ops->set_pio_mode(drive, arg); |
353 | } else { | 181 | } else { |
@@ -453,7 +281,7 @@ static int ide_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
453 | static int generic_ide_probe(struct device *dev) | 281 | static int generic_ide_probe(struct device *dev) |
454 | { | 282 | { |
455 | ide_drive_t *drive = to_ide_device(dev); | 283 | ide_drive_t *drive = to_ide_device(dev); |
456 | ide_driver_t *drv = to_ide_driver(dev->driver); | 284 | struct ide_driver *drv = to_ide_driver(dev->driver); |
457 | 285 | ||
458 | return drv->probe ? drv->probe(drive) : -ENODEV; | 286 | return drv->probe ? drv->probe(drive) : -ENODEV; |
459 | } | 287 | } |
@@ -461,7 +289,7 @@ static int generic_ide_probe(struct device *dev) | |||
461 | static int generic_ide_remove(struct device *dev) | 289 | static int generic_ide_remove(struct device *dev) |
462 | { | 290 | { |
463 | ide_drive_t *drive = to_ide_device(dev); | 291 | ide_drive_t *drive = to_ide_device(dev); |
464 | ide_driver_t *drv = to_ide_driver(dev->driver); | 292 | struct ide_driver *drv = to_ide_driver(dev->driver); |
465 | 293 | ||
466 | if (drv->remove) | 294 | if (drv->remove) |
467 | drv->remove(drive); | 295 | drv->remove(drive); |
@@ -472,7 +300,7 @@ static int generic_ide_remove(struct device *dev) | |||
472 | static void generic_ide_shutdown(struct device *dev) | 300 | static void generic_ide_shutdown(struct device *dev) |
473 | { | 301 | { |
474 | ide_drive_t *drive = to_ide_device(dev); | 302 | ide_drive_t *drive = to_ide_device(dev); |
475 | ide_driver_t *drv = to_ide_driver(dev->driver); | 303 | struct ide_driver *drv = to_ide_driver(dev->driver); |
476 | 304 | ||
477 | if (dev->driver && drv->shutdown) | 305 | if (dev->driver && drv->shutdown) |
478 | drv->shutdown(drive); | 306 | drv->shutdown(drive); |
@@ -660,6 +488,7 @@ MODULE_PARM_DESC(ignore_cable, "ignore cable detection"); | |||
660 | 488 | ||
661 | void ide_port_apply_params(ide_hwif_t *hwif) | 489 | void ide_port_apply_params(ide_hwif_t *hwif) |
662 | { | 490 | { |
491 | ide_drive_t *drive; | ||
663 | int i; | 492 | int i; |
664 | 493 | ||
665 | if (ide_ignore_cable & (1 << hwif->index)) { | 494 | if (ide_ignore_cable & (1 << hwif->index)) { |
@@ -668,8 +497,8 @@ void ide_port_apply_params(ide_hwif_t *hwif) | |||
668 | hwif->cbl = ATA_CBL_PATA40_SHORT; | 497 | hwif->cbl = ATA_CBL_PATA40_SHORT; |
669 | } | 498 | } |
670 | 499 | ||
671 | for (i = 0; i < MAX_DRIVES; i++) | 500 | ide_port_for_each_dev(i, drive, hwif) |
672 | ide_dev_apply_params(&hwif->drives[i], i); | 501 | ide_dev_apply_params(drive, i); |
673 | } | 502 | } |
674 | 503 | ||
675 | /* | 504 | /* |
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c new file mode 100644 index 000000000000..e021078cd06b --- /dev/null +++ b/drivers/ide/it8172.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * IT8172 IDE controller support | ||
5 | * | ||
6 | * Copyright (C) 2000 MontaVista Software Inc. | ||
7 | * Copyright (C) 2008 Shane McDonald | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/ioport.h> | ||
34 | #include <linux/pci.h> | ||
35 | #include <linux/ide.h> | ||
36 | #include <linux/init.h> | ||
37 | |||
38 | #define DRV_NAME "IT8172" | ||
39 | |||
40 | static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio) | ||
41 | { | ||
42 | ide_hwif_t *hwif = drive->hwif; | ||
43 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
44 | u16 drive_enables; | ||
45 | u32 drive_timing; | ||
46 | |||
47 | /* | ||
48 | * The highest value of DIOR/DIOW pulse width and recovery time | ||
49 | * that can be set in the IT8172 is 8 PCI clock cycles. As a result, | ||
50 | * it cannot be configured for PIO mode 0. This table sets these | ||
51 | * parameters to the maximum supported by the IT8172. | ||
52 | */ | ||
53 | static const u8 timings[] = { 0x3f, 0x3c, 0x1b, 0x12, 0x0a }; | ||
54 | |||
55 | pci_read_config_word(dev, 0x40, &drive_enables); | ||
56 | pci_read_config_dword(dev, 0x44, &drive_timing); | ||
57 | |||
58 | /* | ||
59 | * Enable port 0x44. The IT8172 spec is confused; it calls | ||
60 | * this register the "Slave IDE Timing Register", but in fact, | ||
61 | * it controls timing for both master and slave drives. | ||
62 | */ | ||
63 | drive_enables |= 0x4000; | ||
64 | |||
65 | drive_enables &= drive->dn ? 0xc006 : 0xc060; | ||
66 | if (drive->media == ide_disk) | ||
67 | /* enable prefetch */ | ||
68 | drive_enables |= 0x0004 << (drive->dn * 4); | ||
69 | if (ata_id_has_iordy(drive->id)) | ||
70 | /* enable IORDY sample-point */ | ||
71 | drive_enables |= 0x0002 << (drive->dn * 4); | ||
72 | |||
73 | drive_timing &= drive->dn ? 0x00003f00 : 0x000fc000; | ||
74 | drive_timing |= timings[pio] << (drive->dn * 6 + 8); | ||
75 | |||
76 | pci_write_config_word(dev, 0x40, drive_enables); | ||
77 | pci_write_config_dword(dev, 0x44, drive_timing); | ||
78 | } | ||
79 | |||
80 | static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed) | ||
81 | { | ||
82 | ide_hwif_t *hwif = drive->hwif; | ||
83 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
84 | int a_speed = 3 << (drive->dn * 4); | ||
85 | int u_flag = 1 << drive->dn; | ||
86 | int u_speed = 0; | ||
87 | u8 reg48, reg4a; | ||
88 | |||
89 | pci_read_config_byte(dev, 0x48, ®48); | ||
90 | pci_read_config_byte(dev, 0x4a, ®4a); | ||
91 | |||
92 | if (speed >= XFER_UDMA_0) { | ||
93 | u8 udma = speed - XFER_UDMA_0; | ||
94 | u_speed = udma << (drive->dn * 4); | ||
95 | |||
96 | pci_write_config_byte(dev, 0x48, reg48 | u_flag); | ||
97 | reg4a &= ~a_speed; | ||
98 | pci_write_config_byte(dev, 0x4a, reg4a | u_speed); | ||
99 | } else { | ||
100 | const u8 mwdma_to_pio[] = { 0, 3, 4 }; | ||
101 | u8 pio; | ||
102 | |||
103 | pci_write_config_byte(dev, 0x48, reg48 & ~u_flag); | ||
104 | pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed); | ||
105 | |||
106 | pio = mwdma_to_pio[speed - XFER_MW_DMA_0]; | ||
107 | |||
108 | it8172_set_pio_mode(drive, pio); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | |||
113 | static const struct ide_port_ops it8172_port_ops = { | ||
114 | .set_pio_mode = it8172_set_pio_mode, | ||
115 | .set_dma_mode = it8172_set_dma_mode, | ||
116 | }; | ||
117 | |||
118 | static const struct ide_port_info it8172_port_info __devinitdata = { | ||
119 | .name = DRV_NAME, | ||
120 | .port_ops = &it8172_port_ops, | ||
121 | .enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} }, | ||
122 | .host_flags = IDE_HFLAG_SINGLE, | ||
123 | .pio_mask = ATA_PIO4 & ~ATA_PIO0, | ||
124 | .mwdma_mask = ATA_MWDMA2, | ||
125 | .udma_mask = ATA_UDMA2, | ||
126 | }; | ||
127 | |||
128 | static int __devinit it8172_init_one(struct pci_dev *dev, | ||
129 | const struct pci_device_id *id) | ||
130 | { | ||
131 | if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) | ||
132 | return -ENODEV; /* IT8172 is more than an IDE controller */ | ||
133 | return ide_pci_init_one(dev, &it8172_port_info, NULL); | ||
134 | } | ||
135 | |||
136 | static struct pci_device_id it8172_pci_tbl[] = { | ||
137 | { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8172), 0 }, | ||
138 | { 0, }, | ||
139 | }; | ||
140 | MODULE_DEVICE_TABLE(pci, it8172_pci_tbl); | ||
141 | |||
142 | static struct pci_driver it8172_pci_driver = { | ||
143 | .name = "IT8172_IDE", | ||
144 | .id_table = it8172_pci_tbl, | ||
145 | .probe = it8172_init_one, | ||
146 | .remove = ide_pci_remove, | ||
147 | .suspend = ide_pci_suspend, | ||
148 | .resume = ide_pci_resume, | ||
149 | }; | ||
150 | |||
151 | static int __init it8172_ide_init(void) | ||
152 | { | ||
153 | return ide_pci_register_driver(&it8172_pci_driver); | ||
154 | } | ||
155 | |||
156 | static void __exit it8172_ide_exit(void) | ||
157 | { | ||
158 | pci_unregister_driver(&it8172_pci_driver); | ||
159 | } | ||
160 | |||
161 | module_init(it8172_ide_init); | ||
162 | module_exit(it8172_ide_exit); | ||
163 | |||
164 | MODULE_AUTHOR("Steve Longerbeam"); | ||
165 | MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE"); | ||
166 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c index 7c2feeb3c5ec..d7969b6d139e 100644 --- a/drivers/ide/it8213.c +++ b/drivers/ide/it8213.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) | 26 | static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) |
27 | { | 27 | { |
28 | ide_hwif_t *hwif = HWIF(drive); | 28 | ide_hwif_t *hwif = drive->hwif; |
29 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 29 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
30 | int is_slave = drive->dn & 1; | 30 | int is_slave = drive->dn & 1; |
31 | int master_port = 0x40; | 31 | int master_port = 0x40; |
@@ -82,7 +82,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
82 | 82 | ||
83 | static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed) | 83 | static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed) |
84 | { | 84 | { |
85 | ide_hwif_t *hwif = HWIF(drive); | 85 | ide_hwif_t *hwif = drive->hwif; |
86 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 86 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
87 | u8 maslave = 0x40; | 87 | u8 maslave = 0x40; |
88 | int a_speed = 3 << (drive->dn * 4); | 88 | int a_speed = 3 << (drive->dn * 4); |
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c index ef004089761b..0be27ac1f077 100644 --- a/drivers/ide/it821x.c +++ b/drivers/ide/it821x.c | |||
@@ -167,12 +167,10 @@ static void it821x_clock_strategy(ide_drive_t *drive) | |||
167 | ide_hwif_t *hwif = drive->hwif; | 167 | ide_hwif_t *hwif = drive->hwif; |
168 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 168 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
169 | struct it821x_dev *itdev = ide_get_hwifdata(hwif); | 169 | struct it821x_dev *itdev = ide_get_hwifdata(hwif); |
170 | ide_drive_t *pair; | 170 | ide_drive_t *pair = ide_get_pair_dev(drive); |
171 | int clock, altclock, sel = 0; | 171 | int clock, altclock, sel = 0; |
172 | u8 unit = drive->dn & 1, v; | 172 | u8 unit = drive->dn & 1, v; |
173 | 173 | ||
174 | pair = &hwif->drives[1 - unit]; | ||
175 | |||
176 | if(itdev->want[0][0] > itdev->want[1][0]) { | 174 | if(itdev->want[0][0] > itdev->want[1][0]) { |
177 | clock = itdev->want[0][1]; | 175 | clock = itdev->want[0][1]; |
178 | altclock = itdev->want[1][1]; | 176 | altclock = itdev->want[1][1]; |
@@ -239,15 +237,13 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
239 | { | 237 | { |
240 | ide_hwif_t *hwif = drive->hwif; | 238 | ide_hwif_t *hwif = drive->hwif; |
241 | struct it821x_dev *itdev = ide_get_hwifdata(hwif); | 239 | struct it821x_dev *itdev = ide_get_hwifdata(hwif); |
242 | ide_drive_t *pair; | 240 | ide_drive_t *pair = ide_get_pair_dev(drive); |
243 | u8 unit = drive->dn & 1, set_pio = pio; | 241 | u8 unit = drive->dn & 1, set_pio = pio; |
244 | 242 | ||
245 | /* Spec says 89 ref driver uses 88 */ | 243 | /* Spec says 89 ref driver uses 88 */ |
246 | static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; | 244 | static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; |
247 | static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; | 245 | static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; |
248 | 246 | ||
249 | pair = &hwif->drives[1 - unit]; | ||
250 | |||
251 | /* | 247 | /* |
252 | * Compute the best PIO mode we can for a given device. We must | 248 | * Compute the best PIO mode we can for a given device. We must |
253 | * pick a speed that does not cause problems with the other device | 249 | * pick a speed that does not cause problems with the other device |
@@ -279,7 +275,7 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
279 | * the shared MWDMA/PIO timing register. | 275 | * the shared MWDMA/PIO timing register. |
280 | */ | 276 | */ |
281 | 277 | ||
282 | static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted) | 278 | static void it821x_tune_mwdma(ide_drive_t *drive, u8 mode_wanted) |
283 | { | 279 | { |
284 | ide_hwif_t *hwif = drive->hwif; | 280 | ide_hwif_t *hwif = drive->hwif; |
285 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 281 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
@@ -316,7 +312,7 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted) | |||
316 | * controller when doing UDMA modes in pass through. | 312 | * controller when doing UDMA modes in pass through. |
317 | */ | 313 | */ |
318 | 314 | ||
319 | static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) | 315 | static void it821x_tune_udma(ide_drive_t *drive, u8 mode_wanted) |
320 | { | 316 | { |
321 | ide_hwif_t *hwif = drive->hwif; | 317 | ide_hwif_t *hwif = drive->hwif; |
322 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 318 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
@@ -516,6 +512,7 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = { | |||
516 | .dma_test_irq = ide_dma_test_irq, | 512 | .dma_test_irq = ide_dma_test_irq, |
517 | .dma_timeout = ide_dma_timeout, | 513 | .dma_timeout = ide_dma_timeout, |
518 | .dma_lost_irq = ide_dma_lost_irq, | 514 | .dma_lost_irq = ide_dma_lost_irq, |
515 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
519 | }; | 516 | }; |
520 | 517 | ||
521 | /** | 518 | /** |
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 13789060f407..83643ed9a426 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c | |||
@@ -56,7 +56,7 @@ static u8 superio_read_status(ide_hwif_t *hwif) | |||
56 | return superio_ide_inb(hwif->io_ports.status_addr); | 56 | return superio_ide_inb(hwif->io_ports.status_addr); |
57 | } | 57 | } |
58 | 58 | ||
59 | static u8 superio_read_sff_dma_status(ide_hwif_t *hwif) | 59 | static u8 superio_dma_sff_read_status(ide_hwif_t *hwif) |
60 | { | 60 | { |
61 | return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); | 61 | return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS); |
62 | } | 62 | } |
@@ -109,7 +109,6 @@ static const struct ide_tp_ops superio_tp_ops = { | |||
109 | .exec_command = ide_exec_command, | 109 | .exec_command = ide_exec_command, |
110 | .read_status = superio_read_status, | 110 | .read_status = superio_read_status, |
111 | .read_altstatus = ide_read_altstatus, | 111 | .read_altstatus = ide_read_altstatus, |
112 | .read_sff_dma_status = superio_read_sff_dma_status, | ||
113 | 112 | ||
114 | .set_irq = ide_set_irq, | 113 | .set_irq = ide_set_irq, |
115 | 114 | ||
@@ -132,18 +131,20 @@ static void __devinit superio_init_iops(struct hwif_s *hwif) | |||
132 | tmp = superio_ide_inb(dma_stat); | 131 | tmp = superio_ide_inb(dma_stat); |
133 | outb(tmp | 0x66, dma_stat); | 132 | outb(tmp | 0x66, dma_stat); |
134 | } | 133 | } |
134 | #else | ||
135 | #define superio_dma_sff_read_status ide_dma_sff_read_status | ||
135 | #endif | 136 | #endif |
136 | 137 | ||
137 | static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; | 138 | static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; |
138 | 139 | ||
139 | /* | 140 | /* |
140 | * This routine either enables/disables (according to IDE_DFLAG_PRESENT) | 141 | * This routine either enables/disables (according to IDE_DFLAG_PRESENT) |
141 | * the IRQ associated with the port (HWIF(drive)), | 142 | * the IRQ associated with the port, |
142 | * and selects either PIO or DMA handshaking for the next I/O operation. | 143 | * and selects either PIO or DMA handshaking for the next I/O operation. |
143 | */ | 144 | */ |
144 | static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) | 145 | static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma) |
145 | { | 146 | { |
146 | ide_hwif_t *hwif = HWIF(drive); | 147 | ide_hwif_t *hwif = drive->hwif; |
147 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 148 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
148 | unsigned int bit, other, new, *old = (unsigned int *) hwif->select_data; | 149 | unsigned int bit, other, new, *old = (unsigned int *) hwif->select_data; |
149 | unsigned long flags; | 150 | unsigned long flags; |
@@ -197,11 +198,11 @@ static void ns87415_selectproc (ide_drive_t *drive) | |||
197 | 198 | ||
198 | static int ns87415_dma_end(ide_drive_t *drive) | 199 | static int ns87415_dma_end(ide_drive_t *drive) |
199 | { | 200 | { |
200 | ide_hwif_t *hwif = HWIF(drive); | 201 | ide_hwif_t *hwif = drive->hwif; |
201 | u8 dma_stat = 0, dma_cmd = 0; | 202 | u8 dma_stat = 0, dma_cmd = 0; |
202 | 203 | ||
203 | drive->waiting_for_dma = 0; | 204 | drive->waiting_for_dma = 0; |
204 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 205 | dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
205 | /* get DMA command mode */ | 206 | /* get DMA command mode */ |
206 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | 207 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); |
207 | /* stop DMA */ | 208 | /* stop DMA */ |
@@ -308,6 +309,7 @@ static const struct ide_dma_ops ns87415_dma_ops = { | |||
308 | .dma_test_irq = ide_dma_test_irq, | 309 | .dma_test_irq = ide_dma_test_irq, |
309 | .dma_lost_irq = ide_dma_lost_irq, | 310 | .dma_lost_irq = ide_dma_lost_irq, |
310 | .dma_timeout = ide_dma_timeout, | 311 | .dma_timeout = ide_dma_timeout, |
312 | .dma_sff_read_status = superio_dma_sff_read_status, | ||
311 | }; | 313 | }; |
312 | 314 | ||
313 | static const struct ide_port_info ns87415_chipset __devinitdata = { | 315 | static const struct ide_port_info ns87415_chipset __devinitdata = { |
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c index 122ed3c072fd..a7ac490c9ae3 100644 --- a/drivers/ide/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c | |||
@@ -324,8 +324,6 @@ static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif, | |||
324 | 324 | ||
325 | hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET; | 325 | hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET; |
326 | 326 | ||
327 | hwif->dma_ops = &sff_dma_ops; | ||
328 | |||
329 | return 0; | 327 | return 0; |
330 | } | 328 | } |
331 | 329 | ||
@@ -338,6 +336,7 @@ static const struct ide_port_ops palm_bk3710_ports_ops = { | |||
338 | static struct ide_port_info __devinitdata palm_bk3710_port_info = { | 336 | static struct ide_port_info __devinitdata palm_bk3710_port_info = { |
339 | .init_dma = palm_bk3710_init_dma, | 337 | .init_dma = palm_bk3710_init_dma, |
340 | .port_ops = &palm_bk3710_ports_ops, | 338 | .port_ops = &palm_bk3710_ports_ops, |
339 | .dma_ops = &sff_dma_ops, | ||
341 | .host_flags = IDE_HFLAG_MMIO, | 340 | .host_flags = IDE_HFLAG_MMIO, |
342 | .pio_mask = ATA_PIO4, | 341 | .pio_mask = ATA_PIO4, |
343 | .mwdma_mask = ATA_MWDMA2, | 342 | .mwdma_mask = ATA_MWDMA2, |
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c index 211ae46e3e0c..f21290c4b447 100644 --- a/drivers/ide/pdc202xx_new.c +++ b/drivers/ide/pdc202xx_new.c | |||
@@ -143,7 +143,7 @@ static struct udma_timing { | |||
143 | 143 | ||
144 | static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed) | 144 | static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed) |
145 | { | 145 | { |
146 | ide_hwif_t *hwif = HWIF(drive); | 146 | ide_hwif_t *hwif = drive->hwif; |
147 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 147 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
148 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; | 148 | u8 adj = (drive->dn & 1) ? 0x08 : 0x00; |
149 | 149 | ||
@@ -219,7 +219,7 @@ static void pdcnew_reset(ide_drive_t *drive) | |||
219 | * Deleted this because it is redundant from the caller. | 219 | * Deleted this because it is redundant from the caller. |
220 | */ | 220 | */ |
221 | printk(KERN_WARNING "pdc202xx_new: %s channel reset.\n", | 221 | printk(KERN_WARNING "pdc202xx_new: %s channel reset.\n", |
222 | HWIF(drive)->channel ? "Secondary" : "Primary"); | 222 | drive->hwif->channel ? "Secondary" : "Primary"); |
223 | } | 223 | } |
224 | 224 | ||
225 | /** | 225 | /** |
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index 624e62e5cc9a..97193323aebf 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c | |||
@@ -39,7 +39,7 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *); | |||
39 | 39 | ||
40 | static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed) | 40 | static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed) |
41 | { | 41 | { |
42 | ide_hwif_t *hwif = HWIF(drive); | 42 | ide_hwif_t *hwif = drive->hwif; |
43 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 43 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
44 | u8 drive_pci = 0x60 + (drive->dn << 2); | 44 | u8 drive_pci = 0x60 + (drive->dn << 2); |
45 | 45 | ||
@@ -169,8 +169,8 @@ static void pdc202xx_dma_start(ide_drive_t *drive) | |||
169 | if (drive->current_speed > XFER_UDMA_2) | 169 | if (drive->current_speed > XFER_UDMA_2) |
170 | pdc_old_enable_66MHz_clock(drive->hwif); | 170 | pdc_old_enable_66MHz_clock(drive->hwif); |
171 | if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { | 171 | if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { |
172 | struct request *rq = HWGROUP(drive)->rq; | 172 | ide_hwif_t *hwif = drive->hwif; |
173 | ide_hwif_t *hwif = HWIF(drive); | 173 | struct request *rq = hwif->rq; |
174 | unsigned long high_16 = hwif->extra_base - 16; | 174 | unsigned long high_16 = hwif->extra_base - 16; |
175 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | 175 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); |
176 | u32 word_count = 0; | 176 | u32 word_count = 0; |
@@ -189,7 +189,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive) | |||
189 | static int pdc202xx_dma_end(ide_drive_t *drive) | 189 | static int pdc202xx_dma_end(ide_drive_t *drive) |
190 | { | 190 | { |
191 | if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { | 191 | if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) { |
192 | ide_hwif_t *hwif = HWIF(drive); | 192 | ide_hwif_t *hwif = drive->hwif; |
193 | unsigned long high_16 = hwif->extra_base - 16; | 193 | unsigned long high_16 = hwif->extra_base - 16; |
194 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); | 194 | unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); |
195 | u8 clock = 0; | 195 | u8 clock = 0; |
@@ -205,7 +205,7 @@ static int pdc202xx_dma_end(ide_drive_t *drive) | |||
205 | 205 | ||
206 | static int pdc202xx_dma_test_irq(ide_drive_t *drive) | 206 | static int pdc202xx_dma_test_irq(ide_drive_t *drive) |
207 | { | 207 | { |
208 | ide_hwif_t *hwif = HWIF(drive); | 208 | ide_hwif_t *hwif = drive->hwif; |
209 | unsigned long high_16 = hwif->extra_base - 16; | 209 | unsigned long high_16 = hwif->extra_base - 16; |
210 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 210 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
211 | u8 sc1d = inb(high_16 + 0x001d); | 211 | u8 sc1d = inb(high_16 + 0x001d); |
@@ -243,7 +243,7 @@ static void pdc202xx_reset_host (ide_hwif_t *hwif) | |||
243 | 243 | ||
244 | static void pdc202xx_reset (ide_drive_t *drive) | 244 | static void pdc202xx_reset (ide_drive_t *drive) |
245 | { | 245 | { |
246 | ide_hwif_t *hwif = HWIF(drive); | 246 | ide_hwif_t *hwif = drive->hwif; |
247 | ide_hwif_t *mate = hwif->mate; | 247 | ide_hwif_t *mate = hwif->mate; |
248 | 248 | ||
249 | pdc202xx_reset_host(hwif); | 249 | pdc202xx_reset_host(hwif); |
@@ -337,6 +337,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = { | |||
337 | .dma_test_irq = pdc202xx_dma_test_irq, | 337 | .dma_test_irq = pdc202xx_dma_test_irq, |
338 | .dma_lost_irq = pdc202xx_dma_lost_irq, | 338 | .dma_lost_irq = pdc202xx_dma_lost_irq, |
339 | .dma_timeout = pdc202xx_dma_timeout, | 339 | .dma_timeout = pdc202xx_dma_timeout, |
340 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
340 | }; | 341 | }; |
341 | 342 | ||
342 | static const struct ide_dma_ops pdc2026x_dma_ops = { | 343 | static const struct ide_dma_ops pdc2026x_dma_ops = { |
@@ -348,6 +349,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = { | |||
348 | .dma_test_irq = pdc202xx_dma_test_irq, | 349 | .dma_test_irq = pdc202xx_dma_test_irq, |
349 | .dma_lost_irq = pdc202xx_dma_lost_irq, | 350 | .dma_lost_irq = pdc202xx_dma_lost_irq, |
350 | .dma_timeout = pdc202xx_dma_timeout, | 351 | .dma_timeout = pdc202xx_dma_timeout, |
352 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
351 | }; | 353 | }; |
352 | 354 | ||
353 | #define DECLARE_PDC2026X_DEV(udma, sectors) \ | 355 | #define DECLARE_PDC2026X_DEV(udma, sectors) \ |
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 61d2d920a5cd..f1e2e4ef0d71 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
@@ -67,7 +67,7 @@ static int no_piix_dma; | |||
67 | 67 | ||
68 | static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) | 68 | static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) |
69 | { | 69 | { |
70 | ide_hwif_t *hwif = HWIF(drive); | 70 | ide_hwif_t *hwif = drive->hwif; |
71 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 71 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
72 | int is_slave = drive->dn & 1; | 72 | int is_slave = drive->dn & 1; |
73 | int master_port = hwif->channel ? 0x42 : 0x40; | 73 | int master_port = hwif->channel ? 0x42 : 0x40; |
@@ -136,7 +136,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
136 | 136 | ||
137 | static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) | 137 | static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) |
138 | { | 138 | { |
139 | ide_hwif_t *hwif = HWIF(drive); | 139 | ide_hwif_t *hwif = drive->hwif; |
140 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 140 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
141 | u8 maslave = hwif->channel ? 0x42 : 0x40; | 141 | u8 maslave = hwif->channel ? 0x42 : 0x40; |
142 | int a_speed = 3 << (drive->dn * 4); | 142 | int a_speed = 3 << (drive->dn * 4); |
@@ -224,7 +224,7 @@ static unsigned int init_chipset_ich(struct pci_dev *dev) | |||
224 | */ | 224 | */ |
225 | static void ich_clear_irq(ide_drive_t *drive) | 225 | static void ich_clear_irq(ide_drive_t *drive) |
226 | { | 226 | { |
227 | ide_hwif_t *hwif = HWIF(drive); | 227 | ide_hwif_t *hwif = drive->hwif; |
228 | u8 dma_stat; | 228 | u8 dma_stat; |
229 | 229 | ||
230 | /* | 230 | /* |
@@ -260,6 +260,8 @@ static const struct ich_laptop ich_laptop[] = { | |||
260 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ | 260 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ |
261 | { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ | 261 | { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ |
262 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ | 262 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */ |
263 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ | ||
264 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ | ||
263 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ | 265 | { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ |
264 | /* end marker */ | 266 | /* end marker */ |
265 | { 0, } | 267 | { 0, } |
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 7c481bb56fab..74625e821a43 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c | |||
@@ -955,7 +955,6 @@ static const struct ide_tp_ops pmac_tp_ops = { | |||
955 | .exec_command = pmac_exec_command, | 955 | .exec_command = pmac_exec_command, |
956 | .read_status = ide_read_status, | 956 | .read_status = ide_read_status, |
957 | .read_altstatus = ide_read_altstatus, | 957 | .read_altstatus = ide_read_altstatus, |
958 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
959 | 958 | ||
960 | .set_irq = pmac_set_irq, | 959 | .set_irq = pmac_set_irq, |
961 | 960 | ||
@@ -1513,10 +1512,10 @@ use_pio_instead: | |||
1513 | static int | 1512 | static int |
1514 | pmac_ide_dma_setup(ide_drive_t *drive) | 1513 | pmac_ide_dma_setup(ide_drive_t *drive) |
1515 | { | 1514 | { |
1516 | ide_hwif_t *hwif = HWIF(drive); | 1515 | ide_hwif_t *hwif = drive->hwif; |
1517 | pmac_ide_hwif_t *pmif = | 1516 | pmac_ide_hwif_t *pmif = |
1518 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); | 1517 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); |
1519 | struct request *rq = HWGROUP(drive)->rq; | 1518 | struct request *rq = hwif->rq; |
1520 | u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); | 1519 | u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); |
1521 | 1520 | ||
1522 | if (!pmac_ide_build_dmatable(drive, rq)) { | 1521 | if (!pmac_ide_build_dmatable(drive, rq)) { |
@@ -1637,7 +1636,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive) | |||
1637 | break; | 1636 | break; |
1638 | if (++timeout > 100) { | 1637 | if (++timeout > 100) { |
1639 | printk(KERN_WARNING "ide%d, ide_dma_test_irq \ | 1638 | printk(KERN_WARNING "ide%d, ide_dma_test_irq \ |
1640 | timeout flushing channel\n", HWIF(drive)->index); | 1639 | timeout flushing channel\n", hwif->index); |
1641 | break; | 1640 | break; |
1642 | } | 1641 | } |
1643 | } | 1642 | } |
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c index 4af4a8ce4cdf..9f9c0b3cc3a3 100644 --- a/drivers/ide/q40ide.c +++ b/drivers/ide/q40ide.c | |||
@@ -99,7 +99,6 @@ static const struct ide_tp_ops q40ide_tp_ops = { | |||
99 | .exec_command = ide_exec_command, | 99 | .exec_command = ide_exec_command, |
100 | .read_status = ide_read_status, | 100 | .read_status = ide_read_status, |
101 | .read_altstatus = ide_read_altstatus, | 101 | .read_altstatus = ide_read_altstatus, |
102 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
103 | 102 | ||
104 | .set_irq = ide_set_irq, | 103 | .set_irq = ide_set_irq, |
105 | 104 | ||
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c index bc27c7aba936..5b2e3af43c4b 100644 --- a/drivers/ide/qd65xx.c +++ b/drivers/ide/qd65xx.c | |||
@@ -202,7 +202,8 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
202 | recovery_time = drive->id[ATA_ID_EIDE_PIO] - 120; | 202 | recovery_time = drive->id[ATA_ID_EIDE_PIO] - 120; |
203 | } | 203 | } |
204 | 204 | ||
205 | qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time)); | 205 | qd_set_timing(drive, qd6500_compute_timing(drive->hwif, |
206 | active_time, recovery_time)); | ||
206 | } | 207 | } |
207 | 208 | ||
208 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | 209 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) |
@@ -245,11 +246,11 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
245 | printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio); | 246 | printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio); |
246 | } | 247 | } |
247 | 248 | ||
248 | if (!HWIF(drive)->channel && drive->media != ide_disk) { | 249 | if (!hwif->channel && drive->media != ide_disk) { |
249 | outb(0x5f, QD_CONTROL_PORT); | 250 | outb(0x5f, QD_CONTROL_PORT); |
250 | printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO " | 251 | printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO " |
251 | "and post-write buffer on %s.\n", | 252 | "and post-write buffer on %s.\n", |
252 | drive->name, HWIF(drive)->name); | 253 | drive->name, hwif->name); |
253 | } | 254 | } |
254 | 255 | ||
255 | qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time)); | 256 | qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time)); |
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h index c83dea85e621..6636f9665d16 100644 --- a/drivers/ide/qd65xx.h +++ b/drivers/ide/qd65xx.h | |||
@@ -31,8 +31,8 @@ | |||
31 | 31 | ||
32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) |
33 | 33 | ||
34 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) | 34 | #define QD_TIMING(drive) (u8)(((drive)->drive_data) & 0x00ff) |
35 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) | 35 | #define QD_TIMREG(drive) (u8)((((drive)->drive_data) & 0xff00) >> 8) |
36 | 36 | ||
37 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) | 37 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) |
38 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | 38 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) |
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c index ec7f766ef5e4..dbdd2985a0d8 100644 --- a/drivers/ide/sc1200.c +++ b/drivers/ide/sc1200.c | |||
@@ -125,7 +125,7 @@ out: | |||
125 | 125 | ||
126 | static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) | 126 | static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) |
127 | { | 127 | { |
128 | ide_hwif_t *hwif = HWIF(drive); | 128 | ide_hwif_t *hwif = drive->hwif; |
129 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 129 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
130 | unsigned int reg, timings; | 130 | unsigned int reg, timings; |
131 | unsigned short pci_clock; | 131 | unsigned short pci_clock; |
@@ -170,9 +170,9 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
170 | */ | 170 | */ |
171 | static int sc1200_dma_end(ide_drive_t *drive) | 171 | static int sc1200_dma_end(ide_drive_t *drive) |
172 | { | 172 | { |
173 | ide_hwif_t *hwif = HWIF(drive); | 173 | ide_hwif_t *hwif = drive->hwif; |
174 | unsigned long dma_base = hwif->dma_base; | 174 | unsigned long dma_base = hwif->dma_base; |
175 | byte dma_stat; | 175 | u8 dma_stat; |
176 | 176 | ||
177 | dma_stat = inb(dma_base+2); /* get DMA status */ | 177 | dma_stat = inb(dma_base+2); /* get DMA status */ |
178 | 178 | ||
@@ -199,7 +199,7 @@ static int sc1200_dma_end(ide_drive_t *drive) | |||
199 | 199 | ||
200 | static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) | 200 | static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio) |
201 | { | 201 | { |
202 | ide_hwif_t *hwif = HWIF(drive); | 202 | ide_hwif_t *hwif = drive->hwif; |
203 | int mode = -1; | 203 | int mode = -1; |
204 | 204 | ||
205 | /* | 205 | /* |
@@ -292,6 +292,7 @@ static const struct ide_dma_ops sc1200_dma_ops = { | |||
292 | .dma_test_irq = ide_dma_test_irq, | 292 | .dma_test_irq = ide_dma_test_irq, |
293 | .dma_lost_irq = ide_dma_lost_irq, | 293 | .dma_lost_irq = ide_dma_lost_irq, |
294 | .dma_timeout = ide_dma_timeout, | 294 | .dma_timeout = ide_dma_timeout, |
295 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
295 | }; | 296 | }; |
296 | 297 | ||
297 | static const struct ide_port_info sc1200_chipset __devinitdata = { | 298 | static const struct ide_port_info sc1200_chipset __devinitdata = { |
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c index 0f48f9dacfa5..8d2314b6327c 100644 --- a/drivers/ide/scc_pata.c +++ b/drivers/ide/scc_pata.c | |||
@@ -143,7 +143,7 @@ static u8 scc_read_altstatus(ide_hwif_t *hwif) | |||
143 | return (u8)in_be32((void *)hwif->io_ports.ctl_addr); | 143 | return (u8)in_be32((void *)hwif->io_ports.ctl_addr); |
144 | } | 144 | } |
145 | 145 | ||
146 | static u8 scc_read_sff_dma_status(ide_hwif_t *hwif) | 146 | static u8 scc_dma_sff_read_status(ide_hwif_t *hwif) |
147 | { | 147 | { |
148 | return (u8)in_be32((void *)(hwif->dma_base + 4)); | 148 | return (u8)in_be32((void *)(hwif->dma_base + 4)); |
149 | } | 149 | } |
@@ -217,7 +217,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count) | |||
217 | 217 | ||
218 | static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) | 218 | static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) |
219 | { | 219 | { |
220 | ide_hwif_t *hwif = HWIF(drive); | 220 | ide_hwif_t *hwif = drive->hwif; |
221 | struct scc_ports *ports = ide_get_hwifdata(hwif); | 221 | struct scc_ports *ports = ide_get_hwifdata(hwif); |
222 | unsigned long ctl_base = ports->ctl; | 222 | unsigned long ctl_base = ports->ctl; |
223 | unsigned long cckctrl_port = ctl_base + 0xff0; | 223 | unsigned long cckctrl_port = ctl_base + 0xff0; |
@@ -249,7 +249,7 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
249 | 249 | ||
250 | static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) | 250 | static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) |
251 | { | 251 | { |
252 | ide_hwif_t *hwif = HWIF(drive); | 252 | ide_hwif_t *hwif = drive->hwif; |
253 | struct scc_ports *ports = ide_get_hwifdata(hwif); | 253 | struct scc_ports *ports = ide_get_hwifdata(hwif); |
254 | unsigned long ctl_base = ports->ctl; | 254 | unsigned long ctl_base = ports->ctl; |
255 | unsigned long cckctrl_port = ctl_base + 0xff0; | 255 | unsigned long cckctrl_port = ctl_base + 0xff0; |
@@ -259,7 +259,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
259 | unsigned long scrcst_port = ctl_base + 0x014; | 259 | unsigned long scrcst_port = ctl_base + 0x014; |
260 | unsigned long udenvt_port = ctl_base + 0x018; | 260 | unsigned long udenvt_port = ctl_base + 0x018; |
261 | unsigned long tdvhsel_port = ctl_base + 0x020; | 261 | unsigned long tdvhsel_port = ctl_base + 0x020; |
262 | int is_slave = (&hwif->drives[1] == drive); | 262 | int is_slave = drive->dn & 1; |
263 | int offset, idx; | 263 | int offset, idx; |
264 | unsigned long reg; | 264 | unsigned long reg; |
265 | unsigned long jcactsel; | 265 | unsigned long jcactsel; |
@@ -292,7 +292,7 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) | |||
292 | { | 292 | { |
293 | ide_hwif_t *hwif = drive->hwif; | 293 | ide_hwif_t *hwif = drive->hwif; |
294 | u8 unit = drive->dn & 1; | 294 | u8 unit = drive->dn & 1; |
295 | u8 dma_stat = scc_ide_inb(hwif->dma_base + 4); | 295 | u8 dma_stat = scc_dma_sff_read_status(hwif); |
296 | 296 | ||
297 | if (on) | 297 | if (on) |
298 | dma_stat |= (1 << (5 + unit)); | 298 | dma_stat |= (1 << (5 + unit)); |
@@ -316,7 +316,7 @@ static void scc_dma_host_set(ide_drive_t *drive, int on) | |||
316 | static int scc_dma_setup(ide_drive_t *drive) | 316 | static int scc_dma_setup(ide_drive_t *drive) |
317 | { | 317 | { |
318 | ide_hwif_t *hwif = drive->hwif; | 318 | ide_hwif_t *hwif = drive->hwif; |
319 | struct request *rq = HWGROUP(drive)->rq; | 319 | struct request *rq = hwif->rq; |
320 | unsigned int reading; | 320 | unsigned int reading; |
321 | u8 dma_stat; | 321 | u8 dma_stat; |
322 | 322 | ||
@@ -338,7 +338,7 @@ static int scc_dma_setup(ide_drive_t *drive) | |||
338 | out_be32((void __iomem *)hwif->dma_base, reading); | 338 | out_be32((void __iomem *)hwif->dma_base, reading); |
339 | 339 | ||
340 | /* read DMA status for INTR & ERROR flags */ | 340 | /* read DMA status for INTR & ERROR flags */ |
341 | dma_stat = in_be32((void __iomem *)(hwif->dma_base + 4)); | 341 | dma_stat = scc_dma_sff_read_status(hwif); |
342 | 342 | ||
343 | /* clear INTR & ERROR flags */ | 343 | /* clear INTR & ERROR flags */ |
344 | out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); | 344 | out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6); |
@@ -367,7 +367,7 @@ static int __scc_dma_end(ide_drive_t *drive) | |||
367 | /* stop DMA */ | 367 | /* stop DMA */ |
368 | scc_ide_outb(dma_cmd & ~1, hwif->dma_base); | 368 | scc_ide_outb(dma_cmd & ~1, hwif->dma_base); |
369 | /* get DMA status */ | 369 | /* get DMA status */ |
370 | dma_stat = scc_ide_inb(hwif->dma_base + 4); | 370 | dma_stat = scc_dma_sff_read_status(hwif); |
371 | /* clear the INTR & ERROR bits */ | 371 | /* clear the INTR & ERROR bits */ |
372 | scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); | 372 | scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); |
373 | /* purge DMA mappings */ | 373 | /* purge DMA mappings */ |
@@ -387,7 +387,7 @@ static int __scc_dma_end(ide_drive_t *drive) | |||
387 | 387 | ||
388 | static int scc_dma_end(ide_drive_t *drive) | 388 | static int scc_dma_end(ide_drive_t *drive) |
389 | { | 389 | { |
390 | ide_hwif_t *hwif = HWIF(drive); | 390 | ide_hwif_t *hwif = drive->hwif; |
391 | void __iomem *dma_base = (void __iomem *)hwif->dma_base; | 391 | void __iomem *dma_base = (void __iomem *)hwif->dma_base; |
392 | unsigned long intsts_port = hwif->dma_base + 0x014; | 392 | unsigned long intsts_port = hwif->dma_base + 0x014; |
393 | u32 reg; | 393 | u32 reg; |
@@ -405,17 +405,18 @@ static int scc_dma_end(ide_drive_t *drive) | |||
405 | drive->name); | 405 | drive->name); |
406 | data_loss = 1; | 406 | data_loss = 1; |
407 | if (retry++) { | 407 | if (retry++) { |
408 | struct request *rq = HWGROUP(drive)->rq; | 408 | struct request *rq = hwif->rq; |
409 | int unit; | 409 | ide_drive_t *drive; |
410 | int i; | ||
411 | |||
410 | /* ERROR_RESET and drive->crc_count are needed | 412 | /* ERROR_RESET and drive->crc_count are needed |
411 | * to reduce DMA transfer mode in retry process. | 413 | * to reduce DMA transfer mode in retry process. |
412 | */ | 414 | */ |
413 | if (rq) | 415 | if (rq) |
414 | rq->errors |= ERROR_RESET; | 416 | rq->errors |= ERROR_RESET; |
415 | for (unit = 0; unit < MAX_DRIVES; unit++) { | 417 | |
416 | ide_drive_t *drive = &hwif->drives[unit]; | 418 | ide_port_for_each_dev(i, drive, hwif) |
417 | drive->crc_count++; | 419 | drive->crc_count++; |
418 | } | ||
419 | } | 420 | } |
420 | } | 421 | } |
421 | } | 422 | } |
@@ -496,7 +497,7 @@ static int scc_dma_end(ide_drive_t *drive) | |||
496 | /* returns 1 if dma irq issued, 0 otherwise */ | 497 | /* returns 1 if dma irq issued, 0 otherwise */ |
497 | static int scc_dma_test_irq(ide_drive_t *drive) | 498 | static int scc_dma_test_irq(ide_drive_t *drive) |
498 | { | 499 | { |
499 | ide_hwif_t *hwif = HWIF(drive); | 500 | ide_hwif_t *hwif = drive->hwif; |
500 | u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014); | 501 | u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014); |
501 | 502 | ||
502 | /* SCC errata A252,A308 workaround: Step4 */ | 503 | /* SCC errata A252,A308 workaround: Step4 */ |
@@ -852,7 +853,6 @@ static const struct ide_tp_ops scc_tp_ops = { | |||
852 | .exec_command = scc_exec_command, | 853 | .exec_command = scc_exec_command, |
853 | .read_status = scc_read_status, | 854 | .read_status = scc_read_status, |
854 | .read_altstatus = scc_read_altstatus, | 855 | .read_altstatus = scc_read_altstatus, |
855 | .read_sff_dma_status = scc_read_sff_dma_status, | ||
856 | 856 | ||
857 | .set_irq = scc_set_irq, | 857 | .set_irq = scc_set_irq, |
858 | 858 | ||
@@ -879,6 +879,7 @@ static const struct ide_dma_ops scc_dma_ops = { | |||
879 | .dma_test_irq = scc_dma_test_irq, | 879 | .dma_test_irq = scc_dma_test_irq, |
880 | .dma_lost_irq = ide_dma_lost_irq, | 880 | .dma_lost_irq = ide_dma_lost_irq, |
881 | .dma_timeout = ide_dma_timeout, | 881 | .dma_timeout = ide_dma_timeout, |
882 | .dma_sff_read_status = scc_dma_sff_read_status, | ||
882 | }; | 883 | }; |
883 | 884 | ||
884 | #define DECLARE_SCC_DEV(name_str) \ | 885 | #define DECLARE_SCC_DEV(name_str) \ |
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c index 437bc919dafd..382102ba467b 100644 --- a/drivers/ide/serverworks.c +++ b/drivers/ide/serverworks.c | |||
@@ -151,7 +151,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
151 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; | 151 | static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; |
152 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; | 152 | static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; |
153 | 153 | ||
154 | ide_hwif_t *hwif = HWIF(drive); | 154 | ide_hwif_t *hwif = drive->hwif; |
155 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 155 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
156 | u8 unit = drive->dn & 1; | 156 | u8 unit = drive->dn & 1; |
157 | 157 | ||
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 9f1f9163a136..e85d1ed29c2a 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -130,7 +130,7 @@ int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
130 | * we tune the drive then try to grab DMA ownership if we want to be | 130 | * we tune the drive then try to grab DMA ownership if we want to be |
131 | * the DMA end. This has to be become dynamic to handle hot-plug. | 131 | * the DMA end. This has to be become dynamic to handle hot-plug. |
132 | */ | 132 | */ |
133 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 133 | dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
134 | if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { | 134 | if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { |
135 | printk(KERN_INFO "%s %s: simplex device: DMA disabled\n", | 135 | printk(KERN_INFO "%s %s: simplex device: DMA disabled\n", |
136 | d->name, pci_name(dev)); | 136 | d->name, pci_name(dev)); |
@@ -377,6 +377,9 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
377 | 377 | ||
378 | hwif->dma_base = base; | 378 | hwif->dma_base = base; |
379 | 379 | ||
380 | if (hwif->dma_ops == NULL) | ||
381 | hwif->dma_ops = &sff_dma_ops; | ||
382 | |||
380 | if (ide_pci_check_simplex(hwif, d) < 0) | 383 | if (ide_pci_check_simplex(hwif, d) < 0) |
381 | return -1; | 384 | return -1; |
382 | 385 | ||
@@ -393,8 +396,6 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
393 | 396 | ||
394 | if (ide_allocate_dma_engine(hwif)) | 397 | if (ide_allocate_dma_engine(hwif)) |
395 | return -1; | 398 | return -1; |
396 | |||
397 | hwif->dma_ops = &sff_dma_ops; | ||
398 | } | 399 | } |
399 | 400 | ||
400 | return 0; | 401 | return 0; |
@@ -471,7 +472,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, | |||
471 | */ | 472 | */ |
472 | 473 | ||
473 | for (port = 0; port < channels; ++port) { | 474 | for (port = 0; port < channels; ++port) { |
474 | const ide_pci_enablebit_t *e = &(d->enablebits[port]); | 475 | const struct ide_pci_enablebit *e = &d->enablebits[port]; |
475 | 476 | ||
476 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || | 477 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || |
477 | (tmp & e->mask) != e->val)) { | 478 | (tmp & e->mask) != e->val)) { |
@@ -519,8 +520,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev, | |||
519 | if (ret < 0) | 520 | if (ret < 0) |
520 | goto out; | 521 | goto out; |
521 | 522 | ||
522 | /* Is it an "IDE storage" device in non-PCI mode? */ | 523 | if (ide_pci_is_in_compatibility_mode(dev)) { |
523 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 5) != 5) { | ||
524 | if (noisy) | 524 | if (noisy) |
525 | printk(KERN_INFO "%s %s: not 100%% native mode: will " | 525 | printk(KERN_INFO "%s %s: not 100%% native mode: will " |
526 | "probe irqs later\n", d->name, pci_name(dev)); | 526 | "probe irqs later\n", d->name, pci_name(dev)); |
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c index a687a7dfea6f..fdb9d7037694 100644 --- a/drivers/ide/sgiioc4.c +++ b/drivers/ide/sgiioc4.c | |||
@@ -123,7 +123,7 @@ static int | |||
123 | sgiioc4_clearirq(ide_drive_t * drive) | 123 | sgiioc4_clearirq(ide_drive_t * drive) |
124 | { | 124 | { |
125 | u32 intr_reg; | 125 | u32 intr_reg; |
126 | ide_hwif_t *hwif = HWIF(drive); | 126 | ide_hwif_t *hwif = drive->hwif; |
127 | struct ide_io_ports *io_ports = &hwif->io_ports; | 127 | struct ide_io_ports *io_ports = &hwif->io_ports; |
128 | unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2); | 128 | unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2); |
129 | 129 | ||
@@ -181,7 +181,7 @@ sgiioc4_clearirq(ide_drive_t * drive) | |||
181 | 181 | ||
182 | static void sgiioc4_dma_start(ide_drive_t *drive) | 182 | static void sgiioc4_dma_start(ide_drive_t *drive) |
183 | { | 183 | { |
184 | ide_hwif_t *hwif = HWIF(drive); | 184 | ide_hwif_t *hwif = drive->hwif; |
185 | unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4; | 185 | unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4; |
186 | unsigned int reg = readl((void __iomem *)ioc4_dma_addr); | 186 | unsigned int reg = readl((void __iomem *)ioc4_dma_addr); |
187 | unsigned int temp_reg = reg | IOC4_S_DMA_START; | 187 | unsigned int temp_reg = reg | IOC4_S_DMA_START; |
@@ -209,7 +209,7 @@ sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) | |||
209 | static int sgiioc4_dma_end(ide_drive_t *drive) | 209 | static int sgiioc4_dma_end(ide_drive_t *drive) |
210 | { | 210 | { |
211 | u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; | 211 | u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; |
212 | ide_hwif_t *hwif = HWIF(drive); | 212 | ide_hwif_t *hwif = drive->hwif; |
213 | unsigned long dma_base = hwif->dma_base; | 213 | unsigned long dma_base = hwif->dma_base; |
214 | int dma_stat = 0; | 214 | int dma_stat = 0; |
215 | unsigned long *ending_dma = ide_get_hwifdata(hwif); | 215 | unsigned long *ending_dma = ide_get_hwifdata(hwif); |
@@ -271,7 +271,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
271 | /* returns 1 if dma irq issued, 0 otherwise */ | 271 | /* returns 1 if dma irq issued, 0 otherwise */ |
272 | static int sgiioc4_dma_test_irq(ide_drive_t *drive) | 272 | static int sgiioc4_dma_test_irq(ide_drive_t *drive) |
273 | { | 273 | { |
274 | return sgiioc4_checkirq(HWIF(drive)); | 274 | return sgiioc4_checkirq(drive->hwif); |
275 | } | 275 | } |
276 | 276 | ||
277 | static void sgiioc4_dma_host_set(ide_drive_t *drive, int on) | 277 | static void sgiioc4_dma_host_set(ide_drive_t *drive, int on) |
@@ -367,7 +367,7 @@ static void | |||
367 | sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | 367 | sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) |
368 | { | 368 | { |
369 | u32 ioc4_dma; | 369 | u32 ioc4_dma; |
370 | ide_hwif_t *hwif = HWIF(drive); | 370 | ide_hwif_t *hwif = drive->hwif; |
371 | unsigned long dma_base = hwif->dma_base; | 371 | unsigned long dma_base = hwif->dma_base; |
372 | unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; | 372 | unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; |
373 | u32 dma_addr, ending_dma_addr; | 373 | u32 dma_addr, ending_dma_addr; |
@@ -427,7 +427,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | |||
427 | static unsigned int | 427 | static unsigned int |
428 | sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) | 428 | sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) |
429 | { | 429 | { |
430 | ide_hwif_t *hwif = HWIF(drive); | 430 | ide_hwif_t *hwif = drive->hwif; |
431 | unsigned int *table = hwif->dmatable_cpu; | 431 | unsigned int *table = hwif->dmatable_cpu; |
432 | unsigned int count = 0, i = 1; | 432 | unsigned int count = 0, i = 1; |
433 | struct scatterlist *sg; | 433 | struct scatterlist *sg; |
@@ -492,7 +492,7 @@ use_pio_instead: | |||
492 | 492 | ||
493 | static int sgiioc4_dma_setup(ide_drive_t *drive) | 493 | static int sgiioc4_dma_setup(ide_drive_t *drive) |
494 | { | 494 | { |
495 | struct request *rq = HWGROUP(drive)->rq; | 495 | struct request *rq = drive->hwif->rq; |
496 | unsigned int count = 0; | 496 | unsigned int count = 0; |
497 | int ddir; | 497 | int ddir; |
498 | 498 | ||
@@ -523,7 +523,6 @@ static const struct ide_tp_ops sgiioc4_tp_ops = { | |||
523 | .exec_command = ide_exec_command, | 523 | .exec_command = ide_exec_command, |
524 | .read_status = sgiioc4_read_status, | 524 | .read_status = sgiioc4_read_status, |
525 | .read_altstatus = ide_read_altstatus, | 525 | .read_altstatus = ide_read_altstatus, |
526 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
527 | 526 | ||
528 | .set_irq = ide_set_irq, | 527 | .set_irq = ide_set_irq, |
529 | 528 | ||
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index 7d622d20bc4c..cb2b352b876b 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c | |||
@@ -114,7 +114,7 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r) | |||
114 | 114 | ||
115 | static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) | 115 | static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) |
116 | { | 116 | { |
117 | ide_hwif_t *hwif = HWIF(drive); | 117 | ide_hwif_t *hwif = drive->hwif; |
118 | unsigned long base = (unsigned long)hwif->hwif_data; | 118 | unsigned long base = (unsigned long)hwif->hwif_data; |
119 | u8 unit = drive->dn & 1; | 119 | u8 unit = drive->dn & 1; |
120 | 120 | ||
@@ -243,7 +243,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) | |||
243 | static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; | 243 | static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 }; |
244 | static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; | 244 | static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; |
245 | 245 | ||
246 | ide_hwif_t *hwif = HWIF(drive); | 246 | ide_hwif_t *hwif = drive->hwif; |
247 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 247 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
248 | ide_drive_t *pair = ide_get_pair_dev(drive); | 248 | ide_drive_t *pair = ide_get_pair_dev(drive); |
249 | u32 speedt = 0; | 249 | u32 speedt = 0; |
@@ -300,7 +300,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
300 | static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; | 300 | static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 }; |
301 | static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; | 301 | static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 }; |
302 | 302 | ||
303 | ide_hwif_t *hwif = HWIF(drive); | 303 | ide_hwif_t *hwif = drive->hwif; |
304 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 304 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
305 | unsigned long base = (unsigned long)hwif->hwif_data; | 305 | unsigned long base = (unsigned long)hwif->hwif_data; |
306 | u16 ultra = 0, multi = 0; | 306 | u16 ultra = 0, multi = 0; |
@@ -340,7 +340,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
340 | /* returns 1 if dma irq issued, 0 otherwise */ | 340 | /* returns 1 if dma irq issued, 0 otherwise */ |
341 | static int siimage_io_dma_test_irq(ide_drive_t *drive) | 341 | static int siimage_io_dma_test_irq(ide_drive_t *drive) |
342 | { | 342 | { |
343 | ide_hwif_t *hwif = HWIF(drive); | 343 | ide_hwif_t *hwif = drive->hwif; |
344 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 344 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
345 | u8 dma_altstat = 0; | 345 | u8 dma_altstat = 0; |
346 | unsigned long addr = siimage_selreg(hwif, 1); | 346 | unsigned long addr = siimage_selreg(hwif, 1); |
@@ -367,7 +367,7 @@ static int siimage_io_dma_test_irq(ide_drive_t *drive) | |||
367 | 367 | ||
368 | static int siimage_mmio_dma_test_irq(ide_drive_t *drive) | 368 | static int siimage_mmio_dma_test_irq(ide_drive_t *drive) |
369 | { | 369 | { |
370 | ide_hwif_t *hwif = HWIF(drive); | 370 | ide_hwif_t *hwif = drive->hwif; |
371 | unsigned long addr = siimage_selreg(hwif, 0x1); | 371 | unsigned long addr = siimage_selreg(hwif, 0x1); |
372 | void __iomem *sata_error_addr | 372 | void __iomem *sata_error_addr |
373 | = (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET]; | 373 | = (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET]; |
@@ -717,6 +717,7 @@ static const struct ide_dma_ops sil_dma_ops = { | |||
717 | .dma_test_irq = siimage_dma_test_irq, | 717 | .dma_test_irq = siimage_dma_test_irq, |
718 | .dma_timeout = ide_dma_timeout, | 718 | .dma_timeout = ide_dma_timeout, |
719 | .dma_lost_irq = ide_dma_lost_irq, | 719 | .dma_lost_irq = ide_dma_lost_irq, |
720 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
720 | }; | 721 | }; |
721 | 722 | ||
722 | #define DECLARE_SII_DEV(p_ops) \ | 723 | #define DECLARE_SII_DEV(p_ops) \ |
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index ad32e18c5ba3..9ec1a4a4432c 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c | |||
@@ -274,7 +274,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode) | |||
274 | 274 | ||
275 | static void config_drive_art_rwp(ide_drive_t *drive) | 275 | static void config_drive_art_rwp(ide_drive_t *drive) |
276 | { | 276 | { |
277 | ide_hwif_t *hwif = HWIF(drive); | 277 | ide_hwif_t *hwif = drive->hwif; |
278 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 278 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
279 | u8 reg4bh = 0; | 279 | u8 reg4bh = 0; |
280 | u8 rw_prefetch = 0; | 280 | u8 rw_prefetch = 0; |
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 84dc33602ff8..48cc748c5043 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c | |||
@@ -140,7 +140,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) | |||
140 | */ | 140 | */ |
141 | static void sl82c105_dma_lost_irq(ide_drive_t *drive) | 141 | static void sl82c105_dma_lost_irq(ide_drive_t *drive) |
142 | { | 142 | { |
143 | ide_hwif_t *hwif = HWIF(drive); | 143 | ide_hwif_t *hwif = drive->hwif; |
144 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 144 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
145 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; | 145 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; |
146 | u8 dma_cmd; | 146 | u8 dma_cmd; |
@@ -177,7 +177,7 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive) | |||
177 | */ | 177 | */ |
178 | static void sl82c105_dma_start(ide_drive_t *drive) | 178 | static void sl82c105_dma_start(ide_drive_t *drive) |
179 | { | 179 | { |
180 | ide_hwif_t *hwif = HWIF(drive); | 180 | ide_hwif_t *hwif = drive->hwif; |
181 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 181 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
182 | int reg = 0x44 + drive->dn * 4; | 182 | int reg = 0x44 + drive->dn * 4; |
183 | 183 | ||
@@ -299,6 +299,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = { | |||
299 | .dma_test_irq = ide_dma_test_irq, | 299 | .dma_test_irq = ide_dma_test_irq, |
300 | .dma_lost_irq = sl82c105_dma_lost_irq, | 300 | .dma_lost_irq = sl82c105_dma_lost_irq, |
301 | .dma_timeout = sl82c105_dma_timeout, | 301 | .dma_timeout = sl82c105_dma_timeout, |
302 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
302 | }; | 303 | }; |
303 | 304 | ||
304 | static const struct ide_port_info sl82c105_chipset __devinitdata = { | 305 | static const struct ide_port_info sl82c105_chipset __devinitdata = { |
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index 0f759e4ed779..40b4b94a4288 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c | |||
@@ -20,7 +20,7 @@ static DEFINE_SPINLOCK(slc90e66_lock); | |||
20 | 20 | ||
21 | static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) | 21 | static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) |
22 | { | 22 | { |
23 | ide_hwif_t *hwif = HWIF(drive); | 23 | ide_hwif_t *hwif = drive->hwif; |
24 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 24 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
25 | int is_slave = drive->dn & 1; | 25 | int is_slave = drive->dn & 1; |
26 | int master_port = hwif->channel ? 0x42 : 0x40; | 26 | int master_port = hwif->channel ? 0x42 : 0x40; |
@@ -73,7 +73,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
73 | 73 | ||
74 | static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) | 74 | static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed) |
75 | { | 75 | { |
76 | ide_hwif_t *hwif = HWIF(drive); | 76 | ide_hwif_t *hwif = drive->hwif; |
77 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 77 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
78 | u8 maslave = hwif->channel ? 0x42 : 0x40; | 78 | u8 maslave = hwif->channel ? 0x42 : 0x40; |
79 | int sitre = 0, a_speed = 7 << (drive->dn * 4); | 79 | int sitre = 0, a_speed = 7 << (drive->dn * 4); |
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c index 93e2cce4b296..84109f5a1632 100644 --- a/drivers/ide/tc86c001.c +++ b/drivers/ide/tc86c001.c | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed) | 16 | static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed) |
17 | { | 17 | { |
18 | ide_hwif_t *hwif = HWIF(drive); | 18 | ide_hwif_t *hwif = drive->hwif; |
19 | unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); | 19 | unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); |
20 | u16 mode, scr = inw(scr_port); | 20 | u16 mode, scr = inw(scr_port); |
21 | 21 | ||
@@ -62,13 +62,12 @@ static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
62 | */ | 62 | */ |
63 | static int tc86c001_timer_expiry(ide_drive_t *drive) | 63 | static int tc86c001_timer_expiry(ide_drive_t *drive) |
64 | { | 64 | { |
65 | ide_hwif_t *hwif = HWIF(drive); | 65 | ide_hwif_t *hwif = drive->hwif; |
66 | ide_expiry_t *expiry = ide_get_hwifdata(hwif); | 66 | ide_expiry_t *expiry = ide_get_hwifdata(hwif); |
67 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | ||
68 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | 67 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); |
69 | 68 | ||
70 | /* Restore a higher level driver's expiry handler first. */ | 69 | /* Restore a higher level driver's expiry handler first. */ |
71 | hwgroup->expiry = expiry; | 70 | hwif->expiry = expiry; |
72 | 71 | ||
73 | if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */ | 72 | if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */ |
74 | unsigned long sc_base = hwif->config_data; | 73 | unsigned long sc_base = hwif->config_data; |
@@ -110,11 +109,10 @@ static int tc86c001_timer_expiry(ide_drive_t *drive) | |||
110 | 109 | ||
111 | static void tc86c001_dma_start(ide_drive_t *drive) | 110 | static void tc86c001_dma_start(ide_drive_t *drive) |
112 | { | 111 | { |
113 | ide_hwif_t *hwif = HWIF(drive); | 112 | ide_hwif_t *hwif = drive->hwif; |
114 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | ||
115 | unsigned long sc_base = hwif->config_data; | 113 | unsigned long sc_base = hwif->config_data; |
116 | unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04); | 114 | unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04); |
117 | unsigned long nsectors = hwgroup->rq->nr_sectors; | 115 | unsigned long nsectors = hwif->rq->nr_sectors; |
118 | 116 | ||
119 | /* | 117 | /* |
120 | * We have to manually load the sector count and size into | 118 | * We have to manually load the sector count and size into |
@@ -125,8 +123,8 @@ static void tc86c001_dma_start(ide_drive_t *drive) | |||
125 | outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ | 123 | outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ |
126 | 124 | ||
127 | /* Install our timeout expiry hook, saving the current handler... */ | 125 | /* Install our timeout expiry hook, saving the current handler... */ |
128 | ide_set_hwifdata(hwif, hwgroup->expiry); | 126 | ide_set_hwifdata(hwif, hwif->expiry); |
129 | hwgroup->expiry = &tc86c001_timer_expiry; | 127 | hwif->expiry = &tc86c001_timer_expiry; |
130 | 128 | ||
131 | ide_dma_start(drive); | 129 | ide_dma_start(drive); |
132 | } | 130 | } |
@@ -190,6 +188,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = { | |||
190 | .dma_test_irq = ide_dma_test_irq, | 188 | .dma_test_irq = ide_dma_test_irq, |
191 | .dma_lost_irq = ide_dma_lost_irq, | 189 | .dma_lost_irq = ide_dma_lost_irq, |
192 | .dma_timeout = ide_dma_timeout, | 190 | .dma_timeout = ide_dma_timeout, |
191 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
193 | }; | 192 | }; |
194 | 193 | ||
195 | static const struct ide_port_info tc86c001_chipset __devinitdata = { | 194 | static const struct ide_port_info tc86c001_chipset __devinitdata = { |
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c index b6ff40336aa9..8773c3ba7462 100644 --- a/drivers/ide/triflex.c +++ b/drivers/ide/triflex.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | static void triflex_set_mode(ide_drive_t *drive, const u8 speed) | 37 | static void triflex_set_mode(ide_drive_t *drive, const u8 speed) |
38 | { | 38 | { |
39 | ide_hwif_t *hwif = HWIF(drive); | 39 | ide_hwif_t *hwif = drive->hwif; |
40 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 40 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
41 | u32 triflex_timings = 0; | 41 | u32 triflex_timings = 0; |
42 | u16 timing = 0; | 42 | u16 timing = 0; |
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index 2a5ea90cf8b8..b6a1285a4021 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c | |||
@@ -144,7 +144,7 @@ | |||
144 | 144 | ||
145 | static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) | 145 | static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma) |
146 | { | 146 | { |
147 | ide_hwif_t *hwif = HWIF(drive); | 147 | ide_hwif_t *hwif = drive->hwif; |
148 | u16 reg = 0; | 148 | u16 reg = 0; |
149 | unsigned long flags; | 149 | unsigned long flags; |
150 | 150 | ||
@@ -184,7 +184,7 @@ static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command) | |||
184 | static int trm290_dma_setup(ide_drive_t *drive) | 184 | static int trm290_dma_setup(ide_drive_t *drive) |
185 | { | 185 | { |
186 | ide_hwif_t *hwif = drive->hwif; | 186 | ide_hwif_t *hwif = drive->hwif; |
187 | struct request *rq = hwif->hwgroup->rq; | 187 | struct request *rq = hwif->rq; |
188 | unsigned int count, rw; | 188 | unsigned int count, rw; |
189 | 189 | ||
190 | if (rq_data_dir(rq)) { | 190 | if (rq_data_dir(rq)) { |
@@ -222,15 +222,15 @@ static int trm290_dma_end(ide_drive_t *drive) | |||
222 | drive->waiting_for_dma = 0; | 222 | drive->waiting_for_dma = 0; |
223 | /* purge DMA mappings */ | 223 | /* purge DMA mappings */ |
224 | ide_destroy_dmatable(drive); | 224 | ide_destroy_dmatable(drive); |
225 | status = inw(HWIF(drive)->dma_base + 2); | 225 | status = inw(drive->hwif->dma_base + 2); |
226 | |||
226 | return status != 0x00ff; | 227 | return status != 0x00ff; |
227 | } | 228 | } |
228 | 229 | ||
229 | static int trm290_dma_test_irq(ide_drive_t *drive) | 230 | static int trm290_dma_test_irq(ide_drive_t *drive) |
230 | { | 231 | { |
231 | u16 status; | 232 | u16 status = inw(drive->hwif->dma_base + 2); |
232 | 233 | ||
233 | status = inw(HWIF(drive)->dma_base + 2); | ||
234 | return status == 0x00ff; | 234 | return status == 0x00ff; |
235 | } | 235 | } |
236 | 236 | ||
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c index 4a8c5a21bd4c..882f6f07c476 100644 --- a/drivers/ide/tx4939ide.c +++ b/drivers/ide/tx4939ide.c | |||
@@ -293,7 +293,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive) | |||
293 | { | 293 | { |
294 | ide_hwif_t *hwif = drive->hwif; | 294 | ide_hwif_t *hwif = drive->hwif; |
295 | void __iomem *base = TX4939IDE_BASE(hwif); | 295 | void __iomem *base = TX4939IDE_BASE(hwif); |
296 | struct request *rq = hwif->hwgroup->rq; | 296 | struct request *rq = hwif->rq; |
297 | u8 reading; | 297 | u8 reading; |
298 | int nent; | 298 | int nent; |
299 | 299 | ||
@@ -397,6 +397,17 @@ static int tx4939ide_dma_test_irq(ide_drive_t *drive) | |||
397 | return found; | 397 | return found; |
398 | } | 398 | } |
399 | 399 | ||
400 | #ifdef __BIG_ENDIAN | ||
401 | static u8 tx4939ide_dma_sff_read_status(ide_hwif_t *hwif) | ||
402 | { | ||
403 | void __iomem *base = TX4939IDE_BASE(hwif); | ||
404 | |||
405 | return tx4939ide_readb(base, TX4939IDE_DMA_Stat); | ||
406 | } | ||
407 | #else | ||
408 | #define tx4939ide_dma_sff_read_status ide_dma_sff_read_status | ||
409 | #endif | ||
410 | |||
400 | static void tx4939ide_init_hwif(ide_hwif_t *hwif) | 411 | static void tx4939ide_init_hwif(ide_hwif_t *hwif) |
401 | { | 412 | { |
402 | void __iomem *base = TX4939IDE_BASE(hwif); | 413 | void __iomem *base = TX4939IDE_BASE(hwif); |
@@ -443,13 +454,6 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task) | |||
443 | 454 | ||
444 | #ifdef __BIG_ENDIAN | 455 | #ifdef __BIG_ENDIAN |
445 | 456 | ||
446 | static u8 tx4939ide_read_sff_dma_status(ide_hwif_t *hwif) | ||
447 | { | ||
448 | void __iomem *base = TX4939IDE_BASE(hwif); | ||
449 | |||
450 | return tx4939ide_readb(base, TX4939IDE_DMA_Stat); | ||
451 | } | ||
452 | |||
453 | /* custom iops (independent from SWAP_IO_SPACE) */ | 457 | /* custom iops (independent from SWAP_IO_SPACE) */ |
454 | static u8 tx4939ide_inb(unsigned long port) | 458 | static u8 tx4939ide_inb(unsigned long port) |
455 | { | 459 | { |
@@ -585,7 +589,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { | |||
585 | .exec_command = ide_exec_command, | 589 | .exec_command = ide_exec_command, |
586 | .read_status = ide_read_status, | 590 | .read_status = ide_read_status, |
587 | .read_altstatus = ide_read_altstatus, | 591 | .read_altstatus = ide_read_altstatus, |
588 | .read_sff_dma_status = tx4939ide_read_sff_dma_status, | ||
589 | 592 | ||
590 | .set_irq = ide_set_irq, | 593 | .set_irq = ide_set_irq, |
591 | 594 | ||
@@ -609,7 +612,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = { | |||
609 | .exec_command = ide_exec_command, | 612 | .exec_command = ide_exec_command, |
610 | .read_status = ide_read_status, | 613 | .read_status = ide_read_status, |
611 | .read_altstatus = ide_read_altstatus, | 614 | .read_altstatus = ide_read_altstatus, |
612 | .read_sff_dma_status = ide_read_sff_dma_status, | ||
613 | 615 | ||
614 | .set_irq = ide_set_irq, | 616 | .set_irq = ide_set_irq, |
615 | 617 | ||
@@ -638,6 +640,7 @@ static const struct ide_dma_ops tx4939ide_dma_ops = { | |||
638 | .dma_test_irq = tx4939ide_dma_test_irq, | 640 | .dma_test_irq = tx4939ide_dma_test_irq, |
639 | .dma_lost_irq = ide_dma_lost_irq, | 641 | .dma_lost_irq = ide_dma_lost_irq, |
640 | .dma_timeout = ide_dma_timeout, | 642 | .dma_timeout = ide_dma_timeout, |
643 | .dma_sff_read_status = tx4939ide_dma_sff_read_status, | ||
641 | }; | 644 | }; |
642 | 645 | ||
643 | static const struct ide_port_info tx4939ide_port_info __initdata = { | 646 | static const struct ide_port_info tx4939ide_port_info __initdata = { |
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c index e29978cf6197..0608d41fb6d0 100644 --- a/drivers/ide/umc8672.c +++ b/drivers/ide/umc8672.c | |||
@@ -106,22 +106,21 @@ static void umc_set_speeds(u8 speeds[]) | |||
106 | 106 | ||
107 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) | 107 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) |
108 | { | 108 | { |
109 | ide_hwif_t *hwif = drive->hwif; | 109 | ide_hwif_t *hwif = drive->hwif, *mate = hwif->mate; |
110 | ide_hwgroup_t *mate_hwgroup = hwif->mate ? hwif->mate->hwgroup : NULL; | ||
111 | unsigned long uninitialized_var(flags); | 110 | unsigned long uninitialized_var(flags); |
112 | 111 | ||
113 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | 112 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", |
114 | drive->name, pio, pio_to_umc[pio]); | 113 | drive->name, pio, pio_to_umc[pio]); |
115 | if (mate_hwgroup) | 114 | if (mate) |
116 | spin_lock_irqsave(&mate_hwgroup->lock, flags); | 115 | spin_lock_irqsave(&mate->lock, flags); |
117 | if (mate_hwgroup && mate_hwgroup->handler) { | 116 | if (mate && mate->handler) { |
118 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); | 117 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); |
119 | } else { | 118 | } else { |
120 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | 119 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; |
121 | umc_set_speeds(current_speeds); | 120 | umc_set_speeds(current_speeds); |
122 | } | 121 | } |
123 | if (mate_hwgroup) | 122 | if (mate) |
124 | spin_unlock_irqrestore(&mate_hwgroup->lock, flags); | 123 | spin_unlock_irqrestore(&mate->lock, flags); |
125 | } | 124 | } |
126 | 125 | ||
127 | static const struct ide_port_ops umc8672_port_ops = { | 126 | static const struct ide_port_ops umc8672_port_ops = { |
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 2a812d3207e9..fecc0e03c3fc 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c | |||
@@ -178,7 +178,7 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed) | |||
178 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); | 178 | ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT); |
179 | } | 179 | } |
180 | 180 | ||
181 | via_set_speed(HWIF(drive), drive->dn, &t); | 181 | via_set_speed(hwif, drive->dn, &t); |
182 | } | 182 | } |
183 | 183 | ||
184 | /** | 184 | /** |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 22bf981d393b..82607add69a9 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -554,7 +554,7 @@ thermostat_init(void) | |||
554 | const u32 *prop; | 554 | const u32 *prop; |
555 | int i = 0, offset = 0; | 555 | int i = 0, offset = 0; |
556 | int err; | 556 | int err; |
557 | 557 | ||
558 | np = of_find_node_by_name(NULL, "fan"); | 558 | np = of_find_node_by_name(NULL, "fan"); |
559 | if (!np) | 559 | if (!np) |
560 | return -ENODEV; | 560 | return -ENODEV; |
@@ -613,13 +613,13 @@ thermostat_init(void) | |||
613 | } | 613 | } |
614 | 614 | ||
615 | of_dev = of_platform_device_create(np, "temperatures", NULL); | 615 | of_dev = of_platform_device_create(np, "temperatures", NULL); |
616 | 616 | of_node_put(np); | |
617 | |||
617 | if (of_dev == NULL) { | 618 | if (of_dev == NULL) { |
618 | printk(KERN_ERR "Can't register temperatures device !\n"); | 619 | printk(KERN_ERR "Can't register temperatures device !\n"); |
619 | of_node_put(np); | ||
620 | return -ENODEV; | 620 | return -ENODEV; |
621 | } | 621 | } |
622 | 622 | ||
623 | err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); | 623 | err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); |
624 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); | 624 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); |
625 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); | 625 | err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 65d69665f1fc..6a32680dbb1b 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -79,6 +79,10 @@ static int dvb_device_open(struct inode *inode, struct file *file) | |||
79 | file->private_data = dvbdev; | 79 | file->private_data = dvbdev; |
80 | old_fops = file->f_op; | 80 | old_fops = file->f_op; |
81 | file->f_op = fops_get(dvbdev->fops); | 81 | file->f_op = fops_get(dvbdev->fops); |
82 | if (file->f_op == NULL) { | ||
83 | file->f_op = old_fops; | ||
84 | goto fail; | ||
85 | } | ||
82 | if(file->f_op->open) | 86 | if(file->f_op->open) |
83 | err = file->f_op->open(inode,file); | 87 | err = file->f_op->open(inode,file); |
84 | if (err) { | 88 | if (err) { |
@@ -90,6 +94,7 @@ static int dvb_device_open(struct inode *inode, struct file *file) | |||
90 | unlock_kernel(); | 94 | unlock_kernel(); |
91 | return err; | 95 | return err; |
92 | } | 96 | } |
97 | fail: | ||
93 | up_read(&minor_rwsem); | 98 | up_read(&minor_rwsem); |
94 | unlock_kernel(); | 99 | unlock_kernel(); |
95 | return -ENODEV; | 100 | return -ENODEV; |
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index d450cab20be4..b617bf05e2d7 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -203,7 +203,6 @@ static int poll_one(struct file *file, struct poll_wqueues *pwq) | |||
203 | table = &pwq->pt; | 203 | table = &pwq->pt; |
204 | for (;;) { | 204 | for (;;) { |
205 | int mask; | 205 | int mask; |
206 | set_current_state(TASK_INTERRUPTIBLE); | ||
207 | mask = file->f_op->poll(file, table); | 206 | mask = file->f_op->poll(file, table); |
208 | if (mask & POLLIN) | 207 | if (mask & POLLIN) |
209 | break; | 208 | break; |
@@ -212,9 +211,8 @@ static int poll_one(struct file *file, struct poll_wqueues *pwq) | |||
212 | retval = -ERESTARTSYS; | 211 | retval = -ERESTARTSYS; |
213 | break; | 212 | break; |
214 | } | 213 | } |
215 | schedule(); | 214 | poll_schedule(pwq, TASK_INTERRUPTIBLE); |
216 | } | 215 | } |
217 | set_current_state(TASK_RUNNING); | ||
218 | poll_freewait(pwq); | 216 | poll_freewait(pwq); |
219 | return retval; | 217 | return retval; |
220 | } | 218 | } |
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c index a7dd03e8d332..0ee4264f5db7 100644 --- a/drivers/message/i2o/device.c +++ b/drivers/message/i2o/device.c | |||
@@ -52,7 +52,6 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd, | |||
52 | /** | 52 | /** |
53 | * i2o_device_claim - claim a device for use by an OSM | 53 | * i2o_device_claim - claim a device for use by an OSM |
54 | * @dev: I2O device to claim | 54 | * @dev: I2O device to claim |
55 | * @drv: I2O driver which wants to claim the device | ||
56 | * | 55 | * |
57 | * Do the leg work to assign a device to a given OSM. If the claim succeeds, | 56 | * Do the leg work to assign a device to a given OSM. If the claim succeeds, |
58 | * the owner is the primary. If the attempt fails a negative errno code | 57 | * the owner is the primary. If the attempt fails a negative errno code |
@@ -80,7 +79,6 @@ int i2o_device_claim(struct i2o_device *dev) | |||
80 | /** | 79 | /** |
81 | * i2o_device_claim_release - release a device that the OSM is using | 80 | * i2o_device_claim_release - release a device that the OSM is using |
82 | * @dev: device to release | 81 | * @dev: device to release |
83 | * @drv: driver which claimed the device | ||
84 | * | 82 | * |
85 | * Drop a claim by an OSM on a given I2O device. | 83 | * Drop a claim by an OSM on a given I2O device. |
86 | * | 84 | * |
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index e0d474b17433..a0421efe04ca 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c | |||
@@ -173,7 +173,6 @@ void i2o_driver_unregister(struct i2o_driver *drv) | |||
173 | * i2o_driver_dispatch - dispatch an I2O reply message | 173 | * i2o_driver_dispatch - dispatch an I2O reply message |
174 | * @c: I2O controller of the message | 174 | * @c: I2O controller of the message |
175 | * @m: I2O message number | 175 | * @m: I2O message number |
176 | * @msg: I2O message to be delivered | ||
177 | * | 176 | * |
178 | * The reply is delivered to the driver from which the original message | 177 | * The reply is delivered to the driver from which the original message |
179 | * was. This function is only called from interrupt context. | 178 | * was. This function is only called from interrupt context. |
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index b5f6add34b0b..dc14b0b9cbfa 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c | |||
@@ -104,8 +104,7 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi | |||
104 | } | 104 | } |
105 | 105 | ||
106 | sp->irq = pdev->irq; | 106 | sp->irq = pdev->irq; |
107 | sp->base_address = ioremap(pci_resource_start(pdev, 0), | 107 | sp->base_address = pci_ioremap_bar(pdev, 0); |
108 | pci_resource_len(pdev, 0)); | ||
109 | if (!sp->base_address) { | 108 | if (!sp->base_address) { |
110 | dev_err(sp->dev, "Failed to ioremap pci memory\n"); | 109 | dev_err(sp->dev, "Failed to ioremap pci memory\n"); |
111 | result = -ENODEV; | 110 | result = -ENODEV; |
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 6f76573e7c8a..60b0b1a4fb3a 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c | |||
@@ -269,6 +269,16 @@ ioc4_variant(struct ioc4_driver_data *idd) | |||
269 | return IOC4_VARIANT_PCI_RT; | 269 | return IOC4_VARIANT_PCI_RT; |
270 | } | 270 | } |
271 | 271 | ||
272 | static void | ||
273 | ioc4_load_modules(struct work_struct *work) | ||
274 | { | ||
275 | /* arg just has to be freed */ | ||
276 | |||
277 | request_module("sgiioc4"); | ||
278 | |||
279 | kfree(work); | ||
280 | } | ||
281 | |||
272 | /* Adds a new instance of an IOC4 card */ | 282 | /* Adds a new instance of an IOC4 card */ |
273 | static int | 283 | static int |
274 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | 284 | ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) |
@@ -378,6 +388,30 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
378 | } | 388 | } |
379 | mutex_unlock(&ioc4_mutex); | 389 | mutex_unlock(&ioc4_mutex); |
380 | 390 | ||
391 | /* Request sgiioc4 IDE driver on boards that bring that functionality | ||
392 | * off of IOC4. The root filesystem may be hosted on a drive connected | ||
393 | * to IOC4, so we need to make sure the sgiioc4 driver is loaded as it | ||
394 | * won't be picked up by modprobes due to the ioc4 module owning the | ||
395 | * PCI device. | ||
396 | */ | ||
397 | if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { | ||
398 | struct work_struct *work; | ||
399 | work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); | ||
400 | if (!work) { | ||
401 | printk(KERN_WARNING | ||
402 | "%s: IOC4 unable to allocate memory for " | ||
403 | "load of sub-modules.\n", __func__); | ||
404 | } else { | ||
405 | /* Request the module from a work procedure as the | ||
406 | * modprobe goes out to a userland helper and that | ||
407 | * will hang if done directly from ioc4_probe(). | ||
408 | */ | ||
409 | printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); | ||
410 | INIT_WORK(work, ioc4_load_modules); | ||
411 | schedule_work(work); | ||
412 | } | ||
413 | } | ||
414 | |||
381 | return 0; | 415 | return 0; |
382 | 416 | ||
383 | out_misc_region: | 417 | out_misc_region: |
@@ -462,6 +496,8 @@ ioc4_init(void) | |||
462 | static void __devexit | 496 | static void __devexit |
463 | ioc4_exit(void) | 497 | ioc4_exit(void) |
464 | { | 498 | { |
499 | /* Ensure ioc4_load_modules() has completed before exiting */ | ||
500 | flush_scheduled_work(); | ||
465 | pci_unregister_driver(&ioc4_driver); | 501 | pci_unregister_driver(&ioc4_driver); |
466 | } | 502 | } |
467 | 503 | ||
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index e71eba31decb..be5672a98702 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -354,8 +354,7 @@ static int tifm_7xx1_probe(struct pci_dev *dev, | |||
354 | fm->has_ms_pif = tifm_7xx1_has_ms_pif; | 354 | fm->has_ms_pif = tifm_7xx1_has_ms_pif; |
355 | pci_set_drvdata(dev, fm); | 355 | pci_set_drvdata(dev, fm); |
356 | 356 | ||
357 | fm->addr = ioremap(pci_resource_start(dev, 0), | 357 | fm->addr = pci_ioremap_bar(dev, 0); |
358 | pci_resource_len(dev, 0)); | ||
359 | if (!fm->addr) | 358 | if (!fm->addr) |
360 | goto err_out_free; | 359 | goto err_out_free; |
361 | 360 | ||
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index ac2a805ac7ea..8901ecf6e037 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c | |||
@@ -84,7 +84,7 @@ int parport_wait_event (struct parport *port, signed long timeout) | |||
84 | 84 | ||
85 | add_timer (&timer); | 85 | add_timer (&timer); |
86 | ret = down_interruptible (&port->physport->ieee1284.irq); | 86 | ret = down_interruptible (&port->physport->ieee1284.irq); |
87 | if (!del_timer (&timer) && !ret) | 87 | if (!del_timer_sync(&timer) && !ret) |
88 | /* Timed out. */ | 88 | /* Timed out. */ |
89 | ret = 1; | 89 | ret = 1; |
90 | 90 | ||
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c index 956d3e79f6aa..addb87cf44d9 100644 --- a/drivers/rapidio/rio-driver.c +++ b/drivers/rapidio/rio-driver.c | |||
@@ -79,7 +79,6 @@ void rio_dev_put(struct rio_dev *rdev) | |||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * rio_device_probe - Tell if a RIO device structure has a matching RIO device id structure | 81 | * rio_device_probe - Tell if a RIO device structure has a matching RIO device id structure |
82 | * @id: the RIO device id structure to match against | ||
83 | * @dev: the RIO device structure to match against | 82 | * @dev: the RIO device structure to match against |
84 | * | 83 | * |
85 | * return 0 and set rio_dev->driver when drv claims rio_dev, else error | 84 | * return 0 and set rio_dev->driver when drv claims rio_dev, else error |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 165a81843357..4ad831de41ad 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -35,8 +35,8 @@ config RTC_HCTOSYS_DEVICE | |||
35 | default "rtc0" | 35 | default "rtc0" |
36 | help | 36 | help |
37 | The RTC device that will be used to (re)initialize the system | 37 | The RTC device that will be used to (re)initialize the system |
38 | clock, usually rtc0. Initialization is done when the system | 38 | clock, usually rtc0. Initialization is done when the system |
39 | starts up, and when it resumes from a low power state. This | 39 | starts up, and when it resumes from a low power state. This |
40 | device should record time in UTC, since the kernel won't do | 40 | device should record time in UTC, since the kernel won't do |
41 | timezone correction. | 41 | timezone correction. |
42 | 42 | ||
@@ -44,7 +44,7 @@ config RTC_HCTOSYS_DEVICE | |||
44 | functions run, so it must usually be statically linked. | 44 | functions run, so it must usually be statically linked. |
45 | 45 | ||
46 | This clock should be battery-backed, so that it reads the correct | 46 | This clock should be battery-backed, so that it reads the correct |
47 | time when the system boots from a power-off state. Otherwise, your | 47 | time when the system boots from a power-off state. Otherwise, your |
48 | system will need an external clock source (like an NTP server). | 48 | system will need an external clock source (like an NTP server). |
49 | 49 | ||
50 | If the clock you specify here is not battery backed, it may still | 50 | If the clock you specify here is not battery backed, it may still |
@@ -69,8 +69,7 @@ config RTC_INTF_SYSFS | |||
69 | Say yes here if you want to use your RTCs using sysfs interfaces, | 69 | Say yes here if you want to use your RTCs using sysfs interfaces, |
70 | /sys/class/rtc/rtc0 through /sys/.../rtcN. | 70 | /sys/class/rtc/rtc0 through /sys/.../rtcN. |
71 | 71 | ||
72 | This driver can also be built as a module. If so, the module | 72 | If unsure, say Y. |
73 | will be called rtc-sysfs. | ||
74 | 73 | ||
75 | config RTC_INTF_PROC | 74 | config RTC_INTF_PROC |
76 | boolean "/proc/driver/rtc (procfs for rtc0)" | 75 | boolean "/proc/driver/rtc (procfs for rtc0)" |
@@ -78,11 +77,10 @@ config RTC_INTF_PROC | |||
78 | default RTC_CLASS | 77 | default RTC_CLASS |
79 | help | 78 | help |
80 | Say yes here if you want to use your first RTC through the proc | 79 | Say yes here if you want to use your first RTC through the proc |
81 | interface, /proc/driver/rtc. Other RTCs will not be available | 80 | interface, /proc/driver/rtc. Other RTCs will not be available |
82 | through that API. | 81 | through that API. |
83 | 82 | ||
84 | This driver can also be built as a module. If so, the module | 83 | If unsure, say Y. |
85 | will be called rtc-proc. | ||
86 | 84 | ||
87 | config RTC_INTF_DEV | 85 | config RTC_INTF_DEV |
88 | boolean "/dev/rtcN (character devices)" | 86 | boolean "/dev/rtcN (character devices)" |
@@ -90,12 +88,14 @@ config RTC_INTF_DEV | |||
90 | help | 88 | help |
91 | Say yes here if you want to use your RTCs using the /dev | 89 | Say yes here if you want to use your RTCs using the /dev |
92 | interfaces, which "udev" sets up as /dev/rtc0 through | 90 | interfaces, which "udev" sets up as /dev/rtc0 through |
93 | /dev/rtcN. You may want to set up a symbolic link so one | 91 | /dev/rtcN. |
94 | of these can be accessed as /dev/rtc, which is a name | ||
95 | expected by "hwclock" and some other programs. | ||
96 | 92 | ||
97 | This driver can also be built as a module. If so, the module | 93 | You may want to set up a symbolic link so one of these |
98 | will be called rtc-dev. | 94 | can be accessed as /dev/rtc, which is a name |
95 | expected by "hwclock" and some other programs. Recent | ||
96 | versions of "udev" are known to set up the symlink for you. | ||
97 | |||
98 | If unsure, say Y. | ||
99 | 99 | ||
100 | config RTC_INTF_DEV_UIE_EMUL | 100 | config RTC_INTF_DEV_UIE_EMUL |
101 | bool "RTC UIE emulation on dev interface" | 101 | bool "RTC UIE emulation on dev interface" |
@@ -132,14 +132,14 @@ config RTC_DRV_DS1307 | |||
132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" | 132 | tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" |
133 | help | 133 | help |
134 | If you say yes here you get support for various compatible RTC | 134 | If you say yes here you get support for various compatible RTC |
135 | chips (often with battery backup) connected with I2C. This driver | 135 | chips (often with battery backup) connected with I2C. This driver |
136 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, | 136 | should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00, |
137 | and probably other chips. In some cases the RTC must already | 137 | and probably other chips. In some cases the RTC must already |
138 | have been initialized (by manufacturing or a bootloader). | 138 | have been initialized (by manufacturing or a bootloader). |
139 | 139 | ||
140 | The first seven registers on these chips hold an RTC, and other | 140 | The first seven registers on these chips hold an RTC, and other |
141 | registers may add features such as NVRAM, a trickle charger for | 141 | registers may add features such as NVRAM, a trickle charger for |
142 | the RTC/NVRAM backup power, and alarms. NVRAM is visible in | 142 | the RTC/NVRAM backup power, and alarms. NVRAM is visible in |
143 | sysfs, but other chip features may not be available. | 143 | sysfs, but other chip features may not be available. |
144 | 144 | ||
145 | This driver can also be built as a module. If so, the module | 145 | This driver can also be built as a module. If so, the module |
@@ -150,10 +150,10 @@ config RTC_DRV_DS1374 | |||
150 | depends on RTC_CLASS && I2C | 150 | depends on RTC_CLASS && I2C |
151 | help | 151 | help |
152 | If you say yes here you get support for Dallas Semiconductor | 152 | If you say yes here you get support for Dallas Semiconductor |
153 | DS1374 real-time clock chips. If an interrupt is associated | 153 | DS1374 real-time clock chips. If an interrupt is associated |
154 | with the device, the alarm functionality is supported. | 154 | with the device, the alarm functionality is supported. |
155 | 155 | ||
156 | This driver can also be built as a module. If so, the module | 156 | This driver can also be built as a module. If so, the module |
157 | will be called rtc-ds1374. | 157 | will be called rtc-ds1374. |
158 | 158 | ||
159 | config RTC_DRV_DS1672 | 159 | config RTC_DRV_DS1672 |
@@ -247,7 +247,7 @@ config RTC_DRV_TWL92330 | |||
247 | help | 247 | help |
248 | If you say yes here you get support for the RTC on the | 248 | If you say yes here you get support for the RTC on the |
249 | TWL92330 "Menelaus" power management chip, used with OMAP2 | 249 | TWL92330 "Menelaus" power management chip, used with OMAP2 |
250 | platforms. The support is integrated with the rest of | 250 | platforms. The support is integrated with the rest of |
251 | the Menelaus driver; it's not separate module. | 251 | the Menelaus driver; it's not separate module. |
252 | 252 | ||
253 | config RTC_DRV_TWL4030 | 253 | config RTC_DRV_TWL4030 |
@@ -308,7 +308,7 @@ config RTC_DRV_DS1305 | |||
308 | tristate "Dallas/Maxim DS1305/DS1306" | 308 | tristate "Dallas/Maxim DS1305/DS1306" |
309 | help | 309 | help |
310 | Select this driver to get support for the Dallas/Maxim DS1305 | 310 | Select this driver to get support for the Dallas/Maxim DS1305 |
311 | and DS1306 real time clock chips. These support a trickle | 311 | and DS1306 real time clock chips. These support a trickle |
312 | charger, alarms, and NVRAM in addition to the clock. | 312 | charger, alarms, and NVRAM in addition to the clock. |
313 | 313 | ||
314 | This driver can also be built as a module. If so, the module | 314 | This driver can also be built as a module. If so, the module |
@@ -317,7 +317,8 @@ config RTC_DRV_DS1305 | |||
317 | config RTC_DRV_DS1390 | 317 | config RTC_DRV_DS1390 |
318 | tristate "Dallas/Maxim DS1390/93/94" | 318 | tristate "Dallas/Maxim DS1390/93/94" |
319 | help | 319 | help |
320 | If you say yes here you get support for the DS1390/93/94 chips. | 320 | If you say yes here you get support for the |
321 | Dallas/Maxim DS1390/93/94 chips. | ||
321 | 322 | ||
322 | This driver only supports the RTC feature, and not other chip | 323 | This driver only supports the RTC feature, and not other chip |
323 | features such as alarms and trickle charging. | 324 | features such as alarms and trickle charging. |
@@ -381,7 +382,7 @@ config RTC_DRV_CMOS | |||
381 | or LPC bus chips, and so on. | 382 | or LPC bus chips, and so on. |
382 | 383 | ||
383 | Your system will need to define the platform device used by | 384 | Your system will need to define the platform device used by |
384 | this driver, otherwise it won't be accessible. This means | 385 | this driver, otherwise it won't be accessible. This means |
385 | you can safely enable this driver if you don't know whether | 386 | you can safely enable this driver if you don't know whether |
386 | or not your board has this kind of hardware. | 387 | or not your board has this kind of hardware. |
387 | 388 | ||
@@ -598,7 +599,7 @@ config RTC_DRV_AT91RM9200 | |||
598 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL | 599 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL |
599 | help | 600 | help |
600 | Driver for the internal RTC (Realtime Clock) module found on | 601 | Driver for the internal RTC (Realtime Clock) module found on |
601 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips | 602 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips |
602 | this is powered by the backup power supply. | 603 | this is powered by the backup power supply. |
603 | 604 | ||
604 | config RTC_DRV_AT91SAM9 | 605 | config RTC_DRV_AT91SAM9 |
@@ -620,8 +621,8 @@ config RTC_DRV_AT91SAM9_RTT | |||
620 | prompt "RTT module Number" if ARCH_AT91SAM9263 | 621 | prompt "RTT module Number" if ARCH_AT91SAM9263 |
621 | depends on RTC_DRV_AT91SAM9 | 622 | depends on RTC_DRV_AT91SAM9 |
622 | help | 623 | help |
623 | More than one RTT module is available. You can choose which | 624 | More than one RTT module is available. You can choose which |
624 | one will be used as an RTC. The default of zero is normally | 625 | one will be used as an RTC. The default of zero is normally |
625 | OK to use, though some systems use that for non-RTC purposes. | 626 | OK to use, though some systems use that for non-RTC purposes. |
626 | 627 | ||
627 | config RTC_DRV_AT91SAM9_GPBR | 628 | config RTC_DRV_AT91SAM9_GPBR |
@@ -633,10 +634,20 @@ config RTC_DRV_AT91SAM9_GPBR | |||
633 | depends on RTC_DRV_AT91SAM9 | 634 | depends on RTC_DRV_AT91SAM9 |
634 | help | 635 | help |
635 | The RTC driver needs to use one of the General Purpose Backup | 636 | The RTC driver needs to use one of the General Purpose Backup |
636 | Registers (GPBRs) as well as the RTT. You can choose which one | 637 | Registers (GPBRs) as well as the RTT. You can choose which one |
637 | will be used. The default of zero is normally OK to use, but | 638 | will be used. The default of zero is normally OK to use, but |
638 | on some systems other software needs to use that register. | 639 | on some systems other software needs to use that register. |
639 | 640 | ||
641 | config RTC_DRV_AU1XXX | ||
642 | tristate "Au1xxx Counter0 RTC support" | ||
643 | depends on SOC_AU1X00 | ||
644 | help | ||
645 | This is a driver for the Au1xxx on-chip Counter0 (Time-Of-Year | ||
646 | counter) to be used as a RTC. | ||
647 | |||
648 | This driver can also be built as a module. If so, the module | ||
649 | will be called rtc-au1xxx. | ||
650 | |||
640 | config RTC_DRV_BFIN | 651 | config RTC_DRV_BFIN |
641 | tristate "Blackfin On-Chip RTC" | 652 | tristate "Blackfin On-Chip RTC" |
642 | depends on BLACKFIN && !BF561 | 653 | depends on BLACKFIN && !BF561 |
@@ -669,6 +680,17 @@ config RTC_DRV_PPC | |||
669 | the RTC. This exposes that functionality through the generic RTC | 680 | the RTC. This exposes that functionality through the generic RTC |
670 | class. | 681 | class. |
671 | 682 | ||
683 | config RTC_DRV_PXA | ||
684 | tristate "PXA27x/PXA3xx" | ||
685 | depends on ARCH_PXA | ||
686 | help | ||
687 | If you say Y here you will get access to the real time clock | ||
688 | built into your PXA27x or PXA3xx CPU. | ||
689 | |||
690 | This RTC driver uses PXA RTC registers available since pxa27x | ||
691 | series (RDxR, RYxR) instead of legacy RCNR, RTAR. | ||
692 | |||
693 | |||
672 | config RTC_DRV_SUN4V | 694 | config RTC_DRV_SUN4V |
673 | bool "SUN4V Hypervisor RTC" | 695 | bool "SUN4V Hypervisor RTC" |
674 | depends on SPARC64 | 696 | depends on SPARC64 |
@@ -683,4 +705,22 @@ config RTC_DRV_STARFIRE | |||
683 | If you say Y here you will get support for the RTC found on | 705 | If you say Y here you will get support for the RTC found on |
684 | Starfire systems. | 706 | Starfire systems. |
685 | 707 | ||
708 | config RTC_DRV_TX4939 | ||
709 | tristate "TX4939 SoC" | ||
710 | depends on SOC_TX4939 | ||
711 | help | ||
712 | Driver for the internal RTC (Realtime Clock) module found on | ||
713 | Toshiba TX4939 SoC. | ||
714 | |||
715 | config RTC_DRV_MV | ||
716 | tristate "Marvell SoC RTC" | ||
717 | depends on ARCH_KIRKWOOD | ||
718 | help | ||
719 | If you say yes here you will get support for the in-chip RTC | ||
720 | that can be found in some of Marvell's SoC devices, such as | ||
721 | the Kirkwood 88F6281 and 88F6192. | ||
722 | |||
723 | This driver can also be built as a module. If so, the module | ||
724 | will be called rtc-mv. | ||
725 | |||
686 | endif # RTC_CLASS | 726 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6e79c912bf9e..9a4340d48f26 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -20,6 +20,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | 22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o |
23 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o | ||
23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 24 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 25 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 26 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
@@ -47,6 +48,7 @@ obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | |||
47 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o | 48 | obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o |
48 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o | 49 | obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o |
49 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o | 50 | obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o |
51 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | ||
50 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 52 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
51 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 53 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
52 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 54 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
@@ -54,6 +56,7 @@ obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | |||
54 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 56 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
55 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o | 57 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o |
56 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | 58 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o |
59 | obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o | ||
57 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 60 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
58 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 61 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
59 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 62 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
@@ -66,6 +69,7 @@ obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o | |||
66 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o | 69 | obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o |
67 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 70 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
68 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o | 71 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl4030.o |
72 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | ||
69 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 73 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
70 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 74 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
71 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o | 75 | obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 4dfdf019fccc..be5a6b73e601 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -48,9 +48,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
48 | struct rtc_time tm; | 48 | struct rtc_time tm; |
49 | struct timespec ts = current_kernel_time(); | 49 | struct timespec ts = current_kernel_time(); |
50 | 50 | ||
51 | if (strncmp(rtc->dev.bus_id, | 51 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
52 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
53 | BUS_ID_SIZE) != 0) | ||
54 | return 0; | 52 | return 0; |
55 | 53 | ||
56 | rtc_read_time(rtc, &tm); | 54 | rtc_read_time(rtc, &tm); |
@@ -71,20 +69,18 @@ static int rtc_resume(struct device *dev) | |||
71 | time_t newtime; | 69 | time_t newtime; |
72 | struct timespec time; | 70 | struct timespec time; |
73 | 71 | ||
74 | if (strncmp(rtc->dev.bus_id, | 72 | if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) |
75 | CONFIG_RTC_HCTOSYS_DEVICE, | ||
76 | BUS_ID_SIZE) != 0) | ||
77 | return 0; | 73 | return 0; |
78 | 74 | ||
79 | rtc_read_time(rtc, &tm); | 75 | rtc_read_time(rtc, &tm); |
80 | if (rtc_valid_tm(&tm) != 0) { | 76 | if (rtc_valid_tm(&tm) != 0) { |
81 | pr_debug("%s: bogus resume time\n", rtc->dev.bus_id); | 77 | pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); |
82 | return 0; | 78 | return 0; |
83 | } | 79 | } |
84 | rtc_tm_to_time(&tm, &newtime); | 80 | rtc_tm_to_time(&tm, &newtime); |
85 | if (newtime <= oldtime) { | 81 | if (newtime <= oldtime) { |
86 | if (newtime < oldtime) | 82 | if (newtime < oldtime) |
87 | pr_debug("%s: time travel!\n", rtc->dev.bus_id); | 83 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); |
88 | return 0; | 84 | return 0; |
89 | } | 85 | } |
90 | 86 | ||
@@ -156,7 +152,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
156 | init_waitqueue_head(&rtc->irq_queue); | 152 | init_waitqueue_head(&rtc->irq_queue); |
157 | 153 | ||
158 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | 154 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); |
159 | snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); | 155 | dev_set_name(&rtc->dev, "rtc%d", id); |
160 | 156 | ||
161 | rtc_dev_prepare(rtc); | 157 | rtc_dev_prepare(rtc); |
162 | 158 | ||
@@ -169,7 +165,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
169 | rtc_proc_add_device(rtc); | 165 | rtc_proc_add_device(rtc); |
170 | 166 | ||
171 | dev_info(dev, "rtc core: registered %s as %s\n", | 167 | dev_info(dev, "rtc core: registered %s as %s\n", |
172 | rtc->name, rtc->dev.bus_id); | 168 | rtc->name, dev_name(&rtc->dev)); |
173 | 169 | ||
174 | return rtc; | 170 | return rtc; |
175 | 171 | ||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index fd2c652504ff..4348c4b0d453 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -50,10 +50,15 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
50 | 50 | ||
51 | if (!rtc->ops) | 51 | if (!rtc->ops) |
52 | err = -ENODEV; | 52 | err = -ENODEV; |
53 | else if (!rtc->ops->set_time) | 53 | else if (rtc->ops->set_time) |
54 | err = -EINVAL; | ||
55 | else | ||
56 | err = rtc->ops->set_time(rtc->dev.parent, tm); | 54 | err = rtc->ops->set_time(rtc->dev.parent, tm); |
55 | else if (rtc->ops->set_mmss) { | ||
56 | unsigned long secs; | ||
57 | err = rtc_tm_to_time(tm, &secs); | ||
58 | if (err == 0) | ||
59 | err = rtc->ops->set_mmss(rtc->dev.parent, secs); | ||
60 | } else | ||
61 | err = -EINVAL; | ||
57 | 62 | ||
58 | mutex_unlock(&rtc->ops_lock); | 63 | mutex_unlock(&rtc->ops_lock); |
59 | return err; | 64 | return err; |
@@ -389,7 +394,7 @@ static int __rtc_match(struct device *dev, void *data) | |||
389 | { | 394 | { |
390 | char *name = (char *)data; | 395 | char *name = (char *)data; |
391 | 396 | ||
392 | if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) | 397 | if (strcmp(dev_name(dev), name) == 0) |
393 | return 1; | 398 | return 1; |
394 | return 0; | 399 | return 0; |
395 | } | 400 | } |
@@ -504,9 +509,6 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) | |||
504 | if (rtc->ops->irq_set_freq == NULL) | 509 | if (rtc->ops->irq_set_freq == NULL) |
505 | return -ENXIO; | 510 | return -ENXIO; |
506 | 511 | ||
507 | if (!is_power_of_2(freq)) | ||
508 | return -EINVAL; | ||
509 | |||
510 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 512 | spin_lock_irqsave(&rtc->irq_task_lock, flags); |
511 | if (rtc->irq_task != NULL && task == NULL) | 513 | if (rtc->irq_task != NULL && task == NULL) |
512 | err = -EBUSY; | 514 | err = -EBUSY; |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 90b9a6503e15..e1ec33e40e38 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
@@ -205,7 +205,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | |||
205 | { | 205 | { |
206 | struct resource *regs; | 206 | struct resource *regs; |
207 | struct rtc_at32ap700x *rtc; | 207 | struct rtc_at32ap700x *rtc; |
208 | int irq = -1; | 208 | int irq; |
209 | int ret; | 209 | int ret; |
210 | 210 | ||
211 | rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL); | 211 | rtc = kzalloc(sizeof(struct rtc_at32ap700x), GFP_KERNEL); |
@@ -222,7 +222,7 @@ static int __init at32_rtc_probe(struct platform_device *pdev) | |||
222 | } | 222 | } |
223 | 223 | ||
224 | irq = platform_get_irq(pdev, 0); | 224 | irq = platform_get_irq(pdev, 0); |
225 | if (irq < 0) { | 225 | if (irq <= 0) { |
226 | dev_dbg(&pdev->dev, "could not get irq\n"); | 226 | dev_dbg(&pdev->dev, "could not get irq\n"); |
227 | ret = -ENXIO; | 227 | ret = -ENXIO; |
228 | goto out; | 228 | goto out; |
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c new file mode 100644 index 000000000000..8906a688e6a6 --- /dev/null +++ b/drivers/rtc/rtc-au1xxx.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * Au1xxx counter0 (aka Time-Of-Year counter) RTC interface driver. | ||
3 | * | ||
4 | * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | |||
11 | /* All current Au1xxx SoCs have 2 counters fed by an external 32.768 kHz | ||
12 | * crystal. Counter 0, which keeps counting during sleep/powerdown, is | ||
13 | * used to count seconds since the beginning of the unix epoch. | ||
14 | * | ||
15 | * The counters must be configured and enabled by bootloader/board code; | ||
16 | * no checks as to whether they really get a proper 32.768kHz clock are | ||
17 | * made as this would take far too long. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <asm/mach-au1x00/au1000.h> | ||
27 | |||
28 | /* 32kHz clock enabled and detected */ | ||
29 | #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) | ||
30 | |||
31 | static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
32 | { | ||
33 | unsigned long t; | ||
34 | |||
35 | t = au_readl(SYS_TOYREAD); | ||
36 | |||
37 | rtc_time_to_tm(t, tm); | ||
38 | |||
39 | return rtc_valid_tm(tm); | ||
40 | } | ||
41 | |||
42 | static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
43 | { | ||
44 | unsigned long t; | ||
45 | |||
46 | rtc_tm_to_time(tm, &t); | ||
47 | |||
48 | au_writel(t, SYS_TOYWRITE); | ||
49 | au_sync(); | ||
50 | |||
51 | /* wait for the pending register write to succeed. This can | ||
52 | * take up to 6 seconds... | ||
53 | */ | ||
54 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | ||
55 | msleep(1); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static struct rtc_class_ops au1xtoy_rtc_ops = { | ||
61 | .read_time = au1xtoy_rtc_read_time, | ||
62 | .set_time = au1xtoy_rtc_set_time, | ||
63 | }; | ||
64 | |||
65 | static int __devinit au1xtoy_rtc_probe(struct platform_device *pdev) | ||
66 | { | ||
67 | struct rtc_device *rtcdev; | ||
68 | unsigned long t; | ||
69 | int ret; | ||
70 | |||
71 | t = au_readl(SYS_COUNTER_CNTRL); | ||
72 | if (!(t & CNTR_OK)) { | ||
73 | dev_err(&pdev->dev, "counters not working; aborting.\n"); | ||
74 | ret = -ENODEV; | ||
75 | goto out_err; | ||
76 | } | ||
77 | |||
78 | ret = -ETIMEDOUT; | ||
79 | |||
80 | /* set counter0 tickrate to 1Hz if necessary */ | ||
81 | if (au_readl(SYS_TOYTRIM) != 32767) { | ||
82 | /* wait until hardware gives access to TRIM register */ | ||
83 | t = 0x00100000; | ||
84 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && t--) | ||
85 | msleep(1); | ||
86 | |||
87 | if (!t) { | ||
88 | /* timed out waiting for register access; assume | ||
89 | * counters are unusable. | ||
90 | */ | ||
91 | dev_err(&pdev->dev, "timeout waiting for access\n"); | ||
92 | goto out_err; | ||
93 | } | ||
94 | |||
95 | /* set 1Hz TOY tick rate */ | ||
96 | au_writel(32767, SYS_TOYTRIM); | ||
97 | au_sync(); | ||
98 | } | ||
99 | |||
100 | /* wait until the hardware allows writes to the counter reg */ | ||
101 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | ||
102 | msleep(1); | ||
103 | |||
104 | rtcdev = rtc_device_register("rtc-au1xxx", &pdev->dev, | ||
105 | &au1xtoy_rtc_ops, THIS_MODULE); | ||
106 | if (IS_ERR(rtcdev)) { | ||
107 | ret = PTR_ERR(rtcdev); | ||
108 | goto out_err; | ||
109 | } | ||
110 | |||
111 | platform_set_drvdata(pdev, rtcdev); | ||
112 | |||
113 | return 0; | ||
114 | |||
115 | out_err: | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | static int __devexit au1xtoy_rtc_remove(struct platform_device *pdev) | ||
120 | { | ||
121 | struct rtc_device *rtcdev = platform_get_drvdata(pdev); | ||
122 | |||
123 | rtc_device_unregister(rtcdev); | ||
124 | platform_set_drvdata(pdev, NULL); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static struct platform_driver au1xrtc_driver = { | ||
130 | .driver = { | ||
131 | .name = "rtc-au1xxx", | ||
132 | .owner = THIS_MODULE, | ||
133 | }, | ||
134 | .remove = __devexit_p(au1xtoy_rtc_remove), | ||
135 | }; | ||
136 | |||
137 | static int __init au1xtoy_rtc_init(void) | ||
138 | { | ||
139 | return platform_driver_probe(&au1xrtc_driver, au1xtoy_rtc_probe); | ||
140 | } | ||
141 | |||
142 | static void __exit au1xtoy_rtc_exit(void) | ||
143 | { | ||
144 | platform_driver_unregister(&au1xrtc_driver); | ||
145 | } | ||
146 | |||
147 | module_init(au1xtoy_rtc_init); | ||
148 | module_exit(au1xtoy_rtc_exit); | ||
149 | |||
150 | MODULE_DESCRIPTION("Au1xxx TOY-counter-based RTC driver"); | ||
151 | MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); | ||
152 | MODULE_LICENSE("GPL"); | ||
153 | MODULE_ALIAS("platform:rtc-au1xxx"); | ||
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 34439ce3967e..aafd3e6ebb0d 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -390,7 +390,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
390 | 390 | ||
391 | /* Register our RTC with the RTC framework */ | 391 | /* Register our RTC with the RTC framework */ |
392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); | 392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); |
393 | if (unlikely(IS_ERR(rtc))) { | 393 | if (unlikely(IS_ERR(rtc->rtc_dev))) { |
394 | ret = PTR_ERR(rtc->rtc_dev); | 394 | ret = PTR_ERR(rtc->rtc_dev); |
395 | goto err_irq; | 395 | goto err_irq; |
396 | } | 396 | } |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 6cf8e282338f..b6d35f50e404 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | #include <linux/log2.h> | ||
38 | 39 | ||
39 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 40 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
40 | #include <asm-generic/rtc.h> | 41 | #include <asm-generic/rtc.h> |
@@ -58,7 +59,7 @@ struct cmos_rtc { | |||
58 | }; | 59 | }; |
59 | 60 | ||
60 | /* both platform and pnp busses use negative numbers for invalid irqs */ | 61 | /* both platform and pnp busses use negative numbers for invalid irqs */ |
61 | #define is_valid_irq(n) ((n) >= 0) | 62 | #define is_valid_irq(n) ((n) > 0) |
62 | 63 | ||
63 | static const char driver_name[] = "rtc_cmos"; | 64 | static const char driver_name[] = "rtc_cmos"; |
64 | 65 | ||
@@ -384,6 +385,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
384 | if (!is_valid_irq(cmos->irq)) | 385 | if (!is_valid_irq(cmos->irq)) |
385 | return -ENXIO; | 386 | return -ENXIO; |
386 | 387 | ||
388 | if (!is_power_of_2(freq)) | ||
389 | return -EINVAL; | ||
387 | /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ | 390 | /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ |
388 | f = ffs(freq); | 391 | f = ffs(freq); |
389 | if (f-- > 16) | 392 | if (f-- > 16) |
@@ -729,7 +732,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
729 | 732 | ||
730 | cmos_rtc.dev = dev; | 733 | cmos_rtc.dev = dev; |
731 | dev_set_drvdata(dev, &cmos_rtc); | 734 | dev_set_drvdata(dev, &cmos_rtc); |
732 | rename_region(ports, cmos_rtc.rtc->dev.bus_id); | 735 | rename_region(ports, dev_name(&cmos_rtc.rtc->dev)); |
733 | 736 | ||
734 | spin_lock_irq(&rtc_lock); | 737 | spin_lock_irq(&rtc_lock); |
735 | 738 | ||
@@ -777,7 +780,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
777 | rtc_cmos_int_handler = cmos_interrupt; | 780 | rtc_cmos_int_handler = cmos_interrupt; |
778 | 781 | ||
779 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | 782 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, |
780 | IRQF_DISABLED, cmos_rtc.rtc->dev.bus_id, | 783 | IRQF_DISABLED, dev_name(&cmos_rtc.rtc->dev), |
781 | cmos_rtc.rtc); | 784 | cmos_rtc.rtc); |
782 | if (retval < 0) { | 785 | if (retval < 0) { |
783 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 786 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
@@ -795,7 +798,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
795 | } | 798 | } |
796 | 799 | ||
797 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", | 800 | pr_info("%s: alarms up to one %s%s, %zd bytes nvram%s\n", |
798 | cmos_rtc.rtc->dev.bus_id, | 801 | dev_name(&cmos_rtc.rtc->dev), |
799 | is_valid_irq(rtc_irq) | 802 | is_valid_irq(rtc_irq) |
800 | ? (cmos_rtc.mon_alrm | 803 | ? (cmos_rtc.mon_alrm |
801 | ? "year" | 804 | ? "year" |
@@ -885,7 +888,7 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) | |||
885 | } | 888 | } |
886 | 889 | ||
887 | pr_debug("%s: suspend%s, ctrl %02x\n", | 890 | pr_debug("%s: suspend%s, ctrl %02x\n", |
888 | cmos_rtc.rtc->dev.bus_id, | 891 | dev_name(&cmos_rtc.rtc->dev), |
889 | (tmp & RTC_AIE) ? ", alarm may wake" : "", | 892 | (tmp & RTC_AIE) ? ", alarm may wake" : "", |
890 | tmp); | 893 | tmp); |
891 | 894 | ||
@@ -941,7 +944,7 @@ static int cmos_resume(struct device *dev) | |||
941 | } | 944 | } |
942 | 945 | ||
943 | pr_debug("%s: resume, ctrl %02x\n", | 946 | pr_debug("%s: resume, ctrl %02x\n", |
944 | cmos_rtc.rtc->dev.bus_id, | 947 | dev_name(&cmos_rtc.rtc->dev), |
945 | tmp); | 948 | tmp); |
946 | 949 | ||
947 | return 0; | 950 | return 0; |
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 9a234a4ec06d..4aedc705518c 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/bcd.h> | 11 | #include <linux/bcd.h> |
12 | 12 | ||
13 | #define DRV_VERSION "0.1" | 13 | #define DRV_VERSION "0.2" |
14 | 14 | ||
15 | struct ds1216_regs { | 15 | struct ds1216_regs { |
16 | u8 tsec; | 16 | u8 tsec; |
@@ -101,7 +101,8 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
101 | tm->tm_year = bcd2bin(regs.year); | 101 | tm->tm_year = bcd2bin(regs.year); |
102 | if (tm->tm_year < 70) | 102 | if (tm->tm_year < 70) |
103 | tm->tm_year += 100; | 103 | tm->tm_year += 100; |
104 | return 0; | 104 | |
105 | return rtc_valid_tm(tm); | ||
105 | } | 106 | } |
106 | 107 | ||
107 | static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) | 108 | static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) |
@@ -138,9 +139,8 @@ static const struct rtc_class_ops ds1216_rtc_ops = { | |||
138 | .set_time = ds1216_rtc_set_time, | 139 | .set_time = ds1216_rtc_set_time, |
139 | }; | 140 | }; |
140 | 141 | ||
141 | static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | 142 | static int __init ds1216_rtc_probe(struct platform_device *pdev) |
142 | { | 143 | { |
143 | struct rtc_device *rtc; | ||
144 | struct resource *res; | 144 | struct resource *res; |
145 | struct ds1216_priv *priv; | 145 | struct ds1216_priv *priv; |
146 | int ret = 0; | 146 | int ret = 0; |
@@ -152,7 +152,10 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | |||
152 | priv = kzalloc(sizeof *priv, GFP_KERNEL); | 152 | priv = kzalloc(sizeof *priv, GFP_KERNEL); |
153 | if (!priv) | 153 | if (!priv) |
154 | return -ENOMEM; | 154 | return -ENOMEM; |
155 | priv->size = res->end - res->start + 1; | 155 | |
156 | platform_set_drvdata(pdev, priv); | ||
157 | |||
158 | priv->size = resource_size(res); | ||
156 | if (!request_mem_region(res->start, priv->size, pdev->name)) { | 159 | if (!request_mem_region(res->start, priv->size, pdev->name)) { |
157 | ret = -EBUSY; | 160 | ret = -EBUSY; |
158 | goto out; | 161 | goto out; |
@@ -163,22 +166,18 @@ static int __devinit ds1216_rtc_probe(struct platform_device *pdev) | |||
163 | ret = -ENOMEM; | 166 | ret = -ENOMEM; |
164 | goto out; | 167 | goto out; |
165 | } | 168 | } |
166 | rtc = rtc_device_register("ds1216", &pdev->dev, | 169 | priv->rtc = rtc_device_register("ds1216", &pdev->dev, |
167 | &ds1216_rtc_ops, THIS_MODULE); | 170 | &ds1216_rtc_ops, THIS_MODULE); |
168 | if (IS_ERR(rtc)) { | 171 | if (IS_ERR(priv->rtc)) { |
169 | ret = PTR_ERR(rtc); | 172 | ret = PTR_ERR(priv->rtc); |
170 | goto out; | 173 | goto out; |
171 | } | 174 | } |
172 | priv->rtc = rtc; | ||
173 | platform_set_drvdata(pdev, priv); | ||
174 | 175 | ||
175 | /* dummy read to get clock into a known state */ | 176 | /* dummy read to get clock into a known state */ |
176 | ds1216_read(priv->ioaddr, dummy); | 177 | ds1216_read(priv->ioaddr, dummy); |
177 | return 0; | 178 | return 0; |
178 | 179 | ||
179 | out: | 180 | out: |
180 | if (priv->rtc) | ||
181 | rtc_device_unregister(priv->rtc); | ||
182 | if (priv->ioaddr) | 181 | if (priv->ioaddr) |
183 | iounmap(priv->ioaddr); | 182 | iounmap(priv->ioaddr); |
184 | if (priv->baseaddr) | 183 | if (priv->baseaddr) |
@@ -187,7 +186,7 @@ out: | |||
187 | return ret; | 186 | return ret; |
188 | } | 187 | } |
189 | 188 | ||
190 | static int __devexit ds1216_rtc_remove(struct platform_device *pdev) | 189 | static int __exit ds1216_rtc_remove(struct platform_device *pdev) |
191 | { | 190 | { |
192 | struct ds1216_priv *priv = platform_get_drvdata(pdev); | 191 | struct ds1216_priv *priv = platform_get_drvdata(pdev); |
193 | 192 | ||
@@ -203,13 +202,12 @@ static struct platform_driver ds1216_rtc_platform_driver = { | |||
203 | .name = "rtc-ds1216", | 202 | .name = "rtc-ds1216", |
204 | .owner = THIS_MODULE, | 203 | .owner = THIS_MODULE, |
205 | }, | 204 | }, |
206 | .probe = ds1216_rtc_probe, | 205 | .remove = __exit_p(ds1216_rtc_remove), |
207 | .remove = __devexit_p(ds1216_rtc_remove), | ||
208 | }; | 206 | }; |
209 | 207 | ||
210 | static int __init ds1216_rtc_init(void) | 208 | static int __init ds1216_rtc_init(void) |
211 | { | 209 | { |
212 | return platform_driver_register(&ds1216_rtc_platform_driver); | 210 | return platform_driver_probe(&ds1216_rtc_platform_driver, ds1216_rtc_probe); |
213 | } | 211 | } |
214 | 212 | ||
215 | static void __exit ds1216_rtc_exit(void) | 213 | static void __exit ds1216_rtc_exit(void) |
diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 599e976bf014..e54b5c619bdf 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * rtc-ds1390.c -- driver for DS1390/93/94 | 2 | * rtc-ds1390.c -- driver for the Dallas/Maxim DS1390/93/94 SPI RTC |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Mercury IMC Ltd | 4 | * Copyright (C) 2008 Mercury IMC Ltd |
5 | * Written by Mark Jackson <mpfj@mimc.co.uk> | 5 | * Written by Mark Jackson <mpfj@mimc.co.uk> |
@@ -8,11 +8,13 @@ | |||
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | * | 10 | * |
11 | * NOTE : Currently this driver only supports the bare minimum for read | 11 | * NOTE: Currently this driver only supports the bare minimum for read |
12 | * and write the RTC. The extra features provided by the chip family | 12 | * and write the RTC. The extra features provided by the chip family |
13 | * (alarms, trickle charger, different control registers) are unavailable. | 13 | * (alarms, trickle charger, different control registers) are unavailable. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
16 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
17 | #include <linux/rtc.h> | 19 | #include <linux/rtc.h> |
18 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
@@ -42,20 +44,6 @@ struct ds1390 { | |||
42 | u8 txrx_buf[9]; /* cmd + 8 registers */ | 44 | u8 txrx_buf[9]; /* cmd + 8 registers */ |
43 | }; | 45 | }; |
44 | 46 | ||
45 | static void ds1390_set_reg(struct device *dev, unsigned char address, | ||
46 | unsigned char data) | ||
47 | { | ||
48 | struct spi_device *spi = to_spi_device(dev); | ||
49 | struct ds1390 *chip = dev_get_drvdata(dev); | ||
50 | |||
51 | /* Set MSB to indicate write */ | ||
52 | chip->txrx_buf[0] = address | 0x80; | ||
53 | chip->txrx_buf[1] = data; | ||
54 | |||
55 | /* do the i/o */ | ||
56 | spi_write_then_read(spi, chip->txrx_buf, 2, NULL, 0); | ||
57 | } | ||
58 | |||
59 | static int ds1390_get_reg(struct device *dev, unsigned char address, | 47 | static int ds1390_get_reg(struct device *dev, unsigned char address, |
60 | unsigned char *data) | 48 | unsigned char *data) |
61 | { | 49 | { |
@@ -78,7 +66,7 @@ static int ds1390_get_reg(struct device *dev, unsigned char address, | |||
78 | return 0; | 66 | return 0; |
79 | } | 67 | } |
80 | 68 | ||
81 | static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | 69 | static int ds1390_read_time(struct device *dev, struct rtc_time *dt) |
82 | { | 70 | { |
83 | struct spi_device *spi = to_spi_device(dev); | 71 | struct spi_device *spi = to_spi_device(dev); |
84 | struct ds1390 *chip = dev_get_drvdata(dev); | 72 | struct ds1390 *chip = dev_get_drvdata(dev); |
@@ -107,7 +95,7 @@ static int ds1390_get_datetime(struct device *dev, struct rtc_time *dt) | |||
107 | return rtc_valid_tm(dt); | 95 | return rtc_valid_tm(dt); |
108 | } | 96 | } |
109 | 97 | ||
110 | static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | 98 | static int ds1390_set_time(struct device *dev, struct rtc_time *dt) |
111 | { | 99 | { |
112 | struct spi_device *spi = to_spi_device(dev); | 100 | struct spi_device *spi = to_spi_device(dev); |
113 | struct ds1390 *chip = dev_get_drvdata(dev); | 101 | struct ds1390 *chip = dev_get_drvdata(dev); |
@@ -127,16 +115,6 @@ static int ds1390_set_datetime(struct device *dev, struct rtc_time *dt) | |||
127 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); | 115 | return spi_write_then_read(spi, chip->txrx_buf, 8, NULL, 0); |
128 | } | 116 | } |
129 | 117 | ||
130 | static int ds1390_read_time(struct device *dev, struct rtc_time *tm) | ||
131 | { | ||
132 | return ds1390_get_datetime(dev, tm); | ||
133 | } | ||
134 | |||
135 | static int ds1390_set_time(struct device *dev, struct rtc_time *tm) | ||
136 | { | ||
137 | return ds1390_set_datetime(dev, tm); | ||
138 | } | ||
139 | |||
140 | static const struct rtc_class_ops ds1390_rtc_ops = { | 118 | static const struct rtc_class_ops ds1390_rtc_ops = { |
141 | .read_time = ds1390_read_time, | 119 | .read_time = ds1390_read_time, |
142 | .set_time = ds1390_set_time, | 120 | .set_time = ds1390_set_time, |
@@ -149,46 +127,40 @@ static int __devinit ds1390_probe(struct spi_device *spi) | |||
149 | struct ds1390 *chip; | 127 | struct ds1390 *chip; |
150 | int res; | 128 | int res; |
151 | 129 | ||
152 | printk(KERN_DEBUG "DS1390 SPI RTC driver\n"); | ||
153 | |||
154 | rtc = rtc_device_register("ds1390", | ||
155 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
156 | if (IS_ERR(rtc)) { | ||
157 | printk(KERN_ALERT "RTC : unable to register device\n"); | ||
158 | return PTR_ERR(rtc); | ||
159 | } | ||
160 | |||
161 | spi->mode = SPI_MODE_3; | 130 | spi->mode = SPI_MODE_3; |
162 | spi->bits_per_word = 8; | 131 | spi->bits_per_word = 8; |
163 | spi_setup(spi); | 132 | spi_setup(spi); |
164 | 133 | ||
165 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | 134 | chip = kzalloc(sizeof *chip, GFP_KERNEL); |
166 | if (!chip) { | 135 | if (!chip) { |
167 | printk(KERN_ALERT "RTC : unable to allocate device memory\n"); | 136 | dev_err(&spi->dev, "unable to allocate device memory\n"); |
168 | rtc_device_unregister(rtc); | ||
169 | return -ENOMEM; | 137 | return -ENOMEM; |
170 | } | 138 | } |
171 | chip->rtc = rtc; | ||
172 | dev_set_drvdata(&spi->dev, chip); | 139 | dev_set_drvdata(&spi->dev, chip); |
173 | 140 | ||
174 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); | 141 | res = ds1390_get_reg(&spi->dev, DS1390_REG_SECONDS, &tmp); |
175 | if (res) { | 142 | if (res != 0) { |
176 | printk(KERN_ALERT "RTC : unable to read device\n"); | 143 | dev_err(&spi->dev, "unable to read device\n"); |
177 | rtc_device_unregister(rtc); | 144 | kfree(chip); |
178 | return res; | 145 | return res; |
179 | } | 146 | } |
180 | 147 | ||
181 | return 0; | 148 | chip->rtc = rtc_device_register("ds1390", |
149 | &spi->dev, &ds1390_rtc_ops, THIS_MODULE); | ||
150 | if (IS_ERR(chip->rtc)) { | ||
151 | dev_err(&spi->dev, "unable to register device\n"); | ||
152 | res = PTR_ERR(chip->rtc); | ||
153 | kfree(chip); | ||
154 | } | ||
155 | |||
156 | return res; | ||
182 | } | 157 | } |
183 | 158 | ||
184 | static int __devexit ds1390_remove(struct spi_device *spi) | 159 | static int __devexit ds1390_remove(struct spi_device *spi) |
185 | { | 160 | { |
186 | struct ds1390 *chip = platform_get_drvdata(spi); | 161 | struct ds1390 *chip = platform_get_drvdata(spi); |
187 | struct rtc_device *rtc = chip->rtc; | ||
188 | |||
189 | if (rtc) | ||
190 | rtc_device_unregister(rtc); | ||
191 | 162 | ||
163 | rtc_device_unregister(chip->rtc); | ||
192 | kfree(chip); | 164 | kfree(chip); |
193 | 165 | ||
194 | return 0; | 166 | return 0; |
@@ -215,6 +187,6 @@ static __exit void ds1390_exit(void) | |||
215 | } | 187 | } |
216 | module_exit(ds1390_exit); | 188 | module_exit(ds1390_exit); |
217 | 189 | ||
218 | MODULE_DESCRIPTION("DS1390/93/94 SPI RTC driver"); | 190 | MODULE_DESCRIPTION("Dallas/Maxim DS1390/93/94 SPI RTC driver"); |
219 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); | 191 | MODULE_AUTHOR("Mark Jackson <mpfj@mimc.co.uk>"); |
220 | MODULE_LICENSE("GPL"); | 192 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 25caada78398..23a07fe15a2c 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -326,9 +326,9 @@ ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
326 | struct platform_device *pdev = to_platform_device(dev); | 326 | struct platform_device *pdev = to_platform_device(dev); |
327 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 327 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
328 | 328 | ||
329 | if (pdata->irq < 0) { | 329 | if (pdata->irq <= 0) |
330 | return -EINVAL; | 330 | return -EINVAL; |
331 | } | 331 | |
332 | pdata->alrm_mday = alrm->time.tm_mday; | 332 | pdata->alrm_mday = alrm->time.tm_mday; |
333 | pdata->alrm_hour = alrm->time.tm_hour; | 333 | pdata->alrm_hour = alrm->time.tm_hour; |
334 | pdata->alrm_min = alrm->time.tm_min; | 334 | pdata->alrm_min = alrm->time.tm_min; |
@@ -346,9 +346,9 @@ ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
346 | struct platform_device *pdev = to_platform_device(dev); | 346 | struct platform_device *pdev = to_platform_device(dev); |
347 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 347 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
348 | 348 | ||
349 | if (pdata->irq < 0) { | 349 | if (pdata->irq <= 0) |
350 | return -EINVAL; | 350 | return -EINVAL; |
351 | } | 351 | |
352 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 352 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
353 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 353 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
354 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; | 354 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; |
@@ -385,7 +385,7 @@ ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
385 | struct platform_device *pdev = to_platform_device(dev); | 385 | struct platform_device *pdev = to_platform_device(dev); |
386 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 386 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
387 | 387 | ||
388 | if (pdata->irq < 0) { | 388 | if (pdata->irq <= 0) { |
389 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 389 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
390 | } | 390 | } |
391 | switch (cmd) { | 391 | switch (cmd) { |
@@ -503,7 +503,6 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
503 | if (!pdata) { | 503 | if (!pdata) { |
504 | return -ENOMEM; | 504 | return -ENOMEM; |
505 | } | 505 | } |
506 | pdata->irq = -1; | ||
507 | pdata->size = res->end - res->start + 1; | 506 | pdata->size = res->end - res->start + 1; |
508 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { | 507 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { |
509 | ret = -EBUSY; | 508 | ret = -EBUSY; |
@@ -545,13 +544,13 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
545 | * if the platform has an interrupt in mind for this device, | 544 | * if the platform has an interrupt in mind for this device, |
546 | * then by all means, set it | 545 | * then by all means, set it |
547 | */ | 546 | */ |
548 | if (pdata->irq >= 0) { | 547 | if (pdata->irq > 0) { |
549 | rtc_read(RTC_CMD1); | 548 | rtc_read(RTC_CMD1); |
550 | if (request_irq(pdata->irq, ds1511_interrupt, | 549 | if (request_irq(pdata->irq, ds1511_interrupt, |
551 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { | 550 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { |
552 | 551 | ||
553 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 552 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
554 | pdata->irq = -1; | 553 | pdata->irq = 0; |
555 | } | 554 | } |
556 | } | 555 | } |
557 | 556 | ||
@@ -572,7 +571,7 @@ ds1511_rtc_probe(struct platform_device *pdev) | |||
572 | if (pdata->rtc) { | 571 | if (pdata->rtc) { |
573 | rtc_device_unregister(pdata->rtc); | 572 | rtc_device_unregister(pdata->rtc); |
574 | } | 573 | } |
575 | if (pdata->irq >= 0) { | 574 | if (pdata->irq > 0) { |
576 | free_irq(pdata->irq, pdev); | 575 | free_irq(pdata->irq, pdev); |
577 | } | 576 | } |
578 | if (ds1511_base) { | 577 | if (ds1511_base) { |
@@ -595,7 +594,7 @@ ds1511_rtc_remove(struct platform_device *pdev) | |||
595 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | 594 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); |
596 | rtc_device_unregister(pdata->rtc); | 595 | rtc_device_unregister(pdata->rtc); |
597 | pdata->rtc = NULL; | 596 | pdata->rtc = NULL; |
598 | if (pdata->irq >= 0) { | 597 | if (pdata->irq > 0) { |
599 | /* | 598 | /* |
600 | * disable the alarm interrupt | 599 | * disable the alarm interrupt |
601 | */ | 600 | */ |
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index b9475cd20210..38d472b63406 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c | |||
@@ -162,7 +162,7 @@ static int ds1553_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
162 | struct platform_device *pdev = to_platform_device(dev); | 162 | struct platform_device *pdev = to_platform_device(dev); |
163 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 163 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
164 | 164 | ||
165 | if (pdata->irq < 0) | 165 | if (pdata->irq <= 0) |
166 | return -EINVAL; | 166 | return -EINVAL; |
167 | pdata->alrm_mday = alrm->time.tm_mday; | 167 | pdata->alrm_mday = alrm->time.tm_mday; |
168 | pdata->alrm_hour = alrm->time.tm_hour; | 168 | pdata->alrm_hour = alrm->time.tm_hour; |
@@ -179,7 +179,7 @@ static int ds1553_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
179 | struct platform_device *pdev = to_platform_device(dev); | 179 | struct platform_device *pdev = to_platform_device(dev); |
180 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 180 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
181 | 181 | ||
182 | if (pdata->irq < 0) | 182 | if (pdata->irq <= 0) |
183 | return -EINVAL; | 183 | return -EINVAL; |
184 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 184 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
185 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 185 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
@@ -213,7 +213,7 @@ static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
213 | struct platform_device *pdev = to_platform_device(dev); | 213 | struct platform_device *pdev = to_platform_device(dev); |
214 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 214 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
215 | 215 | ||
216 | if (pdata->irq < 0) | 216 | if (pdata->irq <= 0) |
217 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 217 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
218 | switch (cmd) { | 218 | switch (cmd) { |
219 | case RTC_AIE_OFF: | 219 | case RTC_AIE_OFF: |
@@ -301,7 +301,6 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
301 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 301 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
302 | if (!pdata) | 302 | if (!pdata) |
303 | return -ENOMEM; | 303 | return -ENOMEM; |
304 | pdata->irq = -1; | ||
305 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { | 304 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { |
306 | ret = -EBUSY; | 305 | ret = -EBUSY; |
307 | goto out; | 306 | goto out; |
@@ -327,13 +326,13 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
327 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF) | 326 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_BLF) |
328 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | 327 | dev_warn(&pdev->dev, "voltage-low detected.\n"); |
329 | 328 | ||
330 | if (pdata->irq >= 0) { | 329 | if (pdata->irq > 0) { |
331 | writeb(0, ioaddr + RTC_INTERRUPTS); | 330 | writeb(0, ioaddr + RTC_INTERRUPTS); |
332 | if (request_irq(pdata->irq, ds1553_rtc_interrupt, | 331 | if (request_irq(pdata->irq, ds1553_rtc_interrupt, |
333 | IRQF_DISABLED | IRQF_SHARED, | 332 | IRQF_DISABLED | IRQF_SHARED, |
334 | pdev->name, pdev) < 0) { | 333 | pdev->name, pdev) < 0) { |
335 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 334 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
336 | pdata->irq = -1; | 335 | pdata->irq = 0; |
337 | } | 336 | } |
338 | } | 337 | } |
339 | 338 | ||
@@ -353,7 +352,7 @@ static int __devinit ds1553_rtc_probe(struct platform_device *pdev) | |||
353 | out: | 352 | out: |
354 | if (pdata->rtc) | 353 | if (pdata->rtc) |
355 | rtc_device_unregister(pdata->rtc); | 354 | rtc_device_unregister(pdata->rtc); |
356 | if (pdata->irq >= 0) | 355 | if (pdata->irq > 0) |
357 | free_irq(pdata->irq, pdev); | 356 | free_irq(pdata->irq, pdev); |
358 | if (ioaddr) | 357 | if (ioaddr) |
359 | iounmap(ioaddr); | 358 | iounmap(ioaddr); |
@@ -369,7 +368,7 @@ static int __devexit ds1553_rtc_remove(struct platform_device *pdev) | |||
369 | 368 | ||
370 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); | 369 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); |
371 | rtc_device_unregister(pdata->rtc); | 370 | rtc_device_unregister(pdata->rtc); |
372 | if (pdata->irq >= 0) { | 371 | if (pdata->irq > 0) { |
373 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); | 372 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); |
374 | free_irq(pdata->irq, pdev); | 373 | free_irq(pdata->irq, pdev); |
375 | } | 374 | } |
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index 4e91419e8911..06dfb54f99b6 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c | |||
@@ -83,32 +83,11 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) | |||
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | static int ds1672_set_datetime(struct i2c_client *client, struct rtc_time *tm) | ||
87 | { | ||
88 | unsigned long secs; | ||
89 | |||
90 | dev_dbg(&client->dev, | ||
91 | "%s: secs=%d, mins=%d, hours=%d, " | ||
92 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
93 | __func__, | ||
94 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
95 | tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
96 | |||
97 | rtc_tm_to_time(tm, &secs); | ||
98 | |||
99 | return ds1672_set_mmss(client, secs); | ||
100 | } | ||
101 | |||
102 | static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) | 86 | static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) |
103 | { | 87 | { |
104 | return ds1672_get_datetime(to_i2c_client(dev), tm); | 88 | return ds1672_get_datetime(to_i2c_client(dev), tm); |
105 | } | 89 | } |
106 | 90 | ||
107 | static int ds1672_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
108 | { | ||
109 | return ds1672_set_datetime(to_i2c_client(dev), tm); | ||
110 | } | ||
111 | |||
112 | static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) | 91 | static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) |
113 | { | 92 | { |
114 | return ds1672_set_mmss(to_i2c_client(dev), secs); | 93 | return ds1672_set_mmss(to_i2c_client(dev), secs); |
@@ -152,7 +131,6 @@ static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); | |||
152 | 131 | ||
153 | static const struct rtc_class_ops ds1672_rtc_ops = { | 132 | static const struct rtc_class_ops ds1672_rtc_ops = { |
154 | .read_time = ds1672_rtc_read_time, | 133 | .read_time = ds1672_rtc_read_time, |
155 | .set_time = ds1672_rtc_set_time, | ||
156 | .set_mmss = ds1672_rtc_set_mmss, | 134 | .set_mmss = ds1672_rtc_set_mmss, |
157 | }; | 135 | }; |
158 | 136 | ||
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index 45e5b106af73..c51589ede5b7 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* drivers/rtc/rtc-ds3234.c | 1 | /* rtc-ds3234.c |
2 | * | 2 | * |
3 | * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal | 3 | * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal |
4 | * and SRAM. | 4 | * and SRAM. |
@@ -9,13 +9,10 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | * | 11 | * |
12 | * Changelog: | ||
13 | * | ||
14 | * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com> | ||
15 | * - Created based on the max6902 code. Only implements the | ||
16 | * date/time keeping functions; no SRAM yet. | ||
17 | */ | 12 | */ |
18 | 13 | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
19 | #include <linux/device.h> | 16 | #include <linux/device.h> |
20 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
21 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
@@ -34,16 +31,7 @@ | |||
34 | #define DS3234_REG_CONTROL 0x0E | 31 | #define DS3234_REG_CONTROL 0x0E |
35 | #define DS3234_REG_CONT_STAT 0x0F | 32 | #define DS3234_REG_CONT_STAT 0x0F |
36 | 33 | ||
37 | #undef DS3234_DEBUG | 34 | static int ds3234_set_reg(struct device *dev, unsigned char address, |
38 | |||
39 | struct ds3234 { | ||
40 | struct rtc_device *rtc; | ||
41 | u8 buf[8]; /* Burst read: addr + 7 regs */ | ||
42 | u8 tx_buf[2]; | ||
43 | u8 rx_buf[2]; | ||
44 | }; | ||
45 | |||
46 | static void ds3234_set_reg(struct device *dev, unsigned char address, | ||
47 | unsigned char data) | 35 | unsigned char data) |
48 | { | 36 | { |
49 | struct spi_device *spi = to_spi_device(dev); | 37 | struct spi_device *spi = to_spi_device(dev); |
@@ -53,107 +41,45 @@ static void ds3234_set_reg(struct device *dev, unsigned char address, | |||
53 | buf[0] = address | 0x80; | 41 | buf[0] = address | 0x80; |
54 | buf[1] = data; | 42 | buf[1] = data; |
55 | 43 | ||
56 | spi_write(spi, buf, 2); | 44 | return spi_write_then_read(spi, buf, 2, NULL, 0); |
57 | } | 45 | } |
58 | 46 | ||
59 | static int ds3234_get_reg(struct device *dev, unsigned char address, | 47 | static int ds3234_get_reg(struct device *dev, unsigned char address, |
60 | unsigned char *data) | 48 | unsigned char *data) |
61 | { | 49 | { |
62 | struct spi_device *spi = to_spi_device(dev); | 50 | struct spi_device *spi = to_spi_device(dev); |
63 | struct ds3234 *chip = dev_get_drvdata(dev); | ||
64 | struct spi_message message; | ||
65 | struct spi_transfer xfer; | ||
66 | int status; | ||
67 | |||
68 | if (!data) | ||
69 | return -EINVAL; | ||
70 | |||
71 | /* Build our spi message */ | ||
72 | spi_message_init(&message); | ||
73 | memset(&xfer, 0, sizeof(xfer)); | ||
74 | |||
75 | /* Address + dummy tx byte */ | ||
76 | xfer.len = 2; | ||
77 | xfer.tx_buf = chip->tx_buf; | ||
78 | xfer.rx_buf = chip->rx_buf; | ||
79 | |||
80 | chip->tx_buf[0] = address; | ||
81 | chip->tx_buf[1] = 0xff; | ||
82 | 51 | ||
83 | spi_message_add_tail(&xfer, &message); | 52 | *data = address & 0x7f; |
84 | 53 | ||
85 | /* do the i/o */ | 54 | return spi_write_then_read(spi, data, 1, data, 1); |
86 | status = spi_sync(spi, &message); | ||
87 | if (status == 0) | ||
88 | status = message.status; | ||
89 | else | ||
90 | return status; | ||
91 | |||
92 | *data = chip->rx_buf[1]; | ||
93 | |||
94 | return status; | ||
95 | } | 55 | } |
96 | 56 | ||
97 | static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt) | 57 | static int ds3234_read_time(struct device *dev, struct rtc_time *dt) |
98 | { | 58 | { |
59 | int err; | ||
60 | unsigned char buf[8]; | ||
99 | struct spi_device *spi = to_spi_device(dev); | 61 | struct spi_device *spi = to_spi_device(dev); |
100 | struct ds3234 *chip = dev_get_drvdata(dev); | ||
101 | struct spi_message message; | ||
102 | struct spi_transfer xfer; | ||
103 | int status; | ||
104 | |||
105 | /* build the message */ | ||
106 | spi_message_init(&message); | ||
107 | memset(&xfer, 0, sizeof(xfer)); | ||
108 | xfer.len = 1 + 7; /* Addr + 7 registers */ | ||
109 | xfer.tx_buf = chip->buf; | ||
110 | xfer.rx_buf = chip->buf; | ||
111 | chip->buf[0] = 0x00; /* Start address */ | ||
112 | spi_message_add_tail(&xfer, &message); | ||
113 | |||
114 | /* do the i/o */ | ||
115 | status = spi_sync(spi, &message); | ||
116 | if (status == 0) | ||
117 | status = message.status; | ||
118 | else | ||
119 | return status; | ||
120 | 62 | ||
121 | /* Seconds, Minutes, Hours, Day, Date, Month, Year */ | 63 | buf[0] = 0x00; /* Start address */ |
122 | dt->tm_sec = bcd2bin(chip->buf[1]); | ||
123 | dt->tm_min = bcd2bin(chip->buf[2]); | ||
124 | dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f); | ||
125 | dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */ | ||
126 | dt->tm_mday = bcd2bin(chip->buf[5]); | ||
127 | dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */ | ||
128 | dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */ | ||
129 | |||
130 | #ifdef DS3234_DEBUG | ||
131 | dev_dbg(dev, "\n%s : Read RTC values\n", __func__); | ||
132 | dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); | ||
133 | dev_dbg(dev, "tm_min : %i\n", dt->tm_min); | ||
134 | dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); | ||
135 | dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); | ||
136 | dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); | ||
137 | dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); | ||
138 | dev_dbg(dev, "tm_year: %i\n", dt->tm_year); | ||
139 | #endif | ||
140 | 64 | ||
141 | return 0; | 65 | err = spi_write_then_read(spi, buf, 1, buf, 8); |
66 | if (err != 0) | ||
67 | return err; | ||
68 | |||
69 | /* Seconds, Minutes, Hours, Day, Date, Month, Year */ | ||
70 | dt->tm_sec = bcd2bin(buf[0]); | ||
71 | dt->tm_min = bcd2bin(buf[1]); | ||
72 | dt->tm_hour = bcd2bin(buf[2] & 0x3f); | ||
73 | dt->tm_wday = bcd2bin(buf[3]) - 1; /* 0 = Sun */ | ||
74 | dt->tm_mday = bcd2bin(buf[4]); | ||
75 | dt->tm_mon = bcd2bin(buf[5] & 0x1f) - 1; /* 0 = Jan */ | ||
76 | dt->tm_year = bcd2bin(buf[6] & 0xff) + 100; /* Assume 20YY */ | ||
77 | |||
78 | return rtc_valid_tm(dt); | ||
142 | } | 79 | } |
143 | 80 | ||
144 | static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) | 81 | static int ds3234_set_time(struct device *dev, struct rtc_time *dt) |
145 | { | 82 | { |
146 | #ifdef DS3234_DEBUG | ||
147 | dev_dbg(dev, "\n%s : Setting RTC values\n", __func__); | ||
148 | dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec); | ||
149 | dev_dbg(dev, "tm_min : %i\n", dt->tm_min); | ||
150 | dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour); | ||
151 | dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday); | ||
152 | dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday); | ||
153 | dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon); | ||
154 | dev_dbg(dev, "tm_year: %i\n", dt->tm_year); | ||
155 | #endif | ||
156 | |||
157 | ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); | 83 | ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec)); |
158 | ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); | 84 | ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min)); |
159 | ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); | 85 | ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f); |
@@ -174,16 +100,6 @@ static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt) | |||
174 | return 0; | 100 | return 0; |
175 | } | 101 | } |
176 | 102 | ||
177 | static int ds3234_read_time(struct device *dev, struct rtc_time *tm) | ||
178 | { | ||
179 | return ds3234_get_datetime(dev, tm); | ||
180 | } | ||
181 | |||
182 | static int ds3234_set_time(struct device *dev, struct rtc_time *tm) | ||
183 | { | ||
184 | return ds3234_set_datetime(dev, tm); | ||
185 | } | ||
186 | |||
187 | static const struct rtc_class_ops ds3234_rtc_ops = { | 103 | static const struct rtc_class_ops ds3234_rtc_ops = { |
188 | .read_time = ds3234_read_time, | 104 | .read_time = ds3234_read_time, |
189 | .set_time = ds3234_set_time, | 105 | .set_time = ds3234_set_time, |
@@ -193,31 +109,15 @@ static int __devinit ds3234_probe(struct spi_device *spi) | |||
193 | { | 109 | { |
194 | struct rtc_device *rtc; | 110 | struct rtc_device *rtc; |
195 | unsigned char tmp; | 111 | unsigned char tmp; |
196 | struct ds3234 *chip; | ||
197 | int res; | 112 | int res; |
198 | 113 | ||
199 | rtc = rtc_device_register("ds3234", | ||
200 | &spi->dev, &ds3234_rtc_ops, THIS_MODULE); | ||
201 | if (IS_ERR(rtc)) | ||
202 | return PTR_ERR(rtc); | ||
203 | |||
204 | spi->mode = SPI_MODE_3; | 114 | spi->mode = SPI_MODE_3; |
205 | spi->bits_per_word = 8; | 115 | spi->bits_per_word = 8; |
206 | spi_setup(spi); | 116 | spi_setup(spi); |
207 | 117 | ||
208 | chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL); | ||
209 | if (!chip) { | ||
210 | rtc_device_unregister(rtc); | ||
211 | return -ENOMEM; | ||
212 | } | ||
213 | chip->rtc = rtc; | ||
214 | dev_set_drvdata(&spi->dev, chip); | ||
215 | |||
216 | res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); | 118 | res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp); |
217 | if (res) { | 119 | if (res != 0) |
218 | rtc_device_unregister(rtc); | ||
219 | return res; | 120 | return res; |
220 | } | ||
221 | 121 | ||
222 | /* Control settings | 122 | /* Control settings |
223 | * | 123 | * |
@@ -246,26 +146,27 @@ static int __devinit ds3234_probe(struct spi_device *spi) | |||
246 | ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); | 146 | ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp); |
247 | dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); | 147 | dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp); |
248 | 148 | ||
149 | rtc = rtc_device_register("ds3234", | ||
150 | &spi->dev, &ds3234_rtc_ops, THIS_MODULE); | ||
151 | if (IS_ERR(rtc)) | ||
152 | return PTR_ERR(rtc); | ||
153 | |||
154 | dev_set_drvdata(&spi->dev, rtc); | ||
155 | |||
249 | return 0; | 156 | return 0; |
250 | } | 157 | } |
251 | 158 | ||
252 | static int __devexit ds3234_remove(struct spi_device *spi) | 159 | static int __devexit ds3234_remove(struct spi_device *spi) |
253 | { | 160 | { |
254 | struct ds3234 *chip = platform_get_drvdata(spi); | 161 | struct rtc_device *rtc = platform_get_drvdata(spi); |
255 | struct rtc_device *rtc = chip->rtc; | ||
256 | |||
257 | if (rtc) | ||
258 | rtc_device_unregister(rtc); | ||
259 | |||
260 | kfree(chip); | ||
261 | 162 | ||
163 | rtc_device_unregister(rtc); | ||
262 | return 0; | 164 | return 0; |
263 | } | 165 | } |
264 | 166 | ||
265 | static struct spi_driver ds3234_driver = { | 167 | static struct spi_driver ds3234_driver = { |
266 | .driver = { | 168 | .driver = { |
267 | .name = "ds3234", | 169 | .name = "ds3234", |
268 | .bus = &spi_bus_type, | ||
269 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
270 | }, | 171 | }, |
271 | .probe = ds3234_probe, | 172 | .probe = ds3234_probe, |
@@ -274,7 +175,6 @@ static struct spi_driver ds3234_driver = { | |||
274 | 175 | ||
275 | static __init int ds3234_init(void) | 176 | static __init int ds3234_init(void) |
276 | { | 177 | { |
277 | printk(KERN_INFO "DS3234 SPI RTC Driver\n"); | ||
278 | return spi_register_driver(&ds3234_driver); | 178 | return spi_register_driver(&ds3234_driver); |
279 | } | 179 | } |
280 | module_init(ds3234_init); | 180 | module_init(ds3234_init); |
diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 36e4ac0bd69c..f7a3283dd029 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c | |||
@@ -49,18 +49,6 @@ static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) | |||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | 51 | ||
52 | static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
53 | { | ||
54 | int err; | ||
55 | unsigned long secs; | ||
56 | |||
57 | err = rtc_tm_to_time(tm, &secs); | ||
58 | if (err != 0) | ||
59 | return err; | ||
60 | |||
61 | return ep93xx_rtc_set_mmss(dev, secs); | ||
62 | } | ||
63 | |||
64 | static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | 52 | static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) |
65 | { | 53 | { |
66 | unsigned short preload, delete; | 54 | unsigned short preload, delete; |
@@ -75,7 +63,6 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) | |||
75 | 63 | ||
76 | static const struct rtc_class_ops ep93xx_rtc_ops = { | 64 | static const struct rtc_class_ops ep93xx_rtc_ops = { |
77 | .read_time = ep93xx_rtc_read_time, | 65 | .read_time = ep93xx_rtc_read_time, |
78 | .set_time = ep93xx_rtc_set_time, | ||
79 | .set_mmss = ep93xx_rtc_set_mmss, | 66 | .set_mmss = ep93xx_rtc_set_mmss, |
80 | .proc = ep93xx_rtc_proc, | 67 | .proc = ep93xx_rtc_proc, |
81 | }; | 68 | }; |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 43afb7ab5289..33921a6b1707 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -450,7 +450,7 @@ static int __devinit m48t59_rtc_probe(struct platform_device *pdev) | |||
450 | * the mode without IRQ. | 450 | * the mode without IRQ. |
451 | */ | 451 | */ |
452 | m48t59->irq = platform_get_irq(pdev, 0); | 452 | m48t59->irq = platform_get_irq(pdev, 0); |
453 | if (m48t59->irq < 0) | 453 | if (m48t59->irq <= 0) |
454 | m48t59->irq = NO_IRQ; | 454 | m48t59->irq = NO_IRQ; |
455 | 455 | ||
456 | if (m48t59->irq != NO_IRQ) { | 456 | if (m48t59->irq != NO_IRQ) { |
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 2f6507df7b49..36a8ea9ed8ba 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c | |||
@@ -9,14 +9,6 @@ | |||
9 | * | 9 | * |
10 | * Driver for MAX6902 spi RTC | 10 | * Driver for MAX6902 spi RTC |
11 | * | 11 | * |
12 | * Changelog: | ||
13 | * | ||
14 | * 24-May-2006: Raphael Assenat <raph@8d.com> | ||
15 | * - Major rework | ||
16 | * Converted to rtc_device and uses the SPI layer. | ||
17 | * | ||
18 | * ??-???-2005: Someone at Compulab | ||
19 | * - Initial driver creation. | ||
20 | */ | 12 | */ |
21 | 13 | ||
22 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -26,7 +18,6 @@ | |||
26 | #include <linux/rtc.h> | 18 | #include <linux/rtc.h> |
27 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
28 | #include <linux/bcd.h> | 20 | #include <linux/bcd.h> |
29 | #include <linux/delay.h> | ||
30 | 21 | ||
31 | #define MAX6902_REG_SECONDS 0x01 | 22 | #define MAX6902_REG_SECONDS 0x01 |
32 | #define MAX6902_REG_MINUTES 0x03 | 23 | #define MAX6902_REG_MINUTES 0x03 |
@@ -38,16 +29,7 @@ | |||
38 | #define MAX6902_REG_CONTROL 0x0F | 29 | #define MAX6902_REG_CONTROL 0x0F |
39 | #define MAX6902_REG_CENTURY 0x13 | 30 | #define MAX6902_REG_CENTURY 0x13 |
40 | 31 | ||
41 | #undef MAX6902_DEBUG | 32 | static int max6902_set_reg(struct device *dev, unsigned char address, |
42 | |||
43 | struct max6902 { | ||
44 | struct rtc_device *rtc; | ||
45 | u8 buf[9]; /* Burst read cmd + 8 registers */ | ||
46 | u8 tx_buf[2]; | ||
47 | u8 rx_buf[2]; | ||
48 | }; | ||
49 | |||
50 | static void max6902_set_reg(struct device *dev, unsigned char address, | ||
51 | unsigned char data) | 33 | unsigned char data) |
52 | { | 34 | { |
53 | struct spi_device *spi = to_spi_device(dev); | 35 | struct spi_device *spi = to_spi_device(dev); |
@@ -57,113 +39,58 @@ static void max6902_set_reg(struct device *dev, unsigned char address, | |||
57 | buf[0] = address & 0x7f; | 39 | buf[0] = address & 0x7f; |
58 | buf[1] = data; | 40 | buf[1] = data; |
59 | 41 | ||
60 | spi_write(spi, buf, 2); | 42 | return spi_write_then_read(spi, buf, 2, NULL, 0); |
61 | } | 43 | } |
62 | 44 | ||
63 | static int max6902_get_reg(struct device *dev, unsigned char address, | 45 | static int max6902_get_reg(struct device *dev, unsigned char address, |
64 | unsigned char *data) | 46 | unsigned char *data) |
65 | { | 47 | { |
66 | struct spi_device *spi = to_spi_device(dev); | 48 | struct spi_device *spi = to_spi_device(dev); |
67 | struct max6902 *chip = dev_get_drvdata(dev); | ||
68 | struct spi_message message; | ||
69 | struct spi_transfer xfer; | ||
70 | int status; | ||
71 | |||
72 | if (!data) | ||
73 | return -EINVAL; | ||
74 | |||
75 | /* Build our spi message */ | ||
76 | spi_message_init(&message); | ||
77 | memset(&xfer, 0, sizeof(xfer)); | ||
78 | xfer.len = 2; | ||
79 | /* Can tx_buf and rx_buf be equal? The doc in spi.h is not sure... */ | ||
80 | xfer.tx_buf = chip->tx_buf; | ||
81 | xfer.rx_buf = chip->rx_buf; | ||
82 | 49 | ||
83 | /* Set MSB to indicate read */ | 50 | /* Set MSB to indicate read */ |
84 | chip->tx_buf[0] = address | 0x80; | 51 | *data = address | 0x80; |
85 | |||
86 | spi_message_add_tail(&xfer, &message); | ||
87 | 52 | ||
88 | /* do the i/o */ | 53 | return spi_write_then_read(spi, data, 1, data, 1); |
89 | status = spi_sync(spi, &message); | ||
90 | |||
91 | if (status == 0) | ||
92 | *data = chip->rx_buf[1]; | ||
93 | return status; | ||
94 | } | 54 | } |
95 | 55 | ||
96 | static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) | 56 | static int max6902_read_time(struct device *dev, struct rtc_time *dt) |
97 | { | 57 | { |
98 | unsigned char tmp; | 58 | int err, century; |
99 | int century; | ||
100 | int err; | ||
101 | struct spi_device *spi = to_spi_device(dev); | 59 | struct spi_device *spi = to_spi_device(dev); |
102 | struct max6902 *chip = dev_get_drvdata(dev); | 60 | unsigned char buf[8]; |
103 | struct spi_message message; | ||
104 | struct spi_transfer xfer; | ||
105 | int status; | ||
106 | 61 | ||
107 | err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &tmp); | 62 | buf[0] = 0xbf; /* Burst read */ |
108 | if (err) | ||
109 | return err; | ||
110 | |||
111 | /* build the message */ | ||
112 | spi_message_init(&message); | ||
113 | memset(&xfer, 0, sizeof(xfer)); | ||
114 | xfer.len = 1 + 7; /* Burst read command + 7 registers */ | ||
115 | xfer.tx_buf = chip->buf; | ||
116 | xfer.rx_buf = chip->buf; | ||
117 | chip->buf[0] = 0xbf; /* Burst read */ | ||
118 | spi_message_add_tail(&xfer, &message); | ||
119 | 63 | ||
120 | /* do the i/o */ | 64 | err = spi_write_then_read(spi, buf, 1, buf, 8); |
121 | status = spi_sync(spi, &message); | 65 | if (err != 0) |
122 | if (status) | 66 | return err; |
123 | return status; | ||
124 | 67 | ||
125 | /* The chip sends data in this order: | 68 | /* The chip sends data in this order: |
126 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ | 69 | * Seconds, Minutes, Hours, Date, Month, Day, Year */ |
127 | dt->tm_sec = bcd2bin(chip->buf[1]); | 70 | dt->tm_sec = bcd2bin(buf[0]); |
128 | dt->tm_min = bcd2bin(chip->buf[2]); | 71 | dt->tm_min = bcd2bin(buf[1]); |
129 | dt->tm_hour = bcd2bin(chip->buf[3]); | 72 | dt->tm_hour = bcd2bin(buf[2]); |
130 | dt->tm_mday = bcd2bin(chip->buf[4]); | 73 | dt->tm_mday = bcd2bin(buf[3]); |
131 | dt->tm_mon = bcd2bin(chip->buf[5]) - 1; | 74 | dt->tm_mon = bcd2bin(buf[4]) - 1; |
132 | dt->tm_wday = bcd2bin(chip->buf[6]); | 75 | dt->tm_wday = bcd2bin(buf[5]); |
133 | dt->tm_year = bcd2bin(chip->buf[7]); | 76 | dt->tm_year = bcd2bin(buf[6]); |
77 | |||
78 | /* Read century */ | ||
79 | err = max6902_get_reg(dev, MAX6902_REG_CENTURY, &buf[0]); | ||
80 | if (err != 0) | ||
81 | return err; | ||
134 | 82 | ||
135 | century = bcd2bin(tmp) * 100; | 83 | century = bcd2bin(buf[0]) * 100; |
136 | 84 | ||
137 | dt->tm_year += century; | 85 | dt->tm_year += century; |
138 | dt->tm_year -= 1900; | 86 | dt->tm_year -= 1900; |
139 | 87 | ||
140 | #ifdef MAX6902_DEBUG | 88 | return rtc_valid_tm(dt); |
141 | printk("\n%s : Read RTC values\n",__func__); | ||
142 | printk("tm_hour: %i\n",dt->tm_hour); | ||
143 | printk("tm_min : %i\n",dt->tm_min); | ||
144 | printk("tm_sec : %i\n",dt->tm_sec); | ||
145 | printk("tm_year: %i\n",dt->tm_year); | ||
146 | printk("tm_mon : %i\n",dt->tm_mon); | ||
147 | printk("tm_mday: %i\n",dt->tm_mday); | ||
148 | printk("tm_wday: %i\n",dt->tm_wday); | ||
149 | #endif | ||
150 | |||
151 | return 0; | ||
152 | } | 89 | } |
153 | 90 | ||
154 | static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | 91 | static int max6902_set_time(struct device *dev, struct rtc_time *dt) |
155 | { | 92 | { |
156 | dt->tm_year = dt->tm_year+1900; | 93 | dt->tm_year = dt->tm_year + 1900; |
157 | |||
158 | #ifdef MAX6902_DEBUG | ||
159 | printk("\n%s : Setting RTC values\n",__func__); | ||
160 | printk("tm_sec : %i\n",dt->tm_sec); | ||
161 | printk("tm_min : %i\n",dt->tm_min); | ||
162 | printk("tm_hour: %i\n",dt->tm_hour); | ||
163 | printk("tm_mday: %i\n",dt->tm_mday); | ||
164 | printk("tm_wday: %i\n",dt->tm_wday); | ||
165 | printk("tm_year: %i\n",dt->tm_year); | ||
166 | #endif | ||
167 | 94 | ||
168 | /* Remove write protection */ | 95 | /* Remove write protection */ |
169 | max6902_set_reg(dev, 0xF, 0); | 96 | max6902_set_reg(dev, 0xF, 0); |
@@ -173,10 +100,10 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
173 | max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); | 100 | max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour)); |
174 | 101 | ||
175 | max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); | 102 | max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday)); |
176 | max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon+1)); | 103 | max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon + 1)); |
177 | max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); | 104 | max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday)); |
178 | max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year%100)); | 105 | max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year % 100)); |
179 | max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year/100)); | 106 | max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year / 100)); |
180 | 107 | ||
181 | /* Compulab used a delay here. However, the datasheet | 108 | /* Compulab used a delay here. However, the datasheet |
182 | * does not mention a delay being required anywhere... */ | 109 | * does not mention a delay being required anywhere... */ |
@@ -188,16 +115,6 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt) | |||
188 | return 0; | 115 | return 0; |
189 | } | 116 | } |
190 | 117 | ||
191 | static int max6902_read_time(struct device *dev, struct rtc_time *tm) | ||
192 | { | ||
193 | return max6902_get_datetime(dev, tm); | ||
194 | } | ||
195 | |||
196 | static int max6902_set_time(struct device *dev, struct rtc_time *tm) | ||
197 | { | ||
198 | return max6902_set_datetime(dev, tm); | ||
199 | } | ||
200 | |||
201 | static const struct rtc_class_ops max6902_rtc_ops = { | 118 | static const struct rtc_class_ops max6902_rtc_ops = { |
202 | .read_time = max6902_read_time, | 119 | .read_time = max6902_read_time, |
203 | .set_time = max6902_set_time, | 120 | .set_time = max6902_set_time, |
@@ -207,45 +124,29 @@ static int __devinit max6902_probe(struct spi_device *spi) | |||
207 | { | 124 | { |
208 | struct rtc_device *rtc; | 125 | struct rtc_device *rtc; |
209 | unsigned char tmp; | 126 | unsigned char tmp; |
210 | struct max6902 *chip; | ||
211 | int res; | 127 | int res; |
212 | 128 | ||
213 | rtc = rtc_device_register("max6902", | ||
214 | &spi->dev, &max6902_rtc_ops, THIS_MODULE); | ||
215 | if (IS_ERR(rtc)) | ||
216 | return PTR_ERR(rtc); | ||
217 | |||
218 | spi->mode = SPI_MODE_3; | 129 | spi->mode = SPI_MODE_3; |
219 | spi->bits_per_word = 8; | 130 | spi->bits_per_word = 8; |
220 | spi_setup(spi); | 131 | spi_setup(spi); |
221 | 132 | ||
222 | chip = kzalloc(sizeof *chip, GFP_KERNEL); | ||
223 | if (!chip) { | ||
224 | rtc_device_unregister(rtc); | ||
225 | return -ENOMEM; | ||
226 | } | ||
227 | chip->rtc = rtc; | ||
228 | dev_set_drvdata(&spi->dev, chip); | ||
229 | |||
230 | res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); | 133 | res = max6902_get_reg(&spi->dev, MAX6902_REG_SECONDS, &tmp); |
231 | if (res) { | 134 | if (res != 0) |
232 | rtc_device_unregister(rtc); | ||
233 | return res; | 135 | return res; |
234 | } | 136 | |
137 | rtc = rtc_device_register("max6902", | ||
138 | &spi->dev, &max6902_rtc_ops, THIS_MODULE); | ||
139 | if (IS_ERR(rtc)) | ||
140 | return PTR_ERR(rtc); | ||
235 | 141 | ||
236 | return 0; | 142 | return 0; |
237 | } | 143 | } |
238 | 144 | ||
239 | static int __devexit max6902_remove(struct spi_device *spi) | 145 | static int __devexit max6902_remove(struct spi_device *spi) |
240 | { | 146 | { |
241 | struct max6902 *chip = platform_get_drvdata(spi); | 147 | struct rtc_device *rtc = platform_get_drvdata(spi); |
242 | struct rtc_device *rtc = chip->rtc; | ||
243 | |||
244 | if (rtc) | ||
245 | rtc_device_unregister(rtc); | ||
246 | |||
247 | kfree(chip); | ||
248 | 148 | ||
149 | rtc_device_unregister(rtc); | ||
249 | return 0; | 150 | return 0; |
250 | } | 151 | } |
251 | 152 | ||
@@ -261,7 +162,6 @@ static struct spi_driver max6902_driver = { | |||
261 | 162 | ||
262 | static __init int max6902_init(void) | 163 | static __init int max6902_init(void) |
263 | { | 164 | { |
264 | printk("max6902 spi driver\n"); | ||
265 | return spi_register_driver(&max6902_driver); | 165 | return spi_register_driver(&max6902_driver); |
266 | } | 166 | } |
267 | module_init(max6902_init); | 167 | module_init(max6902_init); |
diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c new file mode 100644 index 000000000000..45f12dcd3716 --- /dev/null +++ b/drivers/rtc/rtc-mv.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Driver for the RTC in Marvell SoCs. | ||
3 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | ||
5 | * License version 2. This program is licensed "as is" without any | ||
6 | * warranty of any kind, whether express or implied. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/rtc.h> | ||
12 | #include <linux/bcd.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | |||
17 | #define RTC_TIME_REG_OFFS 0 | ||
18 | #define RTC_SECONDS_OFFS 0 | ||
19 | #define RTC_MINUTES_OFFS 8 | ||
20 | #define RTC_HOURS_OFFS 16 | ||
21 | #define RTC_WDAY_OFFS 24 | ||
22 | #define RTC_HOURS_12H_MODE (1 << 22) /* 12 hours mode */ | ||
23 | |||
24 | #define RTC_DATE_REG_OFFS 4 | ||
25 | #define RTC_MDAY_OFFS 0 | ||
26 | #define RTC_MONTH_OFFS 8 | ||
27 | #define RTC_YEAR_OFFS 16 | ||
28 | |||
29 | |||
30 | struct rtc_plat_data { | ||
31 | struct rtc_device *rtc; | ||
32 | void __iomem *ioaddr; | ||
33 | }; | ||
34 | |||
35 | static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
36 | { | ||
37 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
38 | void __iomem *ioaddr = pdata->ioaddr; | ||
39 | u32 rtc_reg; | ||
40 | |||
41 | rtc_reg = (bin2bcd(tm->tm_sec) << RTC_SECONDS_OFFS) | | ||
42 | (bin2bcd(tm->tm_min) << RTC_MINUTES_OFFS) | | ||
43 | (bin2bcd(tm->tm_hour) << RTC_HOURS_OFFS) | | ||
44 | (bin2bcd(tm->tm_wday) << RTC_WDAY_OFFS); | ||
45 | writel(rtc_reg, ioaddr + RTC_TIME_REG_OFFS); | ||
46 | |||
47 | rtc_reg = (bin2bcd(tm->tm_mday) << RTC_MDAY_OFFS) | | ||
48 | (bin2bcd(tm->tm_mon + 1) << RTC_MONTH_OFFS) | | ||
49 | (bin2bcd(tm->tm_year % 100) << RTC_YEAR_OFFS); | ||
50 | writel(rtc_reg, ioaddr + RTC_DATE_REG_OFFS); | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
56 | { | ||
57 | struct rtc_plat_data *pdata = dev_get_drvdata(dev); | ||
58 | void __iomem *ioaddr = pdata->ioaddr; | ||
59 | u32 rtc_time, rtc_date; | ||
60 | unsigned int year, month, day, hour, minute, second, wday; | ||
61 | |||
62 | rtc_time = readl(ioaddr + RTC_TIME_REG_OFFS); | ||
63 | rtc_date = readl(ioaddr + RTC_DATE_REG_OFFS); | ||
64 | |||
65 | second = rtc_time & 0x7f; | ||
66 | minute = (rtc_time >> RTC_MINUTES_OFFS) & 0x7f; | ||
67 | hour = (rtc_time >> RTC_HOURS_OFFS) & 0x3f; /* assume 24 hours mode */ | ||
68 | wday = (rtc_time >> RTC_WDAY_OFFS) & 0x7; | ||
69 | |||
70 | day = rtc_date & 0x3f; | ||
71 | month = (rtc_date >> RTC_MONTH_OFFS) & 0x3f; | ||
72 | year = (rtc_date >> RTC_YEAR_OFFS) & 0xff; | ||
73 | |||
74 | tm->tm_sec = bcd2bin(second); | ||
75 | tm->tm_min = bcd2bin(minute); | ||
76 | tm->tm_hour = bcd2bin(hour); | ||
77 | tm->tm_mday = bcd2bin(day); | ||
78 | tm->tm_wday = bcd2bin(wday); | ||
79 | tm->tm_mon = bcd2bin(month) - 1; | ||
80 | /* hw counts from year 2000, but tm_year is relative to 1900 */ | ||
81 | tm->tm_year = bcd2bin(year) + 100; | ||
82 | |||
83 | return rtc_valid_tm(tm); | ||
84 | } | ||
85 | |||
86 | static const struct rtc_class_ops mv_rtc_ops = { | ||
87 | .read_time = mv_rtc_read_time, | ||
88 | .set_time = mv_rtc_set_time, | ||
89 | }; | ||
90 | |||
91 | static int __init mv_rtc_probe(struct platform_device *pdev) | ||
92 | { | ||
93 | struct resource *res; | ||
94 | struct rtc_plat_data *pdata; | ||
95 | resource_size_t size; | ||
96 | u32 rtc_time; | ||
97 | |||
98 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
99 | if (!res) | ||
100 | return -ENODEV; | ||
101 | |||
102 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
103 | if (!pdata) | ||
104 | return -ENOMEM; | ||
105 | |||
106 | size = resource_size(res); | ||
107 | if (!devm_request_mem_region(&pdev->dev, res->start, size, | ||
108 | pdev->name)) | ||
109 | return -EBUSY; | ||
110 | |||
111 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, size); | ||
112 | if (!pdata->ioaddr) | ||
113 | return -ENOMEM; | ||
114 | |||
115 | /* make sure the 24 hours mode is enabled */ | ||
116 | rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); | ||
117 | if (rtc_time & RTC_HOURS_12H_MODE) { | ||
118 | dev_err(&pdev->dev, "24 Hours mode not supported.\n"); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | platform_set_drvdata(pdev, pdata); | ||
123 | pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
124 | &mv_rtc_ops, THIS_MODULE); | ||
125 | if (IS_ERR(pdata->rtc)) | ||
126 | return PTR_ERR(pdata->rtc); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int __exit mv_rtc_remove(struct platform_device *pdev) | ||
132 | { | ||
133 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
134 | |||
135 | rtc_device_unregister(pdata->rtc); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static struct platform_driver mv_rtc_driver = { | ||
140 | .remove = __exit_p(mv_rtc_remove), | ||
141 | .driver = { | ||
142 | .name = "rtc-mv", | ||
143 | .owner = THIS_MODULE, | ||
144 | }, | ||
145 | }; | ||
146 | |||
147 | static __init int mv_init(void) | ||
148 | { | ||
149 | return platform_driver_probe(&mv_rtc_driver, mv_rtc_probe); | ||
150 | } | ||
151 | |||
152 | static __exit void mv_exit(void) | ||
153 | { | ||
154 | platform_driver_unregister(&mv_rtc_driver); | ||
155 | } | ||
156 | |||
157 | module_init(mv_init); | ||
158 | module_exit(mv_exit); | ||
159 | |||
160 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>"); | ||
161 | MODULE_DESCRIPTION("Marvell RTC driver"); | ||
162 | MODULE_LICENSE("GPL"); | ||
163 | MODULE_ALIAS("platform:rtc-mv"); | ||
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c new file mode 100644 index 000000000000..cc7eb8767b82 --- /dev/null +++ b/drivers/rtc/rtc-pxa.c | |||
@@ -0,0 +1,489 @@ | |||
1 | /* | ||
2 | * Real Time Clock interface for XScale PXA27x and PXA3xx | ||
3 | * | ||
4 | * Copyright (C) 2008 Robert Jarzmik | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/init.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/rtc.h> | ||
26 | #include <linux/seq_file.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/io.h> | ||
29 | |||
30 | #define TIMER_FREQ CLOCK_TICK_RATE | ||
31 | #define RTC_DEF_DIVIDER (32768 - 1) | ||
32 | #define RTC_DEF_TRIM 0 | ||
33 | #define MAXFREQ_PERIODIC 1000 | ||
34 | |||
35 | /* | ||
36 | * PXA Registers and bits definitions | ||
37 | */ | ||
38 | #define RTSR_PICE (1 << 15) /* Periodic interrupt count enable */ | ||
39 | #define RTSR_PIALE (1 << 14) /* Periodic interrupt Alarm enable */ | ||
40 | #define RTSR_PIAL (1 << 13) /* Periodic interrupt detected */ | ||
41 | #define RTSR_SWALE2 (1 << 11) /* RTC stopwatch alarm2 enable */ | ||
42 | #define RTSR_SWAL2 (1 << 10) /* RTC stopwatch alarm2 detected */ | ||
43 | #define RTSR_SWALE1 (1 << 9) /* RTC stopwatch alarm1 enable */ | ||
44 | #define RTSR_SWAL1 (1 << 8) /* RTC stopwatch alarm1 detected */ | ||
45 | #define RTSR_RDALE2 (1 << 7) /* RTC alarm2 enable */ | ||
46 | #define RTSR_RDAL2 (1 << 6) /* RTC alarm2 detected */ | ||
47 | #define RTSR_RDALE1 (1 << 5) /* RTC alarm1 enable */ | ||
48 | #define RTSR_RDAL1 (1 << 4) /* RTC alarm1 detected */ | ||
49 | #define RTSR_HZE (1 << 3) /* HZ interrupt enable */ | ||
50 | #define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */ | ||
51 | #define RTSR_HZ (1 << 1) /* HZ rising-edge detected */ | ||
52 | #define RTSR_AL (1 << 0) /* RTC alarm detected */ | ||
53 | #define RTSR_TRIG_MASK (RTSR_AL | RTSR_HZ | RTSR_RDAL1 | RTSR_RDAL2\ | ||
54 | | RTSR_SWAL1 | RTSR_SWAL2) | ||
55 | #define RYxR_YEAR_S 9 | ||
56 | #define RYxR_YEAR_MASK (0xfff << RYxR_YEAR_S) | ||
57 | #define RYxR_MONTH_S 5 | ||
58 | #define RYxR_MONTH_MASK (0xf << RYxR_MONTH_S) | ||
59 | #define RYxR_DAY_MASK 0x1f | ||
60 | #define RDxR_HOUR_S 12 | ||
61 | #define RDxR_HOUR_MASK (0x1f << RDxR_HOUR_S) | ||
62 | #define RDxR_MIN_S 6 | ||
63 | #define RDxR_MIN_MASK (0x3f << RDxR_MIN_S) | ||
64 | #define RDxR_SEC_MASK 0x3f | ||
65 | |||
66 | #define RTSR 0x08 | ||
67 | #define RTTR 0x0c | ||
68 | #define RDCR 0x10 | ||
69 | #define RYCR 0x14 | ||
70 | #define RDAR1 0x18 | ||
71 | #define RYAR1 0x1c | ||
72 | #define RTCPICR 0x34 | ||
73 | #define PIAR 0x38 | ||
74 | |||
75 | #define rtc_readl(pxa_rtc, reg) \ | ||
76 | __raw_readl((pxa_rtc)->base + (reg)) | ||
77 | #define rtc_writel(pxa_rtc, reg, value) \ | ||
78 | __raw_writel((value), (pxa_rtc)->base + (reg)) | ||
79 | |||
80 | struct pxa_rtc { | ||
81 | struct resource *ress; | ||
82 | void __iomem *base; | ||
83 | int irq_1Hz; | ||
84 | int irq_Alrm; | ||
85 | struct rtc_device *rtc; | ||
86 | spinlock_t lock; /* Protects this structure */ | ||
87 | struct rtc_time rtc_alarm; | ||
88 | }; | ||
89 | |||
90 | static u32 ryxr_calc(struct rtc_time *tm) | ||
91 | { | ||
92 | return ((tm->tm_year + 1900) << RYxR_YEAR_S) | ||
93 | | ((tm->tm_mon + 1) << RYxR_MONTH_S) | ||
94 | | tm->tm_mday; | ||
95 | } | ||
96 | |||
97 | static u32 rdxr_calc(struct rtc_time *tm) | ||
98 | { | ||
99 | return (tm->tm_hour << RDxR_HOUR_S) | (tm->tm_min << RDxR_MIN_S) | ||
100 | | tm->tm_sec; | ||
101 | } | ||
102 | |||
103 | static void tm_calc(u32 rycr, u32 rdcr, struct rtc_time *tm) | ||
104 | { | ||
105 | tm->tm_year = ((rycr & RYxR_YEAR_MASK) >> RYxR_YEAR_S) - 1900; | ||
106 | tm->tm_mon = (((rycr & RYxR_MONTH_MASK) >> RYxR_MONTH_S)) - 1; | ||
107 | tm->tm_mday = (rycr & RYxR_DAY_MASK); | ||
108 | tm->tm_hour = (rdcr & RDxR_HOUR_MASK) >> RDxR_HOUR_S; | ||
109 | tm->tm_min = (rdcr & RDxR_MIN_MASK) >> RDxR_MIN_S; | ||
110 | tm->tm_sec = rdcr & RDxR_SEC_MASK; | ||
111 | } | ||
112 | |||
113 | static void rtsr_clear_bits(struct pxa_rtc *pxa_rtc, u32 mask) | ||
114 | { | ||
115 | u32 rtsr; | ||
116 | |||
117 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
118 | rtsr &= ~RTSR_TRIG_MASK; | ||
119 | rtsr &= ~mask; | ||
120 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
121 | } | ||
122 | |||
123 | static void rtsr_set_bits(struct pxa_rtc *pxa_rtc, u32 mask) | ||
124 | { | ||
125 | u32 rtsr; | ||
126 | |||
127 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
128 | rtsr &= ~RTSR_TRIG_MASK; | ||
129 | rtsr |= mask; | ||
130 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
131 | } | ||
132 | |||
133 | static irqreturn_t pxa_rtc_irq(int irq, void *dev_id) | ||
134 | { | ||
135 | struct platform_device *pdev = to_platform_device(dev_id); | ||
136 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
137 | u32 rtsr; | ||
138 | unsigned long events = 0; | ||
139 | |||
140 | spin_lock(&pxa_rtc->lock); | ||
141 | |||
142 | /* clear interrupt sources */ | ||
143 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
144 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
145 | |||
146 | /* temporary disable rtc interrupts */ | ||
147 | rtsr_clear_bits(pxa_rtc, RTSR_RDALE1 | RTSR_PIALE | RTSR_HZE); | ||
148 | |||
149 | /* clear alarm interrupt if it has occurred */ | ||
150 | if (rtsr & RTSR_RDAL1) | ||
151 | rtsr &= ~RTSR_RDALE1; | ||
152 | |||
153 | /* update irq data & counter */ | ||
154 | if (rtsr & RTSR_RDAL1) | ||
155 | events |= RTC_AF | RTC_IRQF; | ||
156 | if (rtsr & RTSR_HZ) | ||
157 | events |= RTC_UF | RTC_IRQF; | ||
158 | if (rtsr & RTSR_PIAL) | ||
159 | events |= RTC_PF | RTC_IRQF; | ||
160 | |||
161 | rtc_update_irq(pxa_rtc->rtc, 1, events); | ||
162 | |||
163 | /* enable back rtc interrupts */ | ||
164 | rtc_writel(pxa_rtc, RTSR, rtsr & ~RTSR_TRIG_MASK); | ||
165 | |||
166 | spin_unlock(&pxa_rtc->lock); | ||
167 | return IRQ_HANDLED; | ||
168 | } | ||
169 | |||
170 | static int pxa_rtc_open(struct device *dev) | ||
171 | { | ||
172 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
173 | int ret; | ||
174 | |||
175 | ret = request_irq(pxa_rtc->irq_1Hz, pxa_rtc_irq, IRQF_DISABLED, | ||
176 | "rtc 1Hz", dev); | ||
177 | if (ret < 0) { | ||
178 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_1Hz, | ||
179 | ret); | ||
180 | goto err_irq_1Hz; | ||
181 | } | ||
182 | ret = request_irq(pxa_rtc->irq_Alrm, pxa_rtc_irq, IRQF_DISABLED, | ||
183 | "rtc Alrm", dev); | ||
184 | if (ret < 0) { | ||
185 | dev_err(dev, "can't get irq %i, err %d\n", pxa_rtc->irq_Alrm, | ||
186 | ret); | ||
187 | goto err_irq_Alrm; | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | |||
192 | err_irq_Alrm: | ||
193 | free_irq(pxa_rtc->irq_1Hz, dev); | ||
194 | err_irq_1Hz: | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | static void pxa_rtc_release(struct device *dev) | ||
199 | { | ||
200 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
201 | |||
202 | spin_lock_irq(&pxa_rtc->lock); | ||
203 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); | ||
204 | spin_unlock_irq(&pxa_rtc->lock); | ||
205 | |||
206 | free_irq(pxa_rtc->irq_Alrm, dev); | ||
207 | free_irq(pxa_rtc->irq_1Hz, dev); | ||
208 | } | ||
209 | |||
210 | static int pxa_periodic_irq_set_freq(struct device *dev, int freq) | ||
211 | { | ||
212 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
213 | int period_ms; | ||
214 | |||
215 | if (freq < 1 || freq > MAXFREQ_PERIODIC) | ||
216 | return -EINVAL; | ||
217 | |||
218 | period_ms = 1000 / freq; | ||
219 | rtc_writel(pxa_rtc, PIAR, period_ms); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int pxa_periodic_irq_set_state(struct device *dev, int enabled) | ||
225 | { | ||
226 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
227 | |||
228 | if (enabled) | ||
229 | rtsr_set_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
230 | else | ||
231 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_PICE); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int pxa_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
237 | unsigned long arg) | ||
238 | { | ||
239 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
240 | int ret = 0; | ||
241 | |||
242 | spin_lock_irq(&pxa_rtc->lock); | ||
243 | switch (cmd) { | ||
244 | case RTC_AIE_OFF: | ||
245 | rtsr_clear_bits(pxa_rtc, RTSR_RDALE1); | ||
246 | break; | ||
247 | case RTC_AIE_ON: | ||
248 | rtsr_set_bits(pxa_rtc, RTSR_RDALE1); | ||
249 | break; | ||
250 | case RTC_UIE_OFF: | ||
251 | rtsr_clear_bits(pxa_rtc, RTSR_HZE); | ||
252 | break; | ||
253 | case RTC_UIE_ON: | ||
254 | rtsr_set_bits(pxa_rtc, RTSR_HZE); | ||
255 | break; | ||
256 | default: | ||
257 | ret = -ENOIOCTLCMD; | ||
258 | } | ||
259 | |||
260 | spin_unlock_irq(&pxa_rtc->lock); | ||
261 | return ret; | ||
262 | } | ||
263 | |||
264 | static int pxa_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
265 | { | ||
266 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
267 | u32 rycr, rdcr; | ||
268 | |||
269 | rycr = rtc_readl(pxa_rtc, RYCR); | ||
270 | rdcr = rtc_readl(pxa_rtc, RDCR); | ||
271 | |||
272 | tm_calc(rycr, rdcr, tm); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int pxa_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
277 | { | ||
278 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
279 | |||
280 | rtc_writel(pxa_rtc, RYCR, ryxr_calc(tm)); | ||
281 | rtc_writel(pxa_rtc, RDCR, rdxr_calc(tm)); | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int pxa_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
287 | { | ||
288 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
289 | u32 rtsr, ryar, rdar; | ||
290 | |||
291 | ryar = rtc_readl(pxa_rtc, RYAR1); | ||
292 | rdar = rtc_readl(pxa_rtc, RDAR1); | ||
293 | tm_calc(ryar, rdar, &alrm->time); | ||
294 | |||
295 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
296 | alrm->enabled = (rtsr & RTSR_RDALE1) ? 1 : 0; | ||
297 | alrm->pending = (rtsr & RTSR_RDAL1) ? 1 : 0; | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static int pxa_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
302 | { | ||
303 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
304 | u32 rtsr; | ||
305 | |||
306 | spin_lock_irq(&pxa_rtc->lock); | ||
307 | |||
308 | rtc_writel(pxa_rtc, RYAR1, ryxr_calc(&alrm->time)); | ||
309 | rtc_writel(pxa_rtc, RDAR1, rdxr_calc(&alrm->time)); | ||
310 | |||
311 | rtsr = rtc_readl(pxa_rtc, RTSR); | ||
312 | if (alrm->enabled) | ||
313 | rtsr |= RTSR_RDALE1; | ||
314 | else | ||
315 | rtsr &= ~RTSR_RDALE1; | ||
316 | rtc_writel(pxa_rtc, RTSR, rtsr); | ||
317 | |||
318 | spin_unlock_irq(&pxa_rtc->lock); | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int pxa_rtc_proc(struct device *dev, struct seq_file *seq) | ||
324 | { | ||
325 | struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev); | ||
326 | |||
327 | seq_printf(seq, "trim/divider\t: 0x%08x\n", rtc_readl(pxa_rtc, RTTR)); | ||
328 | seq_printf(seq, "update_IRQ\t: %s\n", | ||
329 | (rtc_readl(pxa_rtc, RTSR) & RTSR_HZE) ? "yes" : "no"); | ||
330 | seq_printf(seq, "periodic_IRQ\t: %s\n", | ||
331 | (rtc_readl(pxa_rtc, RTSR) & RTSR_PIALE) ? "yes" : "no"); | ||
332 | seq_printf(seq, "periodic_freq\t: %u\n", rtc_readl(pxa_rtc, PIAR)); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static const struct rtc_class_ops pxa_rtc_ops = { | ||
338 | .open = pxa_rtc_open, | ||
339 | .release = pxa_rtc_release, | ||
340 | .ioctl = pxa_rtc_ioctl, | ||
341 | .read_time = pxa_rtc_read_time, | ||
342 | .set_time = pxa_rtc_set_time, | ||
343 | .read_alarm = pxa_rtc_read_alarm, | ||
344 | .set_alarm = pxa_rtc_set_alarm, | ||
345 | .proc = pxa_rtc_proc, | ||
346 | .irq_set_state = pxa_periodic_irq_set_state, | ||
347 | .irq_set_freq = pxa_periodic_irq_set_freq, | ||
348 | }; | ||
349 | |||
350 | static int __init pxa_rtc_probe(struct platform_device *pdev) | ||
351 | { | ||
352 | struct device *dev = &pdev->dev; | ||
353 | struct pxa_rtc *pxa_rtc; | ||
354 | int ret; | ||
355 | u32 rttr; | ||
356 | |||
357 | pxa_rtc = kzalloc(sizeof(struct pxa_rtc), GFP_KERNEL); | ||
358 | if (!pxa_rtc) | ||
359 | return -ENOMEM; | ||
360 | |||
361 | spin_lock_init(&pxa_rtc->lock); | ||
362 | platform_set_drvdata(pdev, pxa_rtc); | ||
363 | |||
364 | ret = -ENXIO; | ||
365 | pxa_rtc->ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
366 | if (!pxa_rtc->ress) { | ||
367 | dev_err(dev, "No I/O memory resource defined\n"); | ||
368 | goto err_ress; | ||
369 | } | ||
370 | |||
371 | pxa_rtc->irq_1Hz = platform_get_irq(pdev, 0); | ||
372 | if (pxa_rtc->irq_1Hz < 0) { | ||
373 | dev_err(dev, "No 1Hz IRQ resource defined\n"); | ||
374 | goto err_ress; | ||
375 | } | ||
376 | pxa_rtc->irq_Alrm = platform_get_irq(pdev, 1); | ||
377 | if (pxa_rtc->irq_Alrm < 0) { | ||
378 | dev_err(dev, "No alarm IRQ resource defined\n"); | ||
379 | goto err_ress; | ||
380 | } | ||
381 | |||
382 | ret = -ENOMEM; | ||
383 | pxa_rtc->base = ioremap(pxa_rtc->ress->start, | ||
384 | resource_size(pxa_rtc->ress)); | ||
385 | if (!pxa_rtc->base) { | ||
386 | dev_err(&pdev->dev, "Unable to map pxa RTC I/O memory\n"); | ||
387 | goto err_map; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * If the clock divider is uninitialized then reset it to the | ||
392 | * default value to get the 1Hz clock. | ||
393 | */ | ||
394 | if (rtc_readl(pxa_rtc, RTTR) == 0) { | ||
395 | rttr = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16); | ||
396 | rtc_writel(pxa_rtc, RTTR, rttr); | ||
397 | dev_warn(dev, "warning: initializing default clock" | ||
398 | " divider/trim value\n"); | ||
399 | } | ||
400 | |||
401 | rtsr_clear_bits(pxa_rtc, RTSR_PIALE | RTSR_RDALE1 | RTSR_HZE); | ||
402 | |||
403 | pxa_rtc->rtc = rtc_device_register("pxa-rtc", &pdev->dev, &pxa_rtc_ops, | ||
404 | THIS_MODULE); | ||
405 | ret = PTR_ERR(pxa_rtc->rtc); | ||
406 | if (IS_ERR(pxa_rtc->rtc)) { | ||
407 | dev_err(dev, "Failed to register RTC device -> %d\n", ret); | ||
408 | goto err_rtc_reg; | ||
409 | } | ||
410 | |||
411 | device_init_wakeup(dev, 1); | ||
412 | |||
413 | return 0; | ||
414 | |||
415 | err_rtc_reg: | ||
416 | iounmap(pxa_rtc->base); | ||
417 | err_ress: | ||
418 | err_map: | ||
419 | kfree(pxa_rtc); | ||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | static int __exit pxa_rtc_remove(struct platform_device *pdev) | ||
424 | { | ||
425 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
426 | |||
427 | rtc_device_unregister(pxa_rtc->rtc); | ||
428 | |||
429 | spin_lock_irq(&pxa_rtc->lock); | ||
430 | iounmap(pxa_rtc->base); | ||
431 | spin_unlock_irq(&pxa_rtc->lock); | ||
432 | |||
433 | kfree(pxa_rtc); | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | #ifdef CONFIG_PM | ||
439 | static int pxa_rtc_suspend(struct platform_device *pdev, pm_message_t state) | ||
440 | { | ||
441 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
442 | |||
443 | if (device_may_wakeup(&pdev->dev)) | ||
444 | enable_irq_wake(pxa_rtc->irq_Alrm); | ||
445 | return 0; | ||
446 | } | ||
447 | |||
448 | static int pxa_rtc_resume(struct platform_device *pdev) | ||
449 | { | ||
450 | struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); | ||
451 | |||
452 | if (device_may_wakeup(&pdev->dev)) | ||
453 | disable_irq_wake(pxa_rtc->irq_Alrm); | ||
454 | return 0; | ||
455 | } | ||
456 | #else | ||
457 | #define pxa_rtc_suspend NULL | ||
458 | #define pxa_rtc_resume NULL | ||
459 | #endif | ||
460 | |||
461 | static struct platform_driver pxa_rtc_driver = { | ||
462 | .remove = __exit_p(pxa_rtc_remove), | ||
463 | .suspend = pxa_rtc_suspend, | ||
464 | .resume = pxa_rtc_resume, | ||
465 | .driver = { | ||
466 | .name = "pxa-rtc", | ||
467 | }, | ||
468 | }; | ||
469 | |||
470 | static int __init pxa_rtc_init(void) | ||
471 | { | ||
472 | if (cpu_is_pxa27x() || cpu_is_pxa3xx()) | ||
473 | return platform_driver_probe(&pxa_rtc_driver, pxa_rtc_probe); | ||
474 | |||
475 | return -ENODEV; | ||
476 | } | ||
477 | |||
478 | static void __exit pxa_rtc_exit(void) | ||
479 | { | ||
480 | platform_driver_unregister(&pxa_rtc_driver); | ||
481 | } | ||
482 | |||
483 | module_init(pxa_rtc_init); | ||
484 | module_exit(pxa_rtc_exit); | ||
485 | |||
486 | MODULE_AUTHOR("Robert Jarzmik"); | ||
487 | MODULE_DESCRIPTION("PXA27x/PXA3xx Realtime Clock Driver (RTC)"); | ||
488 | MODULE_LICENSE("GPL"); | ||
489 | MODULE_ALIAS("platform:pxa-rtc"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 7a568beba3f0..e0d7b9991505 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -94,6 +94,9 @@ static int s3c_rtc_setfreq(struct device *dev, int freq) | |||
94 | { | 94 | { |
95 | unsigned int tmp; | 95 | unsigned int tmp; |
96 | 96 | ||
97 | if (!is_power_of_2(freq)) | ||
98 | return -EINVAL; | ||
99 | |||
97 | spin_lock_irq(&s3c_rtc_pie_lock); | 100 | spin_lock_irq(&s3c_rtc_pie_lock); |
98 | 101 | ||
99 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; | 102 | tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE; |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index aaf9d6a337cc..1c3fc6b428e9 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/log2.h> | ||
27 | #include <asm/rtc.h> | 28 | #include <asm/rtc.h> |
28 | 29 | ||
29 | #define DRV_NAME "sh-rtc" | 30 | #define DRV_NAME "sh-rtc" |
@@ -89,7 +90,9 @@ struct sh_rtc { | |||
89 | void __iomem *regbase; | 90 | void __iomem *regbase; |
90 | unsigned long regsize; | 91 | unsigned long regsize; |
91 | struct resource *res; | 92 | struct resource *res; |
92 | unsigned int alarm_irq, periodic_irq, carry_irq; | 93 | int alarm_irq; |
94 | int periodic_irq; | ||
95 | int carry_irq; | ||
93 | struct rtc_device *rtc_dev; | 96 | struct rtc_device *rtc_dev; |
94 | spinlock_t lock; | 97 | spinlock_t lock; |
95 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ | 98 | unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ |
@@ -549,6 +552,8 @@ static int sh_rtc_irq_set_state(struct device *dev, int enabled) | |||
549 | 552 | ||
550 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) | 553 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) |
551 | { | 554 | { |
555 | if (!is_power_of_2(freq)) | ||
556 | return -EINVAL; | ||
552 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); | 557 | return sh_rtc_ioctl(dev, RTC_IRQP_SET, freq); |
553 | } | 558 | } |
554 | 559 | ||
@@ -578,7 +583,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
578 | 583 | ||
579 | /* get periodic/carry/alarm irqs */ | 584 | /* get periodic/carry/alarm irqs */ |
580 | ret = platform_get_irq(pdev, 0); | 585 | ret = platform_get_irq(pdev, 0); |
581 | if (unlikely(ret < 0)) { | 586 | if (unlikely(ret <= 0)) { |
582 | ret = -ENOENT; | 587 | ret = -ENOENT; |
583 | dev_err(&pdev->dev, "No IRQ for period\n"); | 588 | dev_err(&pdev->dev, "No IRQ for period\n"); |
584 | goto err_badres; | 589 | goto err_badres; |
@@ -586,7 +591,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
586 | rtc->periodic_irq = ret; | 591 | rtc->periodic_irq = ret; |
587 | 592 | ||
588 | ret = platform_get_irq(pdev, 1); | 593 | ret = platform_get_irq(pdev, 1); |
589 | if (unlikely(ret < 0)) { | 594 | if (unlikely(ret <= 0)) { |
590 | ret = -ENOENT; | 595 | ret = -ENOENT; |
591 | dev_err(&pdev->dev, "No IRQ for carry\n"); | 596 | dev_err(&pdev->dev, "No IRQ for carry\n"); |
592 | goto err_badres; | 597 | goto err_badres; |
@@ -594,7 +599,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
594 | rtc->carry_irq = ret; | 599 | rtc->carry_irq = ret; |
595 | 600 | ||
596 | ret = platform_get_irq(pdev, 2); | 601 | ret = platform_get_irq(pdev, 2); |
597 | if (unlikely(ret < 0)) { | 602 | if (unlikely(ret <= 0)) { |
598 | ret = -ENOENT; | 603 | ret = -ENOENT; |
599 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | 604 | dev_err(&pdev->dev, "No IRQ for alarm\n"); |
600 | goto err_badres; | 605 | goto err_badres; |
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index f4cd46e15af9..dc0b6224ad9b 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c | |||
@@ -170,7 +170,7 @@ static int stk17ta8_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
170 | struct platform_device *pdev = to_platform_device(dev); | 170 | struct platform_device *pdev = to_platform_device(dev); |
171 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 171 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
172 | 172 | ||
173 | if (pdata->irq < 0) | 173 | if (pdata->irq <= 0) |
174 | return -EINVAL; | 174 | return -EINVAL; |
175 | pdata->alrm_mday = alrm->time.tm_mday; | 175 | pdata->alrm_mday = alrm->time.tm_mday; |
176 | pdata->alrm_hour = alrm->time.tm_hour; | 176 | pdata->alrm_hour = alrm->time.tm_hour; |
@@ -187,7 +187,7 @@ static int stk17ta8_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
187 | struct platform_device *pdev = to_platform_device(dev); | 187 | struct platform_device *pdev = to_platform_device(dev); |
188 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 188 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
189 | 189 | ||
190 | if (pdata->irq < 0) | 190 | if (pdata->irq <= 0) |
191 | return -EINVAL; | 191 | return -EINVAL; |
192 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | 192 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; |
193 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | 193 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; |
@@ -221,7 +221,7 @@ static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
221 | struct platform_device *pdev = to_platform_device(dev); | 221 | struct platform_device *pdev = to_platform_device(dev); |
222 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | 222 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); |
223 | 223 | ||
224 | if (pdata->irq < 0) | 224 | if (pdata->irq <= 0) |
225 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | 225 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ |
226 | switch (cmd) { | 226 | switch (cmd) { |
227 | case RTC_AIE_OFF: | 227 | case RTC_AIE_OFF: |
@@ -303,7 +303,6 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
303 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 303 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); |
304 | if (!pdata) | 304 | if (!pdata) |
305 | return -ENOMEM; | 305 | return -ENOMEM; |
306 | pdata->irq = -1; | ||
307 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { | 306 | if (!request_mem_region(res->start, RTC_REG_SIZE, pdev->name)) { |
308 | ret = -EBUSY; | 307 | ret = -EBUSY; |
309 | goto out; | 308 | goto out; |
@@ -329,13 +328,13 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
329 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF) | 328 | if (readb(ioaddr + RTC_FLAGS) & RTC_FLAGS_PF) |
330 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | 329 | dev_warn(&pdev->dev, "voltage-low detected.\n"); |
331 | 330 | ||
332 | if (pdata->irq >= 0) { | 331 | if (pdata->irq > 0) { |
333 | writeb(0, ioaddr + RTC_INTERRUPTS); | 332 | writeb(0, ioaddr + RTC_INTERRUPTS); |
334 | if (request_irq(pdata->irq, stk17ta8_rtc_interrupt, | 333 | if (request_irq(pdata->irq, stk17ta8_rtc_interrupt, |
335 | IRQF_DISABLED | IRQF_SHARED, | 334 | IRQF_DISABLED | IRQF_SHARED, |
336 | pdev->name, pdev) < 0) { | 335 | pdev->name, pdev) < 0) { |
337 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 336 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
338 | pdata->irq = -1; | 337 | pdata->irq = 0; |
339 | } | 338 | } |
340 | } | 339 | } |
341 | 340 | ||
@@ -355,7 +354,7 @@ static int __init stk17ta8_rtc_probe(struct platform_device *pdev) | |||
355 | out: | 354 | out: |
356 | if (pdata->rtc) | 355 | if (pdata->rtc) |
357 | rtc_device_unregister(pdata->rtc); | 356 | rtc_device_unregister(pdata->rtc); |
358 | if (pdata->irq >= 0) | 357 | if (pdata->irq > 0) |
359 | free_irq(pdata->irq, pdev); | 358 | free_irq(pdata->irq, pdev); |
360 | if (ioaddr) | 359 | if (ioaddr) |
361 | iounmap(ioaddr); | 360 | iounmap(ioaddr); |
@@ -371,7 +370,7 @@ static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev) | |||
371 | 370 | ||
372 | sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); | 371 | sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); |
373 | rtc_device_unregister(pdata->rtc); | 372 | rtc_device_unregister(pdata->rtc); |
374 | if (pdata->irq >= 0) { | 373 | if (pdata->irq > 0) { |
375 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); | 374 | writeb(0, pdata->ioaddr + RTC_INTERRUPTS); |
376 | free_irq(pdata->irq, pdev); | 375 | free_irq(pdata->irq, pdev); |
377 | } | 376 | } |
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index bc930022004a..e478280ff628 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -34,14 +34,9 @@ static int test_rtc_read_time(struct device *dev, | |||
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | static int test_rtc_set_time(struct device *dev, | ||
38 | struct rtc_time *tm) | ||
39 | { | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int test_rtc_set_mmss(struct device *dev, unsigned long secs) | 37 | static int test_rtc_set_mmss(struct device *dev, unsigned long secs) |
44 | { | 38 | { |
39 | dev_info(dev, "%s, secs = %lu\n", __func__, secs); | ||
45 | return 0; | 40 | return 0; |
46 | } | 41 | } |
47 | 42 | ||
@@ -78,7 +73,6 @@ static int test_rtc_ioctl(struct device *dev, unsigned int cmd, | |||
78 | static const struct rtc_class_ops test_rtc_ops = { | 73 | static const struct rtc_class_ops test_rtc_ops = { |
79 | .proc = test_rtc_proc, | 74 | .proc = test_rtc_proc, |
80 | .read_time = test_rtc_read_time, | 75 | .read_time = test_rtc_read_time, |
81 | .set_time = test_rtc_set_time, | ||
82 | .read_alarm = test_rtc_read_alarm, | 76 | .read_alarm = test_rtc_read_alarm, |
83 | .set_alarm = test_rtc_set_alarm, | 77 | .set_alarm = test_rtc_set_alarm, |
84 | .set_mmss = test_rtc_set_mmss, | 78 | .set_mmss = test_rtc_set_mmss, |
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index 01d8da9afdc8..8ce5f74ee45b 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/errno.h> | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/types.h> | 25 | #include <linux/types.h> |
@@ -415,8 +416,8 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
415 | int irq = platform_get_irq(pdev, 0); | 416 | int irq = platform_get_irq(pdev, 0); |
416 | u8 rd_reg; | 417 | u8 rd_reg; |
417 | 418 | ||
418 | if (irq < 0) | 419 | if (irq <= 0) |
419 | return irq; | 420 | return -EINVAL; |
420 | 421 | ||
421 | rtc = rtc_device_register(pdev->name, | 422 | rtc = rtc_device_register(pdev->name, |
422 | &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); | 423 | &pdev->dev, &twl4030_rtc_ops, THIS_MODULE); |
diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c new file mode 100644 index 000000000000..4ee4857ff207 --- /dev/null +++ b/drivers/rtc/rtc-tx4939.c | |||
@@ -0,0 +1,317 @@ | |||
1 | /* | ||
2 | * TX4939 internal RTC driver | ||
3 | * Based on RBTX49xx patch from CELF patch archive. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * (C) Copyright TOSHIBA CORPORATION 2005-2007 | ||
10 | */ | ||
11 | #include <linux/rtc.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <asm/txx9/tx4939.h> | ||
16 | |||
17 | struct tx4939rtc_plat_data { | ||
18 | struct rtc_device *rtc; | ||
19 | struct tx4939_rtc_reg __iomem *rtcreg; | ||
20 | }; | ||
21 | |||
22 | static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev) | ||
23 | { | ||
24 | return platform_get_drvdata(to_platform_device(dev)); | ||
25 | } | ||
26 | |||
27 | static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) | ||
28 | { | ||
29 | int i = 0; | ||
30 | |||
31 | __raw_writel(cmd, &rtcreg->ctl); | ||
32 | /* This might take 30us (next 32.768KHz clock) */ | ||
33 | while (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_BUSY) { | ||
34 | /* timeout on approx. 100us (@ GBUS200MHz) */ | ||
35 | if (i++ > 200 * 100) | ||
36 | return -EBUSY; | ||
37 | cpu_relax(); | ||
38 | } | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | static int tx4939_rtc_set_mmss(struct device *dev, unsigned long secs) | ||
43 | { | ||
44 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
45 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
46 | int i, ret; | ||
47 | unsigned char buf[6]; | ||
48 | |||
49 | buf[0] = 0; | ||
50 | buf[1] = 0; | ||
51 | buf[2] = secs; | ||
52 | buf[3] = secs >> 8; | ||
53 | buf[4] = secs >> 16; | ||
54 | buf[5] = secs >> 24; | ||
55 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
56 | __raw_writel(0, &rtcreg->adr); | ||
57 | for (i = 0; i < 6; i++) | ||
58 | __raw_writel(buf[i], &rtcreg->dat); | ||
59 | ret = tx4939_rtc_cmd(rtcreg, | ||
60 | TX4939_RTCCTL_COMMAND_SETTIME | | ||
61 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
62 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
67 | { | ||
68 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
69 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
70 | int i, ret; | ||
71 | unsigned long sec; | ||
72 | unsigned char buf[6]; | ||
73 | |||
74 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
75 | ret = tx4939_rtc_cmd(rtcreg, | ||
76 | TX4939_RTCCTL_COMMAND_GETTIME | | ||
77 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
78 | if (ret) { | ||
79 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
80 | return ret; | ||
81 | } | ||
82 | __raw_writel(2, &rtcreg->adr); | ||
83 | for (i = 2; i < 6; i++) | ||
84 | buf[i] = __raw_readl(&rtcreg->dat); | ||
85 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
86 | sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; | ||
87 | rtc_time_to_tm(sec, tm); | ||
88 | return rtc_valid_tm(tm); | ||
89 | } | ||
90 | |||
91 | static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
92 | { | ||
93 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
94 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
95 | int i, ret; | ||
96 | unsigned long sec; | ||
97 | unsigned char buf[6]; | ||
98 | |||
99 | if (alrm->time.tm_sec < 0 || | ||
100 | alrm->time.tm_min < 0 || | ||
101 | alrm->time.tm_hour < 0 || | ||
102 | alrm->time.tm_mday < 0 || | ||
103 | alrm->time.tm_mon < 0 || | ||
104 | alrm->time.tm_year < 0) | ||
105 | return -EINVAL; | ||
106 | rtc_tm_to_time(&alrm->time, &sec); | ||
107 | buf[0] = 0; | ||
108 | buf[1] = 0; | ||
109 | buf[2] = sec; | ||
110 | buf[3] = sec >> 8; | ||
111 | buf[4] = sec >> 16; | ||
112 | buf[5] = sec >> 24; | ||
113 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
114 | __raw_writel(0, &rtcreg->adr); | ||
115 | for (i = 0; i < 6; i++) | ||
116 | __raw_writel(buf[i], &rtcreg->dat); | ||
117 | ret = tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_SETALARM | | ||
118 | (alrm->enabled ? TX4939_RTCCTL_ALME : 0)); | ||
119 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
124 | { | ||
125 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
126 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
127 | int i, ret; | ||
128 | unsigned long sec; | ||
129 | unsigned char buf[6]; | ||
130 | u32 ctl; | ||
131 | |||
132 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
133 | ret = tx4939_rtc_cmd(rtcreg, | ||
134 | TX4939_RTCCTL_COMMAND_GETALARM | | ||
135 | (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALME)); | ||
136 | if (ret) { | ||
137 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
138 | return ret; | ||
139 | } | ||
140 | __raw_writel(2, &rtcreg->adr); | ||
141 | for (i = 2; i < 6; i++) | ||
142 | buf[i] = __raw_readl(&rtcreg->dat); | ||
143 | ctl = __raw_readl(&rtcreg->ctl); | ||
144 | alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; | ||
145 | alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; | ||
146 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
147 | sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; | ||
148 | rtc_time_to_tm(sec, &alrm->time); | ||
149 | return rtc_valid_tm(&alrm->time); | ||
150 | } | ||
151 | |||
152 | static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
153 | { | ||
154 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
155 | |||
156 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
157 | tx4939_rtc_cmd(pdata->rtcreg, | ||
158 | TX4939_RTCCTL_COMMAND_NOP | | ||
159 | (enabled ? TX4939_RTCCTL_ALME : 0)); | ||
160 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) | ||
165 | { | ||
166 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id); | ||
167 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
168 | unsigned long events = RTC_IRQF; | ||
169 | |||
170 | spin_lock(&pdata->rtc->irq_lock); | ||
171 | if (__raw_readl(&rtcreg->ctl) & TX4939_RTCCTL_ALMD) { | ||
172 | events |= RTC_AF; | ||
173 | tx4939_rtc_cmd(rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
174 | } | ||
175 | spin_unlock(&pdata->rtc->irq_lock); | ||
176 | rtc_update_irq(pdata->rtc, 1, events); | ||
177 | return IRQ_HANDLED; | ||
178 | } | ||
179 | |||
180 | static const struct rtc_class_ops tx4939_rtc_ops = { | ||
181 | .read_time = tx4939_rtc_read_time, | ||
182 | .read_alarm = tx4939_rtc_read_alarm, | ||
183 | .set_alarm = tx4939_rtc_set_alarm, | ||
184 | .set_mmss = tx4939_rtc_set_mmss, | ||
185 | .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, | ||
186 | }; | ||
187 | |||
188 | static ssize_t tx4939_rtc_nvram_read(struct kobject *kobj, | ||
189 | struct bin_attribute *bin_attr, | ||
190 | char *buf, loff_t pos, size_t size) | ||
191 | { | ||
192 | struct device *dev = container_of(kobj, struct device, kobj); | ||
193 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
194 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
195 | ssize_t count; | ||
196 | |||
197 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
198 | for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | ||
199 | count++, size--) { | ||
200 | __raw_writel(pos++, &rtcreg->adr); | ||
201 | *buf++ = __raw_readl(&rtcreg->dat); | ||
202 | } | ||
203 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
204 | return count; | ||
205 | } | ||
206 | |||
207 | static ssize_t tx4939_rtc_nvram_write(struct kobject *kobj, | ||
208 | struct bin_attribute *bin_attr, | ||
209 | char *buf, loff_t pos, size_t size) | ||
210 | { | ||
211 | struct device *dev = container_of(kobj, struct device, kobj); | ||
212 | struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); | ||
213 | struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; | ||
214 | ssize_t count; | ||
215 | |||
216 | spin_lock_irq(&pdata->rtc->irq_lock); | ||
217 | for (count = 0; size > 0 && pos < TX4939_RTC_REG_RAMSIZE; | ||
218 | count++, size--) { | ||
219 | __raw_writel(pos++, &rtcreg->adr); | ||
220 | __raw_writel(*buf++, &rtcreg->dat); | ||
221 | } | ||
222 | spin_unlock_irq(&pdata->rtc->irq_lock); | ||
223 | return count; | ||
224 | } | ||
225 | |||
226 | static struct bin_attribute tx4939_rtc_nvram_attr = { | ||
227 | .attr = { | ||
228 | .name = "nvram", | ||
229 | .mode = S_IRUGO | S_IWUSR, | ||
230 | }, | ||
231 | .size = TX4939_RTC_REG_RAMSIZE, | ||
232 | .read = tx4939_rtc_nvram_read, | ||
233 | .write = tx4939_rtc_nvram_write, | ||
234 | }; | ||
235 | |||
236 | static int __init tx4939_rtc_probe(struct platform_device *pdev) | ||
237 | { | ||
238 | struct rtc_device *rtc; | ||
239 | struct tx4939rtc_plat_data *pdata; | ||
240 | struct resource *res; | ||
241 | int irq, ret; | ||
242 | |||
243 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
244 | if (!res) | ||
245 | return -ENODEV; | ||
246 | irq = platform_get_irq(pdev, 0); | ||
247 | if (irq < 0) | ||
248 | return -ENODEV; | ||
249 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
250 | if (!pdata) | ||
251 | return -ENOMEM; | ||
252 | platform_set_drvdata(pdev, pdata); | ||
253 | |||
254 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
255 | resource_size(res), pdev->name)) | ||
256 | return -EBUSY; | ||
257 | pdata->rtcreg = devm_ioremap(&pdev->dev, res->start, | ||
258 | resource_size(res)); | ||
259 | if (!pdata->rtcreg) | ||
260 | return -EBUSY; | ||
261 | |||
262 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
263 | if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, | ||
264 | IRQF_DISABLED | IRQF_SHARED, | ||
265 | pdev->name, &pdev->dev) < 0) { | ||
266 | return -EBUSY; | ||
267 | } | ||
268 | rtc = rtc_device_register(pdev->name, &pdev->dev, | ||
269 | &tx4939_rtc_ops, THIS_MODULE); | ||
270 | if (IS_ERR(rtc)) | ||
271 | return PTR_ERR(rtc); | ||
272 | pdata->rtc = rtc; | ||
273 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); | ||
274 | if (ret) | ||
275 | rtc_device_unregister(rtc); | ||
276 | return ret; | ||
277 | } | ||
278 | |||
279 | static int __exit tx4939_rtc_remove(struct platform_device *pdev) | ||
280 | { | ||
281 | struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
282 | struct rtc_device *rtc = pdata->rtc; | ||
283 | |||
284 | spin_lock_irq(&rtc->irq_lock); | ||
285 | tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); | ||
286 | spin_unlock_irq(&rtc->irq_lock); | ||
287 | sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); | ||
288 | rtc_device_unregister(rtc); | ||
289 | platform_set_drvdata(pdev, NULL); | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | static struct platform_driver tx4939_rtc_driver = { | ||
294 | .remove = __exit_p(tx4939_rtc_remove), | ||
295 | .driver = { | ||
296 | .name = "tx4939rtc", | ||
297 | .owner = THIS_MODULE, | ||
298 | }, | ||
299 | }; | ||
300 | |||
301 | static int __init tx4939rtc_init(void) | ||
302 | { | ||
303 | return platform_driver_probe(&tx4939_rtc_driver, tx4939_rtc_probe); | ||
304 | } | ||
305 | |||
306 | static void __exit tx4939rtc_exit(void) | ||
307 | { | ||
308 | platform_driver_unregister(&tx4939_rtc_driver); | ||
309 | } | ||
310 | |||
311 | module_init(tx4939rtc_init); | ||
312 | module_exit(tx4939rtc_exit); | ||
313 | |||
314 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | ||
315 | MODULE_DESCRIPTION("TX4939 internal RTC driver"); | ||
316 | MODULE_LICENSE("GPL"); | ||
317 | MODULE_ALIAS("platform:tx4939rtc"); | ||
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 834dcc6d785f..f11297aff854 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
28 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/log2.h> | ||
30 | 31 | ||
31 | #include <asm/div64.h> | 32 | #include <asm/div64.h> |
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
@@ -84,8 +85,8 @@ static DEFINE_SPINLOCK(rtc_lock); | |||
84 | static char rtc_name[] = "RTC"; | 85 | static char rtc_name[] = "RTC"; |
85 | static unsigned long periodic_count; | 86 | static unsigned long periodic_count; |
86 | static unsigned int alarm_enabled; | 87 | static unsigned int alarm_enabled; |
87 | static int aie_irq = -1; | 88 | static int aie_irq; |
88 | static int pie_irq = -1; | 89 | static int pie_irq; |
89 | 90 | ||
90 | static inline unsigned long read_elapsed_second(void) | 91 | static inline unsigned long read_elapsed_second(void) |
91 | { | 92 | { |
@@ -210,6 +211,8 @@ static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq) | |||
210 | { | 211 | { |
211 | unsigned long count; | 212 | unsigned long count; |
212 | 213 | ||
214 | if (!is_power_of_2(freq)) | ||
215 | return -EINVAL; | ||
213 | count = RTC_FREQUENCY; | 216 | count = RTC_FREQUENCY; |
214 | do_div(count, freq); | 217 | do_div(count, freq); |
215 | 218 | ||
@@ -360,7 +363,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
360 | spin_unlock_irq(&rtc_lock); | 363 | spin_unlock_irq(&rtc_lock); |
361 | 364 | ||
362 | aie_irq = platform_get_irq(pdev, 0); | 365 | aie_irq = platform_get_irq(pdev, 0); |
363 | if (aie_irq < 0 || aie_irq >= nr_irqs) { | 366 | if (aie_irq <= 0) { |
364 | retval = -EBUSY; | 367 | retval = -EBUSY; |
365 | goto err_device_unregister; | 368 | goto err_device_unregister; |
366 | } | 369 | } |
@@ -371,7 +374,7 @@ static int __devinit rtc_probe(struct platform_device *pdev) | |||
371 | goto err_device_unregister; | 374 | goto err_device_unregister; |
372 | 375 | ||
373 | pie_irq = platform_get_irq(pdev, 1); | 376 | pie_irq = platform_get_irq(pdev, 1); |
374 | if (pie_irq < 0 || pie_irq >= nr_irqs) | 377 | if (pie_irq <= 0) |
375 | goto err_free_irq; | 378 | goto err_free_irq; |
376 | 379 | ||
377 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, | 380 | retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED, |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b9d0efb6803f..4a6fe01831a8 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -78,7 +78,7 @@ config SPI_AU1550 | |||
78 | will be called au1550_spi. | 78 | will be called au1550_spi. |
79 | 79 | ||
80 | config SPI_BITBANG | 80 | config SPI_BITBANG |
81 | tristate "Bitbanging SPI master" | 81 | tristate "Utilities for Bitbanging SPI masters" |
82 | help | 82 | help |
83 | With a few GPIO pins, your system can bitbang the SPI protocol. | 83 | With a few GPIO pins, your system can bitbang the SPI protocol. |
84 | Select this to get SPI support through I/O pins (GPIO, parallel | 84 | Select this to get SPI support through I/O pins (GPIO, parallel |
@@ -100,6 +100,22 @@ config SPI_BUTTERFLY | |||
100 | inexpensive battery powered microcontroller evaluation board. | 100 | inexpensive battery powered microcontroller evaluation board. |
101 | This same cable can be used to flash new firmware. | 101 | This same cable can be used to flash new firmware. |
102 | 102 | ||
103 | config SPI_GPIO | ||
104 | tristate "GPIO-based bitbanging SPI Master" | ||
105 | depends on GENERIC_GPIO | ||
106 | select SPI_BITBANG | ||
107 | help | ||
108 | This simple GPIO bitbanging SPI master uses the arch-neutral GPIO | ||
109 | interface to manage MOSI, MISO, SCK, and chipselect signals. SPI | ||
110 | slaves connected to a bus using this driver are configured as usual, | ||
111 | except that the spi_board_info.controller_data holds the GPIO number | ||
112 | for the chipselect used by this controller driver. | ||
113 | |||
114 | Note that this driver often won't achieve even 1 Mbit/sec speeds, | ||
115 | making it unusually slow for SPI. If your platform can inline | ||
116 | GPIO operations, you should be able to leverage that for better | ||
117 | speed with a custom version of this driver; see the source code. | ||
118 | |||
103 | config SPI_IMX | 119 | config SPI_IMX |
104 | tristate "Freescale iMX SPI controller" | 120 | tristate "Freescale iMX SPI controller" |
105 | depends on ARCH_IMX && EXPERIMENTAL | 121 | depends on ARCH_IMX && EXPERIMENTAL |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index ccf18de34e1e..5e9f521b8844 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -16,6 +16,7 @@ obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o | |||
16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o | 16 | obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o |
17 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o | 17 | obj-$(CONFIG_SPI_AU1550) += au1550_spi.o |
18 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o | 18 | obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o |
19 | obj-$(CONFIG_SPI_GPIO) += spi_gpio.o | ||
19 | obj-$(CONFIG_SPI_IMX) += spi_imx.o | 20 | obj-$(CONFIG_SPI_IMX) += spi_imx.o |
20 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o | 21 | obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o |
21 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o | 22 | obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 8abae4ad0fa5..5e39bac9c51b 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -30,13 +30,6 @@ | |||
30 | * The core SPI transfer engine just talks to a register bank to set up | 30 | * The core SPI transfer engine just talks to a register bank to set up |
31 | * DMA transfers; transfer queue progress is driven by IRQs. The clock | 31 | * DMA transfers; transfer queue progress is driven by IRQs. The clock |
32 | * framework provides the base clock, subdivided for each spi_device. | 32 | * framework provides the base clock, subdivided for each spi_device. |
33 | * | ||
34 | * Newer controllers, marked with "new_1" flag, have: | ||
35 | * - CR.LASTXFER | ||
36 | * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) | ||
37 | * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) | ||
38 | * - SPI_CSRx.CSAAT | ||
39 | * - SPI_CSRx.SBCR allows faster clocking | ||
40 | */ | 33 | */ |
41 | struct atmel_spi { | 34 | struct atmel_spi { |
42 | spinlock_t lock; | 35 | spinlock_t lock; |
@@ -45,7 +38,6 @@ struct atmel_spi { | |||
45 | int irq; | 38 | int irq; |
46 | struct clk *clk; | 39 | struct clk *clk; |
47 | struct platform_device *pdev; | 40 | struct platform_device *pdev; |
48 | unsigned new_1:1; | ||
49 | struct spi_device *stay; | 41 | struct spi_device *stay; |
50 | 42 | ||
51 | u8 stopping; | 43 | u8 stopping; |
@@ -59,10 +51,33 @@ struct atmel_spi { | |||
59 | dma_addr_t buffer_dma; | 51 | dma_addr_t buffer_dma; |
60 | }; | 52 | }; |
61 | 53 | ||
54 | /* Controller-specific per-slave state */ | ||
55 | struct atmel_spi_device { | ||
56 | unsigned int npcs_pin; | ||
57 | u32 csr; | ||
58 | }; | ||
59 | |||
62 | #define BUFFER_SIZE PAGE_SIZE | 60 | #define BUFFER_SIZE PAGE_SIZE |
63 | #define INVALID_DMA_ADDRESS 0xffffffff | 61 | #define INVALID_DMA_ADDRESS 0xffffffff |
64 | 62 | ||
65 | /* | 63 | /* |
64 | * Version 2 of the SPI controller has | ||
65 | * - CR.LASTXFER | ||
66 | * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) | ||
67 | * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) | ||
68 | * - SPI_CSRx.CSAAT | ||
69 | * - SPI_CSRx.SBCR allows faster clocking | ||
70 | * | ||
71 | * We can determine the controller version by reading the VERSION | ||
72 | * register, but I haven't checked that it exists on all chips, and | ||
73 | * this is cheaper anyway. | ||
74 | */ | ||
75 | static bool atmel_spi_is_v2(void) | ||
76 | { | ||
77 | return !cpu_is_at91rm9200(); | ||
78 | } | ||
79 | |||
80 | /* | ||
66 | * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby | 81 | * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby |
67 | * they assume that spi slave device state will not change on deselect, so | 82 | * they assume that spi slave device state will not change on deselect, so |
68 | * that automagic deselection is OK. ("NPCSx rises if no data is to be | 83 | * that automagic deselection is OK. ("NPCSx rises if no data is to be |
@@ -80,39 +95,58 @@ struct atmel_spi { | |||
80 | * Master on Chip Select 0.") No workaround exists for that ... so for | 95 | * Master on Chip Select 0.") No workaround exists for that ... so for |
81 | * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, | 96 | * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, |
82 | * and (c) will trigger that first erratum in some cases. | 97 | * and (c) will trigger that first erratum in some cases. |
98 | * | ||
99 | * TODO: Test if the atmel_spi_is_v2() branch below works on | ||
100 | * AT91RM9200 if we use some other register than CSR0. However, don't | ||
101 | * do this unconditionally since AP7000 has an errata where the BITS | ||
102 | * field in CSR0 overrides all other CSRs. | ||
83 | */ | 103 | */ |
84 | 104 | ||
85 | static void cs_activate(struct atmel_spi *as, struct spi_device *spi) | 105 | static void cs_activate(struct atmel_spi *as, struct spi_device *spi) |
86 | { | 106 | { |
87 | unsigned gpio = (unsigned) spi->controller_data; | 107 | struct atmel_spi_device *asd = spi->controller_state; |
88 | unsigned active = spi->mode & SPI_CS_HIGH; | 108 | unsigned active = spi->mode & SPI_CS_HIGH; |
89 | u32 mr; | 109 | u32 mr; |
90 | int i; | ||
91 | u32 csr; | ||
92 | u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; | ||
93 | |||
94 | /* Make sure clock polarity is correct */ | ||
95 | for (i = 0; i < spi->master->num_chipselect; i++) { | ||
96 | csr = spi_readl(as, CSR0 + 4 * i); | ||
97 | if ((csr ^ cpol) & SPI_BIT(CPOL)) | ||
98 | spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL)); | ||
99 | } | ||
100 | 110 | ||
101 | mr = spi_readl(as, MR); | 111 | if (atmel_spi_is_v2()) { |
102 | mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); | 112 | /* |
113 | * Always use CSR0. This ensures that the clock | ||
114 | * switches to the correct idle polarity before we | ||
115 | * toggle the CS. | ||
116 | */ | ||
117 | spi_writel(as, CSR0, asd->csr); | ||
118 | spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MODFDIS) | ||
119 | | SPI_BIT(MSTR)); | ||
120 | mr = spi_readl(as, MR); | ||
121 | gpio_set_value(asd->npcs_pin, active); | ||
122 | } else { | ||
123 | u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; | ||
124 | int i; | ||
125 | u32 csr; | ||
126 | |||
127 | /* Make sure clock polarity is correct */ | ||
128 | for (i = 0; i < spi->master->num_chipselect; i++) { | ||
129 | csr = spi_readl(as, CSR0 + 4 * i); | ||
130 | if ((csr ^ cpol) & SPI_BIT(CPOL)) | ||
131 | spi_writel(as, CSR0 + 4 * i, | ||
132 | csr ^ SPI_BIT(CPOL)); | ||
133 | } | ||
134 | |||
135 | mr = spi_readl(as, MR); | ||
136 | mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); | ||
137 | if (spi->chip_select != 0) | ||
138 | gpio_set_value(asd->npcs_pin, active); | ||
139 | spi_writel(as, MR, mr); | ||
140 | } | ||
103 | 141 | ||
104 | dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", | 142 | dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", |
105 | gpio, active ? " (high)" : "", | 143 | asd->npcs_pin, active ? " (high)" : "", |
106 | mr); | 144 | mr); |
107 | |||
108 | if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) | ||
109 | gpio_set_value(gpio, active); | ||
110 | spi_writel(as, MR, mr); | ||
111 | } | 145 | } |
112 | 146 | ||
113 | static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | 147 | static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) |
114 | { | 148 | { |
115 | unsigned gpio = (unsigned) spi->controller_data; | 149 | struct atmel_spi_device *asd = spi->controller_state; |
116 | unsigned active = spi->mode & SPI_CS_HIGH; | 150 | unsigned active = spi->mode & SPI_CS_HIGH; |
117 | u32 mr; | 151 | u32 mr; |
118 | 152 | ||
@@ -126,11 +160,11 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | |||
126 | } | 160 | } |
127 | 161 | ||
128 | dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", | 162 | dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", |
129 | gpio, active ? " (low)" : "", | 163 | asd->npcs_pin, active ? " (low)" : "", |
130 | mr); | 164 | mr); |
131 | 165 | ||
132 | if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) | 166 | if (atmel_spi_is_v2() || spi->chip_select != 0) |
133 | gpio_set_value(gpio, !active); | 167 | gpio_set_value(asd->npcs_pin, !active); |
134 | } | 168 | } |
135 | 169 | ||
136 | static inline int atmel_spi_xfer_is_last(struct spi_message *msg, | 170 | static inline int atmel_spi_xfer_is_last(struct spi_message *msg, |
@@ -502,6 +536,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
502 | static int atmel_spi_setup(struct spi_device *spi) | 536 | static int atmel_spi_setup(struct spi_device *spi) |
503 | { | 537 | { |
504 | struct atmel_spi *as; | 538 | struct atmel_spi *as; |
539 | struct atmel_spi_device *asd; | ||
505 | u32 scbr, csr; | 540 | u32 scbr, csr; |
506 | unsigned int bits = spi->bits_per_word; | 541 | unsigned int bits = spi->bits_per_word; |
507 | unsigned long bus_hz; | 542 | unsigned long bus_hz; |
@@ -536,19 +571,16 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
536 | } | 571 | } |
537 | 572 | ||
538 | /* see notes above re chipselect */ | 573 | /* see notes above re chipselect */ |
539 | if (cpu_is_at91rm9200() | 574 | if (!atmel_spi_is_v2() |
540 | && spi->chip_select == 0 | 575 | && spi->chip_select == 0 |
541 | && (spi->mode & SPI_CS_HIGH)) { | 576 | && (spi->mode & SPI_CS_HIGH)) { |
542 | dev_dbg(&spi->dev, "setup: can't be active-high\n"); | 577 | dev_dbg(&spi->dev, "setup: can't be active-high\n"); |
543 | return -EINVAL; | 578 | return -EINVAL; |
544 | } | 579 | } |
545 | 580 | ||
546 | /* | 581 | /* v1 chips start out at half the peripheral bus speed. */ |
547 | * Pre-new_1 chips start out at half the peripheral | ||
548 | * bus speed. | ||
549 | */ | ||
550 | bus_hz = clk_get_rate(as->clk); | 582 | bus_hz = clk_get_rate(as->clk); |
551 | if (!as->new_1) | 583 | if (!atmel_spi_is_v2()) |
552 | bus_hz /= 2; | 584 | bus_hz /= 2; |
553 | 585 | ||
554 | if (spi->max_speed_hz) { | 586 | if (spi->max_speed_hz) { |
@@ -589,11 +621,20 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
589 | 621 | ||
590 | /* chipselect must have been muxed as GPIO (e.g. in board setup) */ | 622 | /* chipselect must have been muxed as GPIO (e.g. in board setup) */ |
591 | npcs_pin = (unsigned int)spi->controller_data; | 623 | npcs_pin = (unsigned int)spi->controller_data; |
592 | if (!spi->controller_state) { | 624 | asd = spi->controller_state; |
625 | if (!asd) { | ||
626 | asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL); | ||
627 | if (!asd) | ||
628 | return -ENOMEM; | ||
629 | |||
593 | ret = gpio_request(npcs_pin, spi->dev.bus_id); | 630 | ret = gpio_request(npcs_pin, spi->dev.bus_id); |
594 | if (ret) | 631 | if (ret) { |
632 | kfree(asd); | ||
595 | return ret; | 633 | return ret; |
596 | spi->controller_state = (void *)npcs_pin; | 634 | } |
635 | |||
636 | asd->npcs_pin = npcs_pin; | ||
637 | spi->controller_state = asd; | ||
597 | gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); | 638 | gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); |
598 | } else { | 639 | } else { |
599 | unsigned long flags; | 640 | unsigned long flags; |
@@ -605,11 +646,14 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
605 | spin_unlock_irqrestore(&as->lock, flags); | 646 | spin_unlock_irqrestore(&as->lock, flags); |
606 | } | 647 | } |
607 | 648 | ||
649 | asd->csr = csr; | ||
650 | |||
608 | dev_dbg(&spi->dev, | 651 | dev_dbg(&spi->dev, |
609 | "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", | 652 | "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", |
610 | bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); | 653 | bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); |
611 | 654 | ||
612 | spi_writel(as, CSR0 + 4 * spi->chip_select, csr); | 655 | if (!atmel_spi_is_v2()) |
656 | spi_writel(as, CSR0 + 4 * spi->chip_select, csr); | ||
613 | 657 | ||
614 | return 0; | 658 | return 0; |
615 | } | 659 | } |
@@ -684,10 +728,11 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) | |||
684 | static void atmel_spi_cleanup(struct spi_device *spi) | 728 | static void atmel_spi_cleanup(struct spi_device *spi) |
685 | { | 729 | { |
686 | struct atmel_spi *as = spi_master_get_devdata(spi->master); | 730 | struct atmel_spi *as = spi_master_get_devdata(spi->master); |
731 | struct atmel_spi_device *asd = spi->controller_state; | ||
687 | unsigned gpio = (unsigned) spi->controller_data; | 732 | unsigned gpio = (unsigned) spi->controller_data; |
688 | unsigned long flags; | 733 | unsigned long flags; |
689 | 734 | ||
690 | if (!spi->controller_state) | 735 | if (!asd) |
691 | return; | 736 | return; |
692 | 737 | ||
693 | spin_lock_irqsave(&as->lock, flags); | 738 | spin_lock_irqsave(&as->lock, flags); |
@@ -697,7 +742,9 @@ static void atmel_spi_cleanup(struct spi_device *spi) | |||
697 | } | 742 | } |
698 | spin_unlock_irqrestore(&as->lock, flags); | 743 | spin_unlock_irqrestore(&as->lock, flags); |
699 | 744 | ||
745 | spi->controller_state = NULL; | ||
700 | gpio_free(gpio); | 746 | gpio_free(gpio); |
747 | kfree(asd); | ||
701 | } | 748 | } |
702 | 749 | ||
703 | /*-------------------------------------------------------------------------*/ | 750 | /*-------------------------------------------------------------------------*/ |
@@ -755,8 +802,6 @@ static int __init atmel_spi_probe(struct platform_device *pdev) | |||
755 | goto out_free_buffer; | 802 | goto out_free_buffer; |
756 | as->irq = irq; | 803 | as->irq = irq; |
757 | as->clk = clk; | 804 | as->clk = clk; |
758 | if (!cpu_is_at91rm9200()) | ||
759 | as->new_1 = 1; | ||
760 | 805 | ||
761 | ret = request_irq(irq, atmel_spi_interrupt, 0, | 806 | ret = request_irq(irq, atmel_spi_interrupt, 0, |
762 | pdev->dev.bus_id, master); | 807 | pdev->dev.bus_id, master); |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 6104f461a3cd..d0fc4ca2f656 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1561,11 +1561,12 @@ out_error_master_alloc: | |||
1561 | static int pxa2xx_spi_remove(struct platform_device *pdev) | 1561 | static int pxa2xx_spi_remove(struct platform_device *pdev) |
1562 | { | 1562 | { |
1563 | struct driver_data *drv_data = platform_get_drvdata(pdev); | 1563 | struct driver_data *drv_data = platform_get_drvdata(pdev); |
1564 | struct ssp_device *ssp = drv_data->ssp; | 1564 | struct ssp_device *ssp; |
1565 | int status = 0; | 1565 | int status = 0; |
1566 | 1566 | ||
1567 | if (!drv_data) | 1567 | if (!drv_data) |
1568 | return 0; | 1568 | return 0; |
1569 | ssp = drv_data->ssp; | ||
1569 | 1570 | ||
1570 | /* Remove the queue */ | 1571 | /* Remove the queue */ |
1571 | status = destroy_queue(drv_data); | 1572 | status = destroy_queue(drv_data); |
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c new file mode 100644 index 000000000000..49698cabc30d --- /dev/null +++ b/drivers/spi/spi_gpio.c | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * spi_gpio.c - SPI master driver using generic bitbanged GPIO | ||
3 | * | ||
4 | * Copyright (C) 2006,2008 David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/gpio.h> | ||
24 | |||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/spi/spi_bitbang.h> | ||
27 | #include <linux/spi/spi_gpio.h> | ||
28 | |||
29 | |||
30 | /* | ||
31 | * This bitbanging SPI master driver should help make systems usable | ||
32 | * when a native hardware SPI engine is not available, perhaps because | ||
33 | * its driver isn't yet working or because the I/O pins it requires | ||
34 | * are used for other purposes. | ||
35 | * | ||
36 | * platform_device->driver_data ... points to spi_gpio | ||
37 | * | ||
38 | * spi->controller_state ... reserved for bitbang framework code | ||
39 | * spi->controller_data ... holds chipselect GPIO | ||
40 | * | ||
41 | * spi->master->dev.driver_data ... points to spi_gpio->bitbang | ||
42 | */ | ||
43 | |||
44 | struct spi_gpio { | ||
45 | struct spi_bitbang bitbang; | ||
46 | struct spi_gpio_platform_data pdata; | ||
47 | struct platform_device *pdev; | ||
48 | }; | ||
49 | |||
50 | /*----------------------------------------------------------------------*/ | ||
51 | |||
52 | /* | ||
53 | * Because the overhead of going through four GPIO procedure calls | ||
54 | * per transferred bit can make performance a problem, this code | ||
55 | * is set up so that you can use it in either of two ways: | ||
56 | * | ||
57 | * - The slow generic way: set up platform_data to hold the GPIO | ||
58 | * numbers used for MISO/MOSI/SCK, and issue procedure calls for | ||
59 | * each of them. This driver can handle several such busses. | ||
60 | * | ||
61 | * - The quicker inlined way: only helps with platform GPIO code | ||
62 | * that inlines operations for constant GPIOs. This can give | ||
63 | * you tight (fast!) inner loops, but each such bus needs a | ||
64 | * new driver. You'll define a new C file, with Makefile and | ||
65 | * Kconfig support; the C code can be a total of six lines: | ||
66 | * | ||
67 | * #define DRIVER_NAME "myboard_spi2" | ||
68 | * #define SPI_MISO_GPIO 119 | ||
69 | * #define SPI_MOSI_GPIO 120 | ||
70 | * #define SPI_SCK_GPIO 121 | ||
71 | * #define SPI_N_CHIPSEL 4 | ||
72 | * #include "spi_gpio.c" | ||
73 | */ | ||
74 | |||
75 | #ifndef DRIVER_NAME | ||
76 | #define DRIVER_NAME "spi_gpio" | ||
77 | |||
78 | #define GENERIC_BITBANG /* vs tight inlines */ | ||
79 | |||
80 | /* all functions referencing these symbols must define pdata */ | ||
81 | #define SPI_MISO_GPIO ((pdata)->miso) | ||
82 | #define SPI_MOSI_GPIO ((pdata)->mosi) | ||
83 | #define SPI_SCK_GPIO ((pdata)->sck) | ||
84 | |||
85 | #define SPI_N_CHIPSEL ((pdata)->num_chipselect) | ||
86 | |||
87 | #endif | ||
88 | |||
89 | /*----------------------------------------------------------------------*/ | ||
90 | |||
91 | static inline const struct spi_gpio_platform_data * __pure | ||
92 | spi_to_pdata(const struct spi_device *spi) | ||
93 | { | ||
94 | const struct spi_bitbang *bang; | ||
95 | const struct spi_gpio *spi_gpio; | ||
96 | |||
97 | bang = spi_master_get_devdata(spi->master); | ||
98 | spi_gpio = container_of(bang, struct spi_gpio, bitbang); | ||
99 | return &spi_gpio->pdata; | ||
100 | } | ||
101 | |||
102 | /* this is #defined to avoid unused-variable warnings when inlining */ | ||
103 | #define pdata spi_to_pdata(spi) | ||
104 | |||
105 | static inline void setsck(const struct spi_device *spi, int is_on) | ||
106 | { | ||
107 | gpio_set_value(SPI_SCK_GPIO, is_on); | ||
108 | } | ||
109 | |||
110 | static inline void setmosi(const struct spi_device *spi, int is_on) | ||
111 | { | ||
112 | gpio_set_value(SPI_MOSI_GPIO, is_on); | ||
113 | } | ||
114 | |||
115 | static inline int getmiso(const struct spi_device *spi) | ||
116 | { | ||
117 | return gpio_get_value(SPI_MISO_GPIO); | ||
118 | } | ||
119 | |||
120 | #undef pdata | ||
121 | |||
122 | /* | ||
123 | * NOTE: this clocks "as fast as we can". It "should" be a function of the | ||
124 | * requested device clock. Software overhead means we usually have trouble | ||
125 | * reaching even one Mbit/sec (except when we can inline bitops), so for now | ||
126 | * we'll just assume we never need additional per-bit slowdowns. | ||
127 | */ | ||
128 | #define spidelay(nsecs) do {} while (0) | ||
129 | |||
130 | #define EXPAND_BITBANG_TXRX | ||
131 | #include <linux/spi/spi_bitbang.h> | ||
132 | |||
133 | /* | ||
134 | * These functions can leverage inline expansion of GPIO calls to shrink | ||
135 | * costs for a txrx bit, often by factors of around ten (by instruction | ||
136 | * count). That is particularly visible for larger word sizes, but helps | ||
137 | * even with default 8-bit words. | ||
138 | * | ||
139 | * REVISIT overheads calling these functions for each word also have | ||
140 | * significant performance costs. Having txrx_bufs() calls that inline | ||
141 | * the txrx_word() logic would help performance, e.g. on larger blocks | ||
142 | * used with flash storage or MMC/SD. There should also be ways to make | ||
143 | * GCC be less stupid about reloading registers inside the I/O loops, | ||
144 | * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? | ||
145 | */ | ||
146 | |||
147 | static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, | ||
148 | unsigned nsecs, u32 word, u8 bits) | ||
149 | { | ||
150 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); | ||
151 | } | ||
152 | |||
153 | static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, | ||
154 | unsigned nsecs, u32 word, u8 bits) | ||
155 | { | ||
156 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); | ||
157 | } | ||
158 | |||
159 | static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, | ||
160 | unsigned nsecs, u32 word, u8 bits) | ||
161 | { | ||
162 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits); | ||
163 | } | ||
164 | |||
165 | static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, | ||
166 | unsigned nsecs, u32 word, u8 bits) | ||
167 | { | ||
168 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits); | ||
169 | } | ||
170 | |||
171 | /*----------------------------------------------------------------------*/ | ||
172 | |||
173 | static void spi_gpio_chipselect(struct spi_device *spi, int is_active) | ||
174 | { | ||
175 | unsigned long cs = (unsigned long) spi->controller_data; | ||
176 | |||
177 | /* set initial clock polarity */ | ||
178 | if (is_active) | ||
179 | setsck(spi, spi->mode & SPI_CPOL); | ||
180 | |||
181 | /* SPI is normally active-low */ | ||
182 | gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); | ||
183 | } | ||
184 | |||
185 | static int spi_gpio_setup(struct spi_device *spi) | ||
186 | { | ||
187 | unsigned long cs = (unsigned long) spi->controller_data; | ||
188 | int status = 0; | ||
189 | |||
190 | if (spi->bits_per_word > 32) | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (!spi->controller_state) { | ||
194 | status = gpio_request(cs, spi->dev.bus_id); | ||
195 | if (status) | ||
196 | return status; | ||
197 | status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); | ||
198 | } | ||
199 | if (!status) | ||
200 | status = spi_bitbang_setup(spi); | ||
201 | if (status) { | ||
202 | if (!spi->controller_state) | ||
203 | gpio_free(cs); | ||
204 | } | ||
205 | return status; | ||
206 | } | ||
207 | |||
208 | static void spi_gpio_cleanup(struct spi_device *spi) | ||
209 | { | ||
210 | unsigned long cs = (unsigned long) spi->controller_data; | ||
211 | |||
212 | gpio_free(cs); | ||
213 | spi_bitbang_cleanup(spi); | ||
214 | } | ||
215 | |||
216 | static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) | ||
217 | { | ||
218 | int value; | ||
219 | |||
220 | value = gpio_request(pin, label); | ||
221 | if (value == 0) { | ||
222 | if (is_in) | ||
223 | value = gpio_direction_input(pin); | ||
224 | else | ||
225 | value = gpio_direction_output(pin, 0); | ||
226 | } | ||
227 | return value; | ||
228 | } | ||
229 | |||
230 | static int __init | ||
231 | spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label) | ||
232 | { | ||
233 | int value; | ||
234 | |||
235 | /* NOTE: SPI_*_GPIO symbols may reference "pdata" */ | ||
236 | |||
237 | value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false); | ||
238 | if (value) | ||
239 | goto done; | ||
240 | |||
241 | value = spi_gpio_alloc(SPI_MISO_GPIO, label, true); | ||
242 | if (value) | ||
243 | goto free_mosi; | ||
244 | |||
245 | value = spi_gpio_alloc(SPI_SCK_GPIO, label, false); | ||
246 | if (value) | ||
247 | goto free_miso; | ||
248 | |||
249 | goto done; | ||
250 | |||
251 | free_miso: | ||
252 | gpio_free(SPI_MISO_GPIO); | ||
253 | free_mosi: | ||
254 | gpio_free(SPI_MOSI_GPIO); | ||
255 | done: | ||
256 | return value; | ||
257 | } | ||
258 | |||
259 | static int __init spi_gpio_probe(struct platform_device *pdev) | ||
260 | { | ||
261 | int status; | ||
262 | struct spi_master *master; | ||
263 | struct spi_gpio *spi_gpio; | ||
264 | struct spi_gpio_platform_data *pdata; | ||
265 | |||
266 | pdata = pdev->dev.platform_data; | ||
267 | #ifdef GENERIC_BITBANG | ||
268 | if (!pdata || !pdata->num_chipselect) | ||
269 | return -ENODEV; | ||
270 | #endif | ||
271 | |||
272 | status = spi_gpio_request(pdata, dev_name(&pdev->dev)); | ||
273 | if (status < 0) | ||
274 | return status; | ||
275 | |||
276 | master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio); | ||
277 | if (!master) { | ||
278 | status = -ENOMEM; | ||
279 | goto gpio_free; | ||
280 | } | ||
281 | spi_gpio = spi_master_get_devdata(master); | ||
282 | platform_set_drvdata(pdev, spi_gpio); | ||
283 | |||
284 | spi_gpio->pdev = pdev; | ||
285 | if (pdata) | ||
286 | spi_gpio->pdata = *pdata; | ||
287 | |||
288 | master->bus_num = pdev->id; | ||
289 | master->num_chipselect = SPI_N_CHIPSEL; | ||
290 | master->setup = spi_gpio_setup; | ||
291 | master->cleanup = spi_gpio_cleanup; | ||
292 | |||
293 | spi_gpio->bitbang.master = spi_master_get(master); | ||
294 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | ||
295 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | ||
296 | spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; | ||
297 | spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; | ||
298 | spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; | ||
299 | spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer; | ||
300 | spi_gpio->bitbang.flags = SPI_CS_HIGH; | ||
301 | |||
302 | status = spi_bitbang_start(&spi_gpio->bitbang); | ||
303 | if (status < 0) { | ||
304 | spi_master_put(spi_gpio->bitbang.master); | ||
305 | gpio_free: | ||
306 | gpio_free(SPI_MISO_GPIO); | ||
307 | gpio_free(SPI_MOSI_GPIO); | ||
308 | gpio_free(SPI_SCK_GPIO); | ||
309 | spi_master_put(master); | ||
310 | } | ||
311 | |||
312 | return status; | ||
313 | } | ||
314 | |||
315 | static int __exit spi_gpio_remove(struct platform_device *pdev) | ||
316 | { | ||
317 | struct spi_gpio *spi_gpio; | ||
318 | struct spi_gpio_platform_data *pdata; | ||
319 | int status; | ||
320 | |||
321 | spi_gpio = platform_get_drvdata(pdev); | ||
322 | pdata = pdev->dev.platform_data; | ||
323 | |||
324 | /* stop() unregisters child devices too */ | ||
325 | status = spi_bitbang_stop(&spi_gpio->bitbang); | ||
326 | spi_master_put(spi_gpio->bitbang.master); | ||
327 | |||
328 | platform_set_drvdata(pdev, NULL); | ||
329 | |||
330 | gpio_free(SPI_MISO_GPIO); | ||
331 | gpio_free(SPI_MOSI_GPIO); | ||
332 | gpio_free(SPI_SCK_GPIO); | ||
333 | |||
334 | return status; | ||
335 | } | ||
336 | |||
337 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
338 | |||
339 | static struct platform_driver spi_gpio_driver = { | ||
340 | .driver.name = DRIVER_NAME, | ||
341 | .driver.owner = THIS_MODULE, | ||
342 | .remove = __exit_p(spi_gpio_remove), | ||
343 | }; | ||
344 | |||
345 | static int __init spi_gpio_init(void) | ||
346 | { | ||
347 | return platform_driver_probe(&spi_gpio_driver, spi_gpio_probe); | ||
348 | } | ||
349 | module_init(spi_gpio_init); | ||
350 | |||
351 | static void __exit spi_gpio_exit(void) | ||
352 | { | ||
353 | platform_driver_unregister(&spi_gpio_driver); | ||
354 | } | ||
355 | module_exit(spi_gpio_exit); | ||
356 | |||
357 | |||
358 | MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); | ||
359 | MODULE_AUTHOR("David Brownell"); | ||
360 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 256d18395a23..b3ebc1d0f85f 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/gpio.h> | ||
22 | 23 | ||
23 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
24 | #include <linux/spi/spi_bitbang.h> | 25 | #include <linux/spi/spi_bitbang.h> |
@@ -27,7 +28,6 @@ | |||
27 | #include <asm/dma.h> | 28 | #include <asm/dma.h> |
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
29 | 30 | ||
30 | #include <mach/regs-gpio.h> | ||
31 | #include <plat/regs-spi.h> | 31 | #include <plat/regs-spi.h> |
32 | #include <mach/spi.h> | 32 | #include <mach/spi.h> |
33 | 33 | ||
@@ -66,7 +66,7 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) | |||
66 | 66 | ||
67 | static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) | 67 | static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) |
68 | { | 68 | { |
69 | s3c2410_gpio_setpin(spi->pin_cs, pol); | 69 | gpio_set_value(spi->pin_cs, pol); |
70 | } | 70 | } |
71 | 71 | ||
72 | static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) | 72 | static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) |
@@ -248,8 +248,13 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) | |||
248 | writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); | 248 | writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); |
249 | writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); | 249 | writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); |
250 | 250 | ||
251 | if (hw->pdata && hw->pdata->gpio_setup) | 251 | if (hw->pdata) { |
252 | hw->pdata->gpio_setup(hw->pdata, 1); | 252 | if (hw->set_cs == s3c24xx_spi_gpiocs) |
253 | gpio_direction_output(hw->pdata->pin_cs, 1); | ||
254 | |||
255 | if (hw->pdata->gpio_setup) | ||
256 | hw->pdata->gpio_setup(hw->pdata, 1); | ||
257 | } | ||
253 | } | 258 | } |
254 | 259 | ||
255 | static int __init s3c24xx_spi_probe(struct platform_device *pdev) | 260 | static int __init s3c24xx_spi_probe(struct platform_device *pdev) |
@@ -343,18 +348,27 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
343 | goto err_no_clk; | 348 | goto err_no_clk; |
344 | } | 349 | } |
345 | 350 | ||
346 | s3c24xx_spi_initialsetup(hw); | ||
347 | |||
348 | /* setup any gpio we can */ | 351 | /* setup any gpio we can */ |
349 | 352 | ||
350 | if (!pdata->set_cs) { | 353 | if (!pdata->set_cs) { |
351 | hw->set_cs = s3c24xx_spi_gpiocs; | 354 | if (pdata->pin_cs < 0) { |
355 | dev_err(&pdev->dev, "No chipselect pin\n"); | ||
356 | goto err_register; | ||
357 | } | ||
352 | 358 | ||
353 | s3c2410_gpio_setpin(pdata->pin_cs, 1); | 359 | err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); |
354 | s3c2410_gpio_cfgpin(pdata->pin_cs, S3C2410_GPIO_OUTPUT); | 360 | if (err) { |
361 | dev_err(&pdev->dev, "Failed to get gpio for cs\n"); | ||
362 | goto err_register; | ||
363 | } | ||
364 | |||
365 | hw->set_cs = s3c24xx_spi_gpiocs; | ||
366 | gpio_direction_output(pdata->pin_cs, 1); | ||
355 | } else | 367 | } else |
356 | hw->set_cs = pdata->set_cs; | 368 | hw->set_cs = pdata->set_cs; |
357 | 369 | ||
370 | s3c24xx_spi_initialsetup(hw); | ||
371 | |||
358 | /* register our spi controller */ | 372 | /* register our spi controller */ |
359 | 373 | ||
360 | err = spi_bitbang_start(&hw->bitbang); | 374 | err = spi_bitbang_start(&hw->bitbang); |
@@ -366,6 +380,9 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
366 | return 0; | 380 | return 0; |
367 | 381 | ||
368 | err_register: | 382 | err_register: |
383 | if (hw->set_cs == s3c24xx_spi_gpiocs) | ||
384 | gpio_free(pdata->pin_cs); | ||
385 | |||
369 | clk_disable(hw->clk); | 386 | clk_disable(hw->clk); |
370 | clk_put(hw->clk); | 387 | clk_put(hw->clk); |
371 | 388 | ||
@@ -401,6 +418,9 @@ static int __exit s3c24xx_spi_remove(struct platform_device *dev) | |||
401 | free_irq(hw->irq, hw); | 418 | free_irq(hw->irq, hw); |
402 | iounmap(hw->regs); | 419 | iounmap(hw->regs); |
403 | 420 | ||
421 | if (hw->set_cs == s3c24xx_spi_gpiocs) | ||
422 | gpio_free(hw->pdata->pin_cs); | ||
423 | |||
404 | release_resource(hw->ioarea); | 424 | release_resource(hw->ioarea); |
405 | kfree(hw->ioarea); | 425 | kfree(hw->ioarea); |
406 | 426 | ||
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 243ea4ab20c8..db16112cf197 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c | |||
@@ -2051,7 +2051,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_ | |||
2051 | 2051 | ||
2052 | /* Virtualize mmio region */ | 2052 | /* Virtualize mmio region */ |
2053 | info->fix.mmio_start = reg_addr; | 2053 | info->fix.mmio_start = reg_addr; |
2054 | par->regbase = ioremap(reg_addr, pci_resource_len(pdev, 2)); | 2054 | par->regbase = pci_ioremap_bar(pdev, 2); |
2055 | if (!par->regbase) | 2055 | if (!par->regbase) |
2056 | goto err_free_info; | 2056 | goto err_free_info; |
2057 | 2057 | ||
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 7d1b819e501c..a9b3ada05d99 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -255,7 +255,7 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, | |||
255 | { | 255 | { |
256 | 256 | ||
257 | if (var->bits_per_pixel != LCD_BPP) { | 257 | if (var->bits_per_pixel != LCD_BPP) { |
258 | pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__, | 258 | pr_debug("%s: depth not supported: %u BPP\n", __func__, |
259 | var->bits_per_pixel); | 259 | var->bits_per_pixel); |
260 | return -EINVAL; | 260 | return -EINVAL; |
261 | } | 261 | } |
@@ -264,7 +264,7 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, | |||
264 | info->var.xres_virtual != var->xres_virtual || | 264 | info->var.xres_virtual != var->xres_virtual || |
265 | info->var.yres_virtual != var->yres_virtual) { | 265 | info->var.yres_virtual != var->yres_virtual) { |
266 | pr_debug("%s: Resolution not supported: X%u x Y%u \n", | 266 | pr_debug("%s: Resolution not supported: X%u x Y%u \n", |
267 | __FUNCTION__, var->xres, var->yres); | 267 | __func__, var->xres, var->yres); |
268 | return -EINVAL; | 268 | return -EINVAL; |
269 | } | 269 | } |
270 | 270 | ||
@@ -274,7 +274,7 @@ static int bfin_t350mcqb_fb_check_var(struct fb_var_screeninfo *var, | |||
274 | 274 | ||
275 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { | 275 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { |
276 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", | 276 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", |
277 | __FUNCTION__, var->yres_virtual); | 277 | __func__, var->yres_virtual); |
278 | return -ENOMEM; | 278 | return -ENOMEM; |
279 | } | 279 | } |
280 | 280 | ||
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c index c9b191319a9a..c7ff3c1a266a 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/carminefb.c | |||
@@ -168,7 +168,7 @@ static int carmine_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
168 | blue >>= 8; | 168 | blue >>= 8; |
169 | transp >>= 8; | 169 | transp >>= 8; |
170 | 170 | ||
171 | ((u32 *)info->pseudo_palette)[regno] = be32_to_cpu(transp << 24 | | 171 | ((__be32 *)info->pseudo_palette)[regno] = cpu_to_be32(transp << 24 | |
172 | red << 0 | green << 8 | blue << 16); | 172 | red << 0 | green << 8 | blue << 16); |
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c index 39d5d643a50b..7a9e42e3a9a9 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/cyber2000fb.c | |||
@@ -1583,8 +1583,7 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1583 | goto failed_release; | 1583 | goto failed_release; |
1584 | 1584 | ||
1585 | cfb->dev = dev; | 1585 | cfb->dev = dev; |
1586 | cfb->region = ioremap(pci_resource_start(dev, 0), | 1586 | cfb->region = pci_ioremap_bar(dev, 0); |
1587 | pci_resource_len(dev, 0)); | ||
1588 | if (!cfb->region) | 1587 | if (!cfb->region) |
1589 | goto failed_ioremap; | 1588 | goto failed_ioremap; |
1590 | 1589 | ||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 3c65b0d67617..756efeb91abc 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -510,6 +510,10 @@ static int fb_prepare_extra_logos(struct fb_info *info, unsigned int height, | |||
510 | fb_logo_ex_num = 0; | 510 | fb_logo_ex_num = 0; |
511 | 511 | ||
512 | for (i = 0; i < fb_logo_ex_num; i++) { | 512 | for (i = 0; i < fb_logo_ex_num; i++) { |
513 | if (fb_logo_ex[i].logo->type != fb_logo.logo->type) { | ||
514 | fb_logo_ex[i].logo = NULL; | ||
515 | continue; | ||
516 | } | ||
513 | height += fb_logo_ex[i].logo->height; | 517 | height += fb_logo_ex[i].logo->height; |
514 | if (height > yres) { | 518 | if (height > yres) { |
515 | height -= fb_logo_ex[i].logo->height; | 519 | height -= fb_logo_ex[i].logo->height; |
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index f89c3cce1e0c..fe5b519860b1 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c | |||
@@ -912,6 +912,7 @@ static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
912 | { | 912 | { |
913 | unsigned int line_length; | 913 | unsigned int line_length; |
914 | struct gbe_timing_info timing; | 914 | struct gbe_timing_info timing; |
915 | int ret; | ||
915 | 916 | ||
916 | /* Limit bpp to 8, 16, and 32 */ | 917 | /* Limit bpp to 8, 16, and 32 */ |
917 | if (var->bits_per_pixel <= 8) | 918 | if (var->bits_per_pixel <= 8) |
@@ -930,8 +931,10 @@ static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
930 | 931 | ||
931 | var->grayscale = 0; /* No grayscale for now */ | 932 | var->grayscale = 0; /* No grayscale for now */ |
932 | 933 | ||
933 | if ((var->pixclock = compute_gbe_timing(var, &timing)) < 0) | 934 | ret = compute_gbe_timing(var, &timing); |
934 | return(-EINVAL); | 935 | var->pixclock = ret; |
936 | if (ret < 0) | ||
937 | return -EINVAL; | ||
935 | 938 | ||
936 | /* Adjust virtual resolution, if necessary */ | 939 | /* Adjust virtual resolution, if necessary */ |
937 | if (var->xres > var->xres_virtual || (!ywrap && !ypan)) | 940 | if (var->xres > var->xres_virtual || (!ywrap && !ypan)) |
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c index bb20a2289760..751e491ca8c8 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/geode/gx1fb_core.c | |||
@@ -217,8 +217,7 @@ static int __init gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *d | |||
217 | ret = pci_request_region(dev, 0, "gx1fb (video)"); | 217 | ret = pci_request_region(dev, 0, "gx1fb (video)"); |
218 | if (ret < 0) | 218 | if (ret < 0) |
219 | return ret; | 219 | return ret; |
220 | par->vid_regs = ioremap(pci_resource_start(dev, 0), | 220 | par->vid_regs = pci_ioremap_bar(dev, 0); |
221 | pci_resource_len(dev, 0)); | ||
222 | if (!par->vid_regs) | 221 | if (!par->vid_regs) |
223 | return -ENOMEM; | 222 | return -ENOMEM; |
224 | 223 | ||
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index de2b8f9876a5..484118926318 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c | |||
@@ -242,23 +242,21 @@ static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *de | |||
242 | ret = pci_request_region(dev, 3, "gxfb (video processor)"); | 242 | ret = pci_request_region(dev, 3, "gxfb (video processor)"); |
243 | if (ret < 0) | 243 | if (ret < 0) |
244 | return ret; | 244 | return ret; |
245 | par->vid_regs = ioremap(pci_resource_start(dev, 3), | 245 | par->vid_regs = pci_ioremap_bar(dev, 3); |
246 | pci_resource_len(dev, 3)); | ||
247 | if (!par->vid_regs) | 246 | if (!par->vid_regs) |
248 | return -ENOMEM; | 247 | return -ENOMEM; |
249 | 248 | ||
250 | ret = pci_request_region(dev, 2, "gxfb (display controller)"); | 249 | ret = pci_request_region(dev, 2, "gxfb (display controller)"); |
251 | if (ret < 0) | 250 | if (ret < 0) |
252 | return ret; | 251 | return ret; |
253 | par->dc_regs = ioremap(pci_resource_start(dev, 2), pci_resource_len(dev, 2)); | 252 | par->dc_regs = pci_ioremap_bar(dev, 2); |
254 | if (!par->dc_regs) | 253 | if (!par->dc_regs) |
255 | return -ENOMEM; | 254 | return -ENOMEM; |
256 | 255 | ||
257 | ret = pci_request_region(dev, 1, "gxfb (graphics processor)"); | 256 | ret = pci_request_region(dev, 1, "gxfb (graphics processor)"); |
258 | if (ret < 0) | 257 | if (ret < 0) |
259 | return ret; | 258 | return ret; |
260 | par->gp_regs = ioremap(pci_resource_start(dev, 1), | 259 | par->gp_regs = pci_ioremap_bar(dev, 1); |
261 | pci_resource_len(dev, 1)); | ||
262 | 260 | ||
263 | if (!par->gp_regs) | 261 | if (!par->gp_regs) |
264 | return -ENOMEM; | 262 | return -ENOMEM; |
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c index 2cd9b74d2225..b965ecdbc604 100644 --- a/drivers/video/geode/lxfb_core.c +++ b/drivers/video/geode/lxfb_core.c | |||
@@ -379,20 +379,17 @@ static int __init lxfb_map_video_memory(struct fb_info *info, | |||
379 | if (info->screen_base == NULL) | 379 | if (info->screen_base == NULL) |
380 | return ret; | 380 | return ret; |
381 | 381 | ||
382 | par->gp_regs = ioremap(pci_resource_start(dev, 1), | 382 | par->gp_regs = pci_ioremap_bar(dev, 1); |
383 | pci_resource_len(dev, 1)); | ||
384 | 383 | ||
385 | if (par->gp_regs == NULL) | 384 | if (par->gp_regs == NULL) |
386 | return ret; | 385 | return ret; |
387 | 386 | ||
388 | par->dc_regs = ioremap(pci_resource_start(dev, 2), | 387 | par->dc_regs = pci_ioremap_bar(dev, 2); |
389 | pci_resource_len(dev, 2)); | ||
390 | 388 | ||
391 | if (par->dc_regs == NULL) | 389 | if (par->dc_regs == NULL) |
392 | return ret; | 390 | return ret; |
393 | 391 | ||
394 | par->vp_regs = ioremap(pci_resource_start(dev, 3), | 392 | par->vp_regs = pci_ioremap_bar(dev, 3); |
395 | pci_resource_len(dev, 3)); | ||
396 | 393 | ||
397 | if (par->vp_regs == NULL) | 394 | if (par->vp_regs == NULL) |
398 | return ret; | 395 | return ret; |
diff --git a/drivers/video/gxt4500.c b/drivers/video/gxt4500.c index 564557792bed..896e53dea906 100644 --- a/drivers/video/gxt4500.c +++ b/drivers/video/gxt4500.c | |||
@@ -648,7 +648,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev, | |||
648 | info->pseudo_palette = par->pseudo_palette; | 648 | info->pseudo_palette = par->pseudo_palette; |
649 | 649 | ||
650 | info->fix.mmio_start = reg_phys; | 650 | info->fix.mmio_start = reg_phys; |
651 | par->regs = ioremap(reg_phys, pci_resource_len(pdev, 0)); | 651 | par->regs = pci_ioremap_bar(pdev, 0); |
652 | if (!par->regs) { | 652 | if (!par->regs) { |
653 | dev_err(&pdev->dev, "gxt4500: cannot map registers\n"); | 653 | dev_err(&pdev->dev, "gxt4500: cannot map registers\n"); |
654 | goto err_free_all; | 654 | goto err_free_all; |
@@ -656,7 +656,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev, | |||
656 | 656 | ||
657 | info->fix.smem_start = fb_phys; | 657 | info->fix.smem_start = fb_phys; |
658 | info->fix.smem_len = pci_resource_len(pdev, 1); | 658 | info->fix.smem_len = pci_resource_len(pdev, 1); |
659 | info->screen_base = ioremap(fb_phys, pci_resource_len(pdev, 1)); | 659 | info->screen_base = pci_ioremap_bar(pdev, 1); |
660 | if (!info->screen_base) { | 660 | if (!info->screen_base) { |
661 | dev_err(&pdev->dev, "gxt4500: cannot map framebuffer\n"); | 661 | dev_err(&pdev->dev, "gxt4500: cannot map framebuffer\n"); |
662 | goto err_unmap_regs; | 662 | goto err_unmap_regs; |
diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c index 76764ea3486a..f5bedee4310a 100644 --- a/drivers/video/i810/i810_accel.c +++ b/drivers/video/i810/i810_accel.c | |||
@@ -301,8 +301,10 @@ void i810fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
301 | u32 dx, dy, width, height, dest, rop = 0, color = 0; | 301 | u32 dx, dy, width, height, dest, rop = 0, color = 0; |
302 | 302 | ||
303 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 303 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
304 | par->depth == 4) | 304 | par->depth == 4) { |
305 | return cfb_fillrect(info, rect); | 305 | cfb_fillrect(info, rect); |
306 | return; | ||
307 | } | ||
306 | 308 | ||
307 | if (par->depth == 1) | 309 | if (par->depth == 1) |
308 | color = rect->color; | 310 | color = rect->color; |
@@ -327,8 +329,10 @@ void i810fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
327 | u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; | 329 | u32 sx, sy, dx, dy, pitch, width, height, src, dest, xdir; |
328 | 330 | ||
329 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 331 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
330 | par->depth == 4) | 332 | par->depth == 4) { |
331 | return cfb_copyarea(info, region); | 333 | cfb_copyarea(info, region); |
334 | return; | ||
335 | } | ||
332 | 336 | ||
333 | dx = region->dx * par->depth; | 337 | dx = region->dx * par->depth; |
334 | sx = region->sx * par->depth; | 338 | sx = region->sx * par->depth; |
@@ -366,8 +370,10 @@ void i810fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
366 | u32 fg = 0, bg = 0, size, dst; | 370 | u32 fg = 0, bg = 0, size, dst; |
367 | 371 | ||
368 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || | 372 | if (!info->var.accel_flags || par->dev_flags & LOCKUP || |
369 | par->depth == 4 || image->depth != 1) | 373 | par->depth == 4 || image->depth != 1) { |
370 | return cfb_imageblit(info, image); | 374 | cfb_imageblit(info, image); |
375 | return; | ||
376 | } | ||
371 | 377 | ||
372 | switch (info->var.bits_per_pixel) { | 378 | switch (info->var.bits_per_pixel) { |
373 | case 8: | 379 | case 8: |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index a09e23649357..6d8e5415c809 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -1493,8 +1493,10 @@ static void intelfb_fillrect (struct fb_info *info, | |||
1493 | DBG_MSG("intelfb_fillrect\n"); | 1493 | DBG_MSG("intelfb_fillrect\n"); |
1494 | #endif | 1494 | #endif |
1495 | 1495 | ||
1496 | if (!ACCEL(dinfo, info) || dinfo->depth == 4) | 1496 | if (!ACCEL(dinfo, info) || dinfo->depth == 4) { |
1497 | return cfb_fillrect(info, rect); | 1497 | cfb_fillrect(info, rect); |
1498 | return; | ||
1499 | } | ||
1498 | 1500 | ||
1499 | if (rect->rop == ROP_COPY) | 1501 | if (rect->rop == ROP_COPY) |
1500 | rop = PAT_ROP_GXCOPY; | 1502 | rop = PAT_ROP_GXCOPY; |
@@ -1521,8 +1523,10 @@ static void intelfb_copyarea(struct fb_info *info, | |||
1521 | DBG_MSG("intelfb_copyarea\n"); | 1523 | DBG_MSG("intelfb_copyarea\n"); |
1522 | #endif | 1524 | #endif |
1523 | 1525 | ||
1524 | if (!ACCEL(dinfo, info) || dinfo->depth == 4) | 1526 | if (!ACCEL(dinfo, info) || dinfo->depth == 4) { |
1525 | return cfb_copyarea(info, region); | 1527 | cfb_copyarea(info, region); |
1528 | return; | ||
1529 | } | ||
1526 | 1530 | ||
1527 | intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, | 1531 | intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, |
1528 | region->dy, region->width, region->height, | 1532 | region->dy, region->width, region->height, |
@@ -1540,8 +1544,10 @@ static void intelfb_imageblit(struct fb_info *info, | |||
1540 | #endif | 1544 | #endif |
1541 | 1545 | ||
1542 | if (!ACCEL(dinfo, info) || dinfo->depth == 4 | 1546 | if (!ACCEL(dinfo, info) || dinfo->depth == 4 |
1543 | || image->depth != 1) | 1547 | || image->depth != 1) { |
1544 | return cfb_imageblit(info, image); | 1548 | cfb_imageblit(info, image); |
1549 | return; | ||
1550 | } | ||
1545 | 1551 | ||
1546 | if (dinfo->depth != 8) { | 1552 | if (dinfo->depth != 8) { |
1547 | fgcolor = dinfo->pseudo_palette[image->fg_color]; | 1553 | fgcolor = dinfo->pseudo_palette[image->fg_color]; |
@@ -1554,8 +1560,10 @@ static void intelfb_imageblit(struct fb_info *info, | |||
1554 | if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width, | 1560 | if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width, |
1555 | image->height, image->data, | 1561 | image->height, image->data, |
1556 | image->dx, image->dy, | 1562 | image->dx, image->dy, |
1557 | dinfo->pitch, info->var.bits_per_pixel)) | 1563 | dinfo->pitch, info->var.bits_per_pixel)) { |
1558 | return cfb_imageblit(info, image); | 1564 | cfb_imageblit(info, image); |
1565 | return; | ||
1566 | } | ||
1559 | } | 1567 | } |
1560 | 1568 | ||
1561 | static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) | 1569 | static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index d3c3af53a290..16186240c5f2 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -329,7 +329,7 @@ const struct fb_videomode vesa_modes[] = { | |||
329 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 329 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
330 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | 330 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, |
331 | /* 17 1152x864-75 VESA */ | 331 | /* 17 1152x864-75 VESA */ |
332 | { NULL, 75, 1153, 864, 9259, 256, 64, 32, 1, 128, 3, | 332 | { NULL, 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3, |
333 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 333 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
334 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, | 334 | FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, |
335 | /* 18 1280x960-60 VESA */ | 335 | /* 18 1280x960-60 VESA */ |
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index bfb802d26d5a..588527a254c2 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -1453,7 +1453,8 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1453 | * is less than 16 bits wide. This is due to insufficient | 1453 | * is less than 16 bits wide. This is due to insufficient |
1454 | * padding when writing the image. We need to adjust | 1454 | * padding when writing the image. We need to adjust |
1455 | * struct fb_pixmap. Not yet done. */ | 1455 | * struct fb_pixmap. Not yet done. */ |
1456 | return cfb_imageblit(info, image); | 1456 | cfb_imageblit(info, image); |
1457 | return; | ||
1457 | } | 1458 | } |
1458 | bltCntl_flags = NEO_BC0_SRC_MONO; | 1459 | bltCntl_flags = NEO_BC0_SRC_MONO; |
1459 | } else if (image->depth == info->var.bits_per_pixel) { | 1460 | } else if (image->depth == info->var.bits_per_pixel) { |
@@ -1461,7 +1462,8 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1461 | } else { | 1462 | } else { |
1462 | /* We don't currently support hardware acceleration if image | 1463 | /* We don't currently support hardware acceleration if image |
1463 | * depth is different from display */ | 1464 | * depth is different from display */ |
1464 | return cfb_imageblit(info, image); | 1465 | cfb_imageblit(info, image); |
1466 | return; | ||
1465 | } | 1467 | } |
1466 | 1468 | ||
1467 | switch (info->var.bits_per_pixel) { | 1469 | switch (info->var.bits_per_pixel) { |
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c index fa4821c5572b..ad6472a894ea 100644 --- a/drivers/video/nvidia/nv_accel.c +++ b/drivers/video/nvidia/nv_accel.c | |||
@@ -300,8 +300,10 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region) | |||
300 | if (info->state != FBINFO_STATE_RUNNING) | 300 | if (info->state != FBINFO_STATE_RUNNING) |
301 | return; | 301 | return; |
302 | 302 | ||
303 | if (par->lockup) | 303 | if (par->lockup) { |
304 | return cfb_copyarea(info, region); | 304 | cfb_copyarea(info, region); |
305 | return; | ||
306 | } | ||
305 | 307 | ||
306 | NVDmaStart(info, par, BLIT_POINT_SRC, 3); | 308 | NVDmaStart(info, par, BLIT_POINT_SRC, 3); |
307 | NVDmaNext(par, (region->sy << 16) | region->sx); | 309 | NVDmaNext(par, (region->sy << 16) | region->sx); |
@@ -319,8 +321,10 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | |||
319 | if (info->state != FBINFO_STATE_RUNNING) | 321 | if (info->state != FBINFO_STATE_RUNNING) |
320 | return; | 322 | return; |
321 | 323 | ||
322 | if (par->lockup) | 324 | if (par->lockup) { |
323 | return cfb_fillrect(info, rect); | 325 | cfb_fillrect(info, rect); |
326 | return; | ||
327 | } | ||
324 | 328 | ||
325 | if (info->var.bits_per_pixel == 8) | 329 | if (info->var.bits_per_pixel == 8) |
326 | color = rect->color; | 330 | color = rect->color; |
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 68089d1456c2..6666f45a2f8c 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c | |||
@@ -539,8 +539,10 @@ static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
539 | bgx = par->palette[image->bg_color]; | 539 | bgx = par->palette[image->bg_color]; |
540 | break; | 540 | break; |
541 | } | 541 | } |
542 | if (image->depth != 1) | 542 | if (image->depth != 1) { |
543 | return cfb_imageblit(info, image); | 543 | cfb_imageblit(info, image); |
544 | return; | ||
545 | } | ||
544 | 546 | ||
545 | if (info->var.bits_per_pixel == 8) { | 547 | if (info->var.bits_per_pixel == 8) { |
546 | fgx |= fgx << 8; | 548 | fgx |= fgx << 8; |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index f94ae84a58cd..dcd98793d568 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -159,6 +159,9 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
159 | break; | 159 | break; |
160 | 160 | ||
161 | case SM501_MEMF_PANEL: | 161 | case SM501_MEMF_PANEL: |
162 | if (size > inf->fbmem_len) | ||
163 | return -ENOMEM; | ||
164 | |||
162 | ptr = inf->fbmem_len - size; | 165 | ptr = inf->fbmem_len - size; |
163 | fbi = inf->fb[HEAD_CRT]; | 166 | fbi = inf->fb[HEAD_CRT]; |
164 | 167 | ||
@@ -172,9 +175,6 @@ static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, | |||
172 | if (fbi && ptr < fbi->fix.smem_len) | 175 | if (fbi && ptr < fbi->fix.smem_len) |
173 | return -ENOMEM; | 176 | return -ENOMEM; |
174 | 177 | ||
175 | if (ptr < 0) | ||
176 | return -ENOMEM; | ||
177 | |||
178 | break; | 178 | break; |
179 | 179 | ||
180 | case SM501_MEMF_CRT: | 180 | case SM501_MEMF_CRT: |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index e21fe5b6f9ff..37b433a08ce8 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -870,8 +870,10 @@ static void viafb_fillrect(struct fb_info *info, | |||
870 | u32 col = 0, rop = 0; | 870 | u32 col = 0, rop = 0; |
871 | int pitch; | 871 | int pitch; |
872 | 872 | ||
873 | if (!viafb_accel) | 873 | if (!viafb_accel) { |
874 | return cfb_fillrect(info, rect); | 874 | cfb_fillrect(info, rect); |
875 | return; | ||
876 | } | ||
875 | 877 | ||
876 | if (!rect->width || !rect->height) | 878 | if (!rect->width || !rect->height) |
877 | return; | 879 | return; |
@@ -937,8 +939,10 @@ static void viafb_copyarea(struct fb_info *info, | |||
937 | 939 | ||
938 | DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); | 940 | DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); |
939 | 941 | ||
940 | if (!viafb_accel) | 942 | if (!viafb_accel) { |
941 | return cfb_copyarea(info, area); | 943 | cfb_copyarea(info, area); |
944 | return; | ||
945 | } | ||
942 | 946 | ||
943 | if (!area->width || !area->height) | 947 | if (!area->width || !area->height) |
944 | return; | 948 | return; |
@@ -994,8 +998,10 @@ static void viafb_imageblit(struct fb_info *info, | |||
994 | int i; | 998 | int i; |
995 | int pitch; | 999 | int pitch; |
996 | 1000 | ||
997 | if (!viafb_accel) | 1001 | if (!viafb_accel) { |
998 | return cfb_imageblit(info, image); | 1002 | cfb_imageblit(info, image); |
1003 | return; | ||
1004 | } | ||
999 | 1005 | ||
1000 | udata = (u32 *) image->data; | 1006 | udata = (u32 *) image->data; |
1001 | 1007 | ||