diff options
Diffstat (limited to 'drivers')
27 files changed, 645 insertions, 554 deletions
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c index 67fbd7aab5d..34d15d54823 100644 --- a/drivers/char/efirtc.c +++ b/drivers/char/efirtc.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/rtc.h> | 37 | #include <linux/rtc.h> |
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/efi.h> | 39 | #include <linux/efi.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
42 | 41 | ||
43 | #include <asm/system.h> | 42 | #include <asm/system.h> |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 82a51f38a54..1bc00c9d860 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -916,7 +916,6 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
916 | ws.ws_col = vc->vc_cols; | 916 | ws.ws_col = vc->vc_cols; |
917 | ws.ws_ypixel = vc->vc_scan_lines; | 917 | ws.ws_ypixel = vc->vc_scan_lines; |
918 | 918 | ||
919 | mutex_lock(&vc->vc_tty->termios_mutex); | ||
920 | spin_lock_irq(&vc->vc_tty->ctrl_lock); | 919 | spin_lock_irq(&vc->vc_tty->ctrl_lock); |
921 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) | 920 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) |
922 | pgrp = get_pid(vc->vc_tty->pgrp); | 921 | pgrp = get_pid(vc->vc_tty->pgrp); |
@@ -926,7 +925,6 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
926 | put_pid(pgrp); | 925 | put_pid(pgrp); |
927 | } | 926 | } |
928 | *cws = ws; | 927 | *cws = ws; |
929 | mutex_unlock(&vc->vc_tty->termios_mutex); | ||
930 | } | 928 | } |
931 | 929 | ||
932 | if (CON_IS_VISIBLE(vc)) | 930 | if (CON_IS_VISIBLE(vc)) |
diff --git a/drivers/isdn/Makefile b/drivers/isdn/Makefile index 8380a4568d1..f1f777570e8 100644 --- a/drivers/isdn/Makefile +++ b/drivers/isdn/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-$(CONFIG_ISDN_I4L) += i4l/ | 5 | obj-$(CONFIG_ISDN_I4L) += i4l/ |
6 | obj-$(CONFIG_ISDN_CAPI) += capi/ | 6 | obj-$(CONFIG_ISDN_CAPI) += capi/ |
7 | obj-$(CONFIG_MISDN) += mISDN/ | 7 | obj-$(CONFIG_MISDN) += mISDN/ |
8 | obj-$(CONFIG_ISDN_CAPI) += hardware/ | 8 | obj-$(CONFIG_ISDN) += hardware/ |
9 | obj-$(CONFIG_ISDN_DIVERSION) += divert/ | 9 | obj-$(CONFIG_ISDN_DIVERSION) += divert/ |
10 | obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/ | 10 | obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/ |
11 | obj-$(CONFIG_ISDN_DRV_ICN) += icn/ | 11 | obj-$(CONFIG_ISDN_DRV_ICN) += icn/ |
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 2649ea55a9e..1eac03f39d0 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -140,7 +140,7 @@ | |||
140 | * #define HFC_REGISTER_DEBUG | 140 | * #define HFC_REGISTER_DEBUG |
141 | */ | 141 | */ |
142 | 142 | ||
143 | static const char *hfcmulti_revision = "2.00"; | 143 | static const char *hfcmulti_revision = "2.02"; |
144 | 144 | ||
145 | #include <linux/module.h> | 145 | #include <linux/module.h> |
146 | #include <linux/pci.h> | 146 | #include <linux/pci.h> |
@@ -427,12 +427,12 @@ write_fifo_regio(struct hfc_multi *hc, u_char *data, int len) | |||
427 | { | 427 | { |
428 | outb(A_FIFO_DATA0, (hc->pci_iobase)+4); | 428 | outb(A_FIFO_DATA0, (hc->pci_iobase)+4); |
429 | while (len>>2) { | 429 | while (len>>2) { |
430 | outl(*(u32 *)data, hc->pci_iobase); | 430 | outl(cpu_to_le32(*(u32 *)data), hc->pci_iobase); |
431 | data += 4; | 431 | data += 4; |
432 | len -= 4; | 432 | len -= 4; |
433 | } | 433 | } |
434 | while (len>>1) { | 434 | while (len>>1) { |
435 | outw(*(u16 *)data, hc->pci_iobase); | 435 | outw(cpu_to_le16(*(u16 *)data), hc->pci_iobase); |
436 | data += 2; | 436 | data += 2; |
437 | len -= 2; | 437 | len -= 2; |
438 | } | 438 | } |
@@ -447,17 +447,19 @@ void | |||
447 | write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) | 447 | write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) |
448 | { | 448 | { |
449 | while (len>>2) { | 449 | while (len>>2) { |
450 | writel(*(u32 *)data, (hc->pci_membase)+A_FIFO_DATA0); | 450 | writel(cpu_to_le32(*(u32 *)data), |
451 | hc->pci_membase + A_FIFO_DATA0); | ||
451 | data += 4; | 452 | data += 4; |
452 | len -= 4; | 453 | len -= 4; |
453 | } | 454 | } |
454 | while (len>>1) { | 455 | while (len>>1) { |
455 | writew(*(u16 *)data, (hc->pci_membase)+A_FIFO_DATA0); | 456 | writew(cpu_to_le16(*(u16 *)data), |
457 | hc->pci_membase + A_FIFO_DATA0); | ||
456 | data += 2; | 458 | data += 2; |
457 | len -= 2; | 459 | len -= 2; |
458 | } | 460 | } |
459 | while (len) { | 461 | while (len) { |
460 | writeb(*data, (hc->pci_membase)+A_FIFO_DATA0); | 462 | writeb(*data, hc->pci_membase + A_FIFO_DATA0); |
461 | data++; | 463 | data++; |
462 | len--; | 464 | len--; |
463 | } | 465 | } |
@@ -468,12 +470,12 @@ read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) | |||
468 | { | 470 | { |
469 | outb(A_FIFO_DATA0, (hc->pci_iobase)+4); | 471 | outb(A_FIFO_DATA0, (hc->pci_iobase)+4); |
470 | while (len>>2) { | 472 | while (len>>2) { |
471 | *(u32 *)data = inl(hc->pci_iobase); | 473 | *(u32 *)data = le32_to_cpu(inl(hc->pci_iobase)); |
472 | data += 4; | 474 | data += 4; |
473 | len -= 4; | 475 | len -= 4; |
474 | } | 476 | } |
475 | while (len>>1) { | 477 | while (len>>1) { |
476 | *(u16 *)data = inw(hc->pci_iobase); | 478 | *(u16 *)data = le16_to_cpu(inw(hc->pci_iobase)); |
477 | data += 2; | 479 | data += 2; |
478 | len -= 2; | 480 | len -= 2; |
479 | } | 481 | } |
@@ -490,18 +492,18 @@ read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) | |||
490 | { | 492 | { |
491 | while (len>>2) { | 493 | while (len>>2) { |
492 | *(u32 *)data = | 494 | *(u32 *)data = |
493 | readl((hc->pci_membase)+A_FIFO_DATA0); | 495 | le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0)); |
494 | data += 4; | 496 | data += 4; |
495 | len -= 4; | 497 | len -= 4; |
496 | } | 498 | } |
497 | while (len>>1) { | 499 | while (len>>1) { |
498 | *(u16 *)data = | 500 | *(u16 *)data = |
499 | readw((hc->pci_membase)+A_FIFO_DATA0); | 501 | le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0)); |
500 | data += 2; | 502 | data += 2; |
501 | len -= 2; | 503 | len -= 2; |
502 | } | 504 | } |
503 | while (len) { | 505 | while (len) { |
504 | *data = readb((hc->pci_membase)+A_FIFO_DATA0); | 506 | *data = readb(hc->pci_membase + A_FIFO_DATA0); |
505 | data++; | 507 | data++; |
506 | len--; | 508 | len--; |
507 | } | 509 | } |
@@ -3971,7 +3973,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, | |||
3971 | struct bchannel *bch; | 3973 | struct bchannel *bch; |
3972 | int ch; | 3974 | int ch; |
3973 | 3975 | ||
3974 | if (!test_bit(rq->adr.channel, &dch->dev.channelmap[0])) | 3976 | if (!test_channelmap(rq->adr.channel, dch->dev.channelmap)) |
3975 | return -EINVAL; | 3977 | return -EINVAL; |
3976 | if (rq->protocol == ISDN_P_NONE) | 3978 | if (rq->protocol == ISDN_P_NONE) |
3977 | return -EINVAL; | 3979 | return -EINVAL; |
@@ -4587,7 +4589,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m) | |||
4587 | list_add(&bch->ch.list, &dch->dev.bchannels); | 4589 | list_add(&bch->ch.list, &dch->dev.bchannels); |
4588 | hc->chan[ch].bch = bch; | 4590 | hc->chan[ch].bch = bch; |
4589 | hc->chan[ch].port = 0; | 4591 | hc->chan[ch].port = 0; |
4590 | test_and_set_bit(bch->nr, &dch->dev.channelmap[0]); | 4592 | set_channelmap(bch->nr, dch->dev.channelmap); |
4591 | } | 4593 | } |
4592 | /* set optical line type */ | 4594 | /* set optical line type */ |
4593 | if (port[Port_cnt] & 0x001) { | 4595 | if (port[Port_cnt] & 0x001) { |
@@ -4755,7 +4757,7 @@ init_multi_port(struct hfc_multi *hc, int pt) | |||
4755 | list_add(&bch->ch.list, &dch->dev.bchannels); | 4757 | list_add(&bch->ch.list, &dch->dev.bchannels); |
4756 | hc->chan[i + ch].bch = bch; | 4758 | hc->chan[i + ch].bch = bch; |
4757 | hc->chan[i + ch].port = pt; | 4759 | hc->chan[i + ch].port = pt; |
4758 | test_and_set_bit(bch->nr, &dch->dev.channelmap[0]); | 4760 | set_channelmap(bch->nr, dch->dev.channelmap); |
4759 | } | 4761 | } |
4760 | /* set master clock */ | 4762 | /* set master clock */ |
4761 | if (port[Port_cnt] & 0x001) { | 4763 | if (port[Port_cnt] & 0x001) { |
@@ -5050,12 +5052,12 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev) | |||
5050 | 5052 | ||
5051 | static const struct hm_map hfcm_map[] = { | 5053 | static const struct hm_map hfcm_map[] = { |
5052 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0}, | 5054 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0}, |
5053 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S}, | 5055 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0}, |
5054 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0}, | 5056 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0}, |
5055 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0}, | 5057 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0}, |
5056 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0}, | 5058 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0}, |
5057 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0}, | 5059 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0}, |
5058 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, 0, 0}, | 5060 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0}, |
5059 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0}, | 5061 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0}, |
5060 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO}, | 5062 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO}, |
5061 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0}, | 5063 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0}, |
@@ -5251,9 +5253,6 @@ HFCmulti_init(void) | |||
5251 | if (debug & DEBUG_HFCMULTI_INIT) | 5253 | if (debug & DEBUG_HFCMULTI_INIT) |
5252 | printk(KERN_DEBUG "%s: init entered\n", __func__); | 5254 | printk(KERN_DEBUG "%s: init entered\n", __func__); |
5253 | 5255 | ||
5254 | #ifdef __BIG_ENDIAN | ||
5255 | #error "not running on big endian machines now" | ||
5256 | #endif | ||
5257 | hfc_interrupt = symbol_get(ztdummy_extern_interrupt); | 5256 | hfc_interrupt = symbol_get(ztdummy_extern_interrupt); |
5258 | register_interrupt = symbol_get(ztdummy_register_interrupt); | 5257 | register_interrupt = symbol_get(ztdummy_register_interrupt); |
5259 | unregister_interrupt = symbol_get(ztdummy_unregister_interrupt); | 5258 | unregister_interrupt = symbol_get(ztdummy_unregister_interrupt); |
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 3231814e7ef..9cf5edbb1a9 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c | |||
@@ -2056,7 +2056,7 @@ setup_card(struct hfc_pci *card) | |||
2056 | card->dch.dev.nrbchan = 2; | 2056 | card->dch.dev.nrbchan = 2; |
2057 | for (i = 0; i < 2; i++) { | 2057 | for (i = 0; i < 2; i++) { |
2058 | card->bch[i].nr = i + 1; | 2058 | card->bch[i].nr = i + 1; |
2059 | test_and_set_bit(i + 1, &card->dch.dev.channelmap[0]); | 2059 | set_channelmap(i + 1, card->dch.dev.channelmap); |
2060 | card->bch[i].debug = debug; | 2060 | card->bch[i].debug = debug; |
2061 | mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); | 2061 | mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); |
2062 | card->bch[i].hw = card; | 2062 | card->bch[i].hw = card; |
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 155b99780c4..e42150a5778 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -1006,8 +1006,7 @@ open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq) | |||
1006 | struct bchannel *bch; | 1006 | struct bchannel *bch; |
1007 | int ch; | 1007 | int ch; |
1008 | 1008 | ||
1009 | if (!test_bit(rq->adr.channel & 0x1f, | 1009 | if (!test_channelmap(rq->adr.channel, dch->dev.channelmap)) |
1010 | &dch->dev.channelmap[rq->adr.channel >> 5])) | ||
1011 | return -EINVAL; | 1010 | return -EINVAL; |
1012 | if (rq->protocol == ISDN_P_NONE) | 1011 | if (rq->protocol == ISDN_P_NONE) |
1013 | return -EINVAL; | 1012 | return -EINVAL; |
@@ -1412,8 +1411,7 @@ init_card(struct l1oip *hc, int pri, int bundle) | |||
1412 | bch->ch.nr = i + ch; | 1411 | bch->ch.nr = i + ch; |
1413 | list_add(&bch->ch.list, &dch->dev.bchannels); | 1412 | list_add(&bch->ch.list, &dch->dev.bchannels); |
1414 | hc->chan[i + ch].bch = bch; | 1413 | hc->chan[i + ch].bch = bch; |
1415 | test_and_set_bit(bch->nr & 0x1f, | 1414 | set_channelmap(bch->nr, dch->dev.channelmap); |
1416 | &dch->dev.channelmap[bch->nr >> 5]); | ||
1417 | } | 1415 | } |
1418 | ret = mISDN_register_device(&dch->dev, hc->name); | 1416 | ret = mISDN_register_device(&dch->dev, hc->name); |
1419 | if (ret) | 1417 | if (ret) |
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 4ba4cc364c9..e5a20f9542d 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c | |||
@@ -379,7 +379,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
379 | di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); | 379 | di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); |
380 | di.protocol = dev->D.protocol; | 380 | di.protocol = dev->D.protocol; |
381 | memcpy(di.channelmap, dev->channelmap, | 381 | memcpy(di.channelmap, dev->channelmap, |
382 | MISDN_CHMAP_SIZE * 4); | 382 | sizeof(di.channelmap)); |
383 | di.nrbchan = dev->nrbchan; | 383 | di.nrbchan = dev->nrbchan; |
384 | strcpy(di.name, dev->name); | 384 | strcpy(di.name, dev->name); |
385 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) | 385 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) |
@@ -637,7 +637,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
637 | di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); | 637 | di.Bprotocols = dev->Bprotocols | get_all_Bprotocols(); |
638 | di.protocol = dev->D.protocol; | 638 | di.protocol = dev->D.protocol; |
639 | memcpy(di.channelmap, dev->channelmap, | 639 | memcpy(di.channelmap, dev->channelmap, |
640 | MISDN_CHMAP_SIZE * 4); | 640 | sizeof(di.channelmap)); |
641 | di.nrbchan = dev->nrbchan; | 641 | di.nrbchan = dev->nrbchan; |
642 | strcpy(di.name, dev->name); | 642 | strcpy(di.name, dev->name); |
643 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) | 643 | if (copy_to_user((void __user *)arg, &di, sizeof(di))) |
diff --git a/drivers/mtd/maps/ipaq-flash.c b/drivers/mtd/maps/ipaq-flash.c index a806119797e..113b1062020 100644 --- a/drivers/mtd/maps/ipaq-flash.c +++ b/drivers/mtd/maps/ipaq-flash.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #include <asm/hardware.h> | 27 | #include <asm/hardware.h> |
28 | #include <asm/arch-sa1100/h3600.h> | 28 | #include <asm/arch/h3600.h> |
29 | #include <asm/io.h> | 29 | #include <asm/io.h> |
30 | 30 | ||
31 | 31 | ||
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c index 9b6af7e74a6..00d46e137b2 100644 --- a/drivers/mtd/mtdsuper.c +++ b/drivers/mtd/mtdsuper.c | |||
@@ -125,8 +125,11 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, | |||
125 | int (*fill_super)(struct super_block *, void *, int), | 125 | int (*fill_super)(struct super_block *, void *, int), |
126 | struct vfsmount *mnt) | 126 | struct vfsmount *mnt) |
127 | { | 127 | { |
128 | #ifdef CONFIG_BLOCK | ||
128 | struct block_device *bdev; | 129 | struct block_device *bdev; |
129 | int mtdnr, ret; | 130 | int ret, major; |
131 | #endif | ||
132 | int mtdnr; | ||
130 | 133 | ||
131 | if (!dev_name) | 134 | if (!dev_name) |
132 | return -EINVAL; | 135 | return -EINVAL; |
@@ -178,6 +181,7 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, | |||
178 | } | 181 | } |
179 | } | 182 | } |
180 | 183 | ||
184 | #ifdef CONFIG_BLOCK | ||
181 | /* try the old way - the hack where we allowed users to mount | 185 | /* try the old way - the hack where we allowed users to mount |
182 | * /dev/mtdblock$(n) but didn't actually _use_ the blockdev | 186 | * /dev/mtdblock$(n) but didn't actually _use_ the blockdev |
183 | */ | 187 | */ |
@@ -190,22 +194,25 @@ int get_sb_mtd(struct file_system_type *fs_type, int flags, | |||
190 | DEBUG(1, "MTDSB: lookup_bdev() returned 0\n"); | 194 | DEBUG(1, "MTDSB: lookup_bdev() returned 0\n"); |
191 | 195 | ||
192 | ret = -EINVAL; | 196 | ret = -EINVAL; |
193 | if (MAJOR(bdev->bd_dev) != MTD_BLOCK_MAJOR) | ||
194 | goto not_an_MTD_device; | ||
195 | 197 | ||
198 | major = MAJOR(bdev->bd_dev); | ||
196 | mtdnr = MINOR(bdev->bd_dev); | 199 | mtdnr = MINOR(bdev->bd_dev); |
197 | bdput(bdev); | 200 | bdput(bdev); |
198 | 201 | ||
202 | if (major != MTD_BLOCK_MAJOR) | ||
203 | goto not_an_MTD_device; | ||
204 | |||
199 | return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super, | 205 | return get_sb_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super, |
200 | mnt); | 206 | mnt); |
201 | 207 | ||
202 | not_an_MTD_device: | 208 | not_an_MTD_device: |
209 | #endif /* CONFIG_BLOCK */ | ||
210 | |||
203 | if (!(flags & MS_SILENT)) | 211 | if (!(flags & MS_SILENT)) |
204 | printk(KERN_NOTICE | 212 | printk(KERN_NOTICE |
205 | "MTD: Attempt to mount non-MTD device \"%s\"\n", | 213 | "MTD: Attempt to mount non-MTD device \"%s\"\n", |
206 | dev_name); | 214 | dev_name); |
207 | bdput(bdev); | 215 | return -EINVAL; |
208 | return ret; | ||
209 | } | 216 | } |
210 | 217 | ||
211 | EXPORT_SYMBOL_GPL(get_sb_mtd); | 218 | EXPORT_SYMBOL_GPL(get_sb_mtd); |
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index d0c1d63d189..203e579ebbd 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -275,7 +275,7 @@ static int readable(struct pcmcia_socket *s, struct resource *res, | |||
275 | destroy_cis_cache(s); | 275 | destroy_cis_cache(s); |
276 | } | 276 | } |
277 | s->cis_mem.res = NULL; | 277 | s->cis_mem.res = NULL; |
278 | if ((ret != 0) || (count == 0)) | 278 | if ((ret != 0) || (*count == 0)) |
279 | return 0; | 279 | return 0; |
280 | return 1; | 280 | return 1; |
281 | } | 281 | } |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index da876d3924b..74d12b58a26 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -1249,6 +1249,13 @@ static struct pci_device_id hptiop_id_table[] = { | |||
1249 | { PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops }, | 1249 | { PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops }, |
1250 | { PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops }, | 1250 | { PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops }, |
1251 | { PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops }, | 1251 | { PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops }, |
1252 | { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1253 | { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1254 | { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1255 | { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1256 | { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1257 | { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1258 | { PCI_VDEVICE(TTI, 0x4311), (kernel_ulong_t)&hptiop_itl_ops }, | ||
1252 | { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops }, | 1259 | { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops }, |
1253 | { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops }, | 1260 | { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops }, |
1254 | { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops }, | 1261 | { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops }, |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 75a64a6cae8..b29360ed0bd 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -366,12 +366,14 @@ spi_transport_rd_attr(rti, "%d\n"); | |||
366 | spi_transport_rd_attr(pcomp_en, "%d\n"); | 366 | spi_transport_rd_attr(pcomp_en, "%d\n"); |
367 | spi_transport_rd_attr(hold_mcs, "%d\n"); | 367 | spi_transport_rd_attr(hold_mcs, "%d\n"); |
368 | 368 | ||
369 | /* we only care about the first child device so we return 1 */ | 369 | /* we only care about the first child device that's a real SCSI device |
370 | * so we return 1 to terminate the iteration when we find it */ | ||
370 | static int child_iter(struct device *dev, void *data) | 371 | static int child_iter(struct device *dev, void *data) |
371 | { | 372 | { |
372 | struct scsi_device *sdev = to_scsi_device(dev); | 373 | if (!scsi_is_sdev_device(dev)) |
374 | return 0; | ||
373 | 375 | ||
374 | spi_dv_device(sdev); | 376 | spi_dv_device(to_scsi_device(dev)); |
375 | return 1; | 377 | return 1; |
376 | } | 378 | } |
377 | 379 | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e5e7d785645..8e08d51a0f0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -375,7 +375,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
375 | struct gendisk *disk = rq->rq_disk; | 375 | struct gendisk *disk = rq->rq_disk; |
376 | struct scsi_disk *sdkp; | 376 | struct scsi_disk *sdkp; |
377 | sector_t block = rq->sector; | 377 | sector_t block = rq->sector; |
378 | sector_t threshold; | ||
379 | unsigned int this_count = rq->nr_sectors; | 378 | unsigned int this_count = rq->nr_sectors; |
380 | unsigned int timeout = sdp->timeout; | 379 | unsigned int timeout = sdp->timeout; |
381 | int ret; | 380 | int ret; |
@@ -423,21 +422,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) | |||
423 | } | 422 | } |
424 | 423 | ||
425 | /* | 424 | /* |
426 | * Some SD card readers can't handle multi-sector accesses which touch | 425 | * Some devices (some sdcards for one) don't like it if the |
427 | * the last one or two hardware sectors. Split accesses as needed. | 426 | * last sector gets read in a larger then 1 sector read. |
428 | */ | 427 | */ |
429 | threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * | 428 | if (unlikely(sdp->last_sector_bug && |
430 | (sdp->sector_size / 512); | 429 | rq->nr_sectors > sdp->sector_size / 512 && |
431 | 430 | block + this_count == get_capacity(disk))) | |
432 | if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { | 431 | this_count -= sdp->sector_size / 512; |
433 | if (block < threshold) { | ||
434 | /* Access up to the threshold but not beyond */ | ||
435 | this_count = threshold - block; | ||
436 | } else { | ||
437 | /* Access only a single hardware sector */ | ||
438 | this_count = sdp->sector_size / 512; | ||
439 | } | ||
440 | } | ||
441 | 432 | ||
442 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", | 433 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", |
443 | (unsigned long long)block)); | 434 | (unsigned long long)block)); |
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 95b9f06534d..550b2f70a1f 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h | |||
@@ -31,12 +31,6 @@ | |||
31 | */ | 31 | */ |
32 | #define SD_BUF_SIZE 512 | 32 | #define SD_BUF_SIZE 512 |
33 | 33 | ||
34 | /* | ||
35 | * Number of sectors at the end of the device to avoid multi-sector | ||
36 | * accesses to in the case of last_sector_bug | ||
37 | */ | ||
38 | #define SD_LAST_BUGGY_SECTORS 8 | ||
39 | |||
40 | struct scsi_disk { | 34 | struct scsi_disk { |
41 | struct scsi_driver *driver; /* always &sd_template */ | 35 | struct scsi_driver *driver; /* always &sd_template */ |
42 | struct scsi_device *device; | 36 | struct scsi_device *device; |
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 0fe031f003e..1bcf3c33d7f 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c | |||
@@ -345,14 +345,14 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev, | |||
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | #define VPD_INQUIRY_SIZE 512 | 348 | #define VPD_INQUIRY_SIZE 36 |
349 | 349 | ||
350 | static void ses_match_to_enclosure(struct enclosure_device *edev, | 350 | static void ses_match_to_enclosure(struct enclosure_device *edev, |
351 | struct scsi_device *sdev) | 351 | struct scsi_device *sdev) |
352 | { | 352 | { |
353 | unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL); | 353 | unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL); |
354 | unsigned char *desc; | 354 | unsigned char *desc; |
355 | int len; | 355 | u16 vpd_len; |
356 | struct efd efd = { | 356 | struct efd efd = { |
357 | .addr = 0, | 357 | .addr = 0, |
358 | }; | 358 | }; |
@@ -372,9 +372,19 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, | |||
372 | VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES)) | 372 | VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES)) |
373 | goto free; | 373 | goto free; |
374 | 374 | ||
375 | len = (buf[2] << 8) + buf[3]; | 375 | vpd_len = (buf[2] << 8) + buf[3]; |
376 | kfree(buf); | ||
377 | buf = kmalloc(vpd_len, GFP_KERNEL); | ||
378 | if (!buf) | ||
379 | return; | ||
380 | cmd[3] = vpd_len >> 8; | ||
381 | cmd[4] = vpd_len & 0xff; | ||
382 | if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, | ||
383 | vpd_len, NULL, SES_TIMEOUT, SES_RETRIES)) | ||
384 | goto free; | ||
385 | |||
376 | desc = buf + 4; | 386 | desc = buf + 4; |
377 | while (desc < buf + len) { | 387 | while (desc < buf + vpd_len) { |
378 | enum scsi_protocol proto = desc[0] >> 4; | 388 | enum scsi_protocol proto = desc[0] >> 4; |
379 | u8 code_set = desc[0] & 0x0f; | 389 | u8 code_set = desc[0] & 0x0f; |
380 | u8 piv = desc[1] & 0x80; | 390 | u8 piv = desc[1] & 0x80; |
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 9d8543762a3..efcd44344fb 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c | |||
@@ -817,7 +817,7 @@ static void bfin_serial_set_ldisc(struct uart_port *port) | |||
817 | if (line >= port->info->port.tty->driver->num) | 817 | if (line >= port->info->port.tty->driver->num) |
818 | return; | 818 | return; |
819 | 819 | ||
820 | switch (port->info->port.tty->ldisc.num) { | 820 | switch (port->info->port.tty->termios->c_line) { |
821 | case N_IRDA: | 821 | case N_IRDA: |
822 | val = UART_GET_GCTL(&bfin_serial_ports[line]); | 822 | val = UART_GET_GCTL(&bfin_serial_ports[line]); |
823 | val |= (IREN | RPOLC); | 823 | val |= (IREN | RPOLC); |
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 8249ac49055..bf94a770bb4 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c | |||
@@ -234,7 +234,7 @@ unsigned long r_alt_ser_baudrate_shadow = 0; | |||
234 | 234 | ||
235 | static struct e100_serial rs_table[] = { | 235 | static struct e100_serial rs_table[] = { |
236 | { .baud = DEF_BAUD, | 236 | { .baud = DEF_BAUD, |
237 | .port = (unsigned char *)R_SERIAL0_CTRL, | 237 | .ioport = (unsigned char *)R_SERIAL0_CTRL, |
238 | .irq = 1U << 12, /* uses DMA 6 and 7 */ | 238 | .irq = 1U << 12, /* uses DMA 6 and 7 */ |
239 | .oclrintradr = R_DMA_CH6_CLR_INTR, | 239 | .oclrintradr = R_DMA_CH6_CLR_INTR, |
240 | .ofirstadr = R_DMA_CH6_FIRST, | 240 | .ofirstadr = R_DMA_CH6_FIRST, |
@@ -288,7 +288,7 @@ static struct e100_serial rs_table[] = { | |||
288 | }, /* ttyS0 */ | 288 | }, /* ttyS0 */ |
289 | #ifndef CONFIG_SVINTO_SIM | 289 | #ifndef CONFIG_SVINTO_SIM |
290 | { .baud = DEF_BAUD, | 290 | { .baud = DEF_BAUD, |
291 | .port = (unsigned char *)R_SERIAL1_CTRL, | 291 | .ioport = (unsigned char *)R_SERIAL1_CTRL, |
292 | .irq = 1U << 16, /* uses DMA 8 and 9 */ | 292 | .irq = 1U << 16, /* uses DMA 8 and 9 */ |
293 | .oclrintradr = R_DMA_CH8_CLR_INTR, | 293 | .oclrintradr = R_DMA_CH8_CLR_INTR, |
294 | .ofirstadr = R_DMA_CH8_FIRST, | 294 | .ofirstadr = R_DMA_CH8_FIRST, |
@@ -344,7 +344,7 @@ static struct e100_serial rs_table[] = { | |||
344 | }, /* ttyS1 */ | 344 | }, /* ttyS1 */ |
345 | 345 | ||
346 | { .baud = DEF_BAUD, | 346 | { .baud = DEF_BAUD, |
347 | .port = (unsigned char *)R_SERIAL2_CTRL, | 347 | .ioport = (unsigned char *)R_SERIAL2_CTRL, |
348 | .irq = 1U << 4, /* uses DMA 2 and 3 */ | 348 | .irq = 1U << 4, /* uses DMA 2 and 3 */ |
349 | .oclrintradr = R_DMA_CH2_CLR_INTR, | 349 | .oclrintradr = R_DMA_CH2_CLR_INTR, |
350 | .ofirstadr = R_DMA_CH2_FIRST, | 350 | .ofirstadr = R_DMA_CH2_FIRST, |
@@ -398,7 +398,7 @@ static struct e100_serial rs_table[] = { | |||
398 | }, /* ttyS2 */ | 398 | }, /* ttyS2 */ |
399 | 399 | ||
400 | { .baud = DEF_BAUD, | 400 | { .baud = DEF_BAUD, |
401 | .port = (unsigned char *)R_SERIAL3_CTRL, | 401 | .ioport = (unsigned char *)R_SERIAL3_CTRL, |
402 | .irq = 1U << 8, /* uses DMA 4 and 5 */ | 402 | .irq = 1U << 8, /* uses DMA 4 and 5 */ |
403 | .oclrintradr = R_DMA_CH4_CLR_INTR, | 403 | .oclrintradr = R_DMA_CH4_CLR_INTR, |
404 | .ofirstadr = R_DMA_CH4_FIRST, | 404 | .ofirstadr = R_DMA_CH4_FIRST, |
@@ -939,7 +939,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = | |||
939 | /* Output */ | 939 | /* Output */ |
940 | #define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK) | 940 | #define E100_RTS_GET(info) ((info)->rx_ctrl & E100_RTS_MASK) |
941 | /* Input */ | 941 | /* Input */ |
942 | #define E100_CTS_GET(info) ((info)->port[REG_STATUS] & E100_CTS_MASK) | 942 | #define E100_CTS_GET(info) ((info)->ioport[REG_STATUS] & E100_CTS_MASK) |
943 | 943 | ||
944 | /* These are typically PA or PB and 0 means 0V, 1 means 3.3V */ | 944 | /* These are typically PA or PB and 0 means 0V, 1 means 3.3V */ |
945 | /* Is an output */ | 945 | /* Is an output */ |
@@ -1092,7 +1092,7 @@ e100_rts(struct e100_serial *info, int set) | |||
1092 | local_irq_save(flags); | 1092 | local_irq_save(flags); |
1093 | info->rx_ctrl &= ~E100_RTS_MASK; | 1093 | info->rx_ctrl &= ~E100_RTS_MASK; |
1094 | info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ | 1094 | info->rx_ctrl |= (set ? 0 : E100_RTS_MASK); /* RTS is active low */ |
1095 | info->port[REG_REC_CTRL] = info->rx_ctrl; | 1095 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; |
1096 | local_irq_restore(flags); | 1096 | local_irq_restore(flags); |
1097 | #ifdef SERIAL_DEBUG_IO | 1097 | #ifdef SERIAL_DEBUG_IO |
1098 | printk("ser%i rts %i\n", info->line, set); | 1098 | printk("ser%i rts %i\n", info->line, set); |
@@ -1142,7 +1142,7 @@ e100_disable_rx(struct e100_serial *info) | |||
1142 | { | 1142 | { |
1143 | #ifndef CONFIG_SVINTO_SIM | 1143 | #ifndef CONFIG_SVINTO_SIM |
1144 | /* disable the receiver */ | 1144 | /* disable the receiver */ |
1145 | info->port[REG_REC_CTRL] = | 1145 | info->ioport[REG_REC_CTRL] = |
1146 | (info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); | 1146 | (info->rx_ctrl &= ~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); |
1147 | #endif | 1147 | #endif |
1148 | } | 1148 | } |
@@ -1152,7 +1152,7 @@ e100_enable_rx(struct e100_serial *info) | |||
1152 | { | 1152 | { |
1153 | #ifndef CONFIG_SVINTO_SIM | 1153 | #ifndef CONFIG_SVINTO_SIM |
1154 | /* enable the receiver */ | 1154 | /* enable the receiver */ |
1155 | info->port[REG_REC_CTRL] = | 1155 | info->ioport[REG_REC_CTRL] = |
1156 | (info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); | 1156 | (info->rx_ctrl |= IO_MASK(R_SERIAL0_REC_CTRL, rec_enable)); |
1157 | #endif | 1157 | #endif |
1158 | } | 1158 | } |
@@ -1490,7 +1490,7 @@ rs_stop(struct tty_struct *tty) | |||
1490 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1490 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | *((unsigned long *)&info->port[REG_XOFF]) = xoff; | 1493 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; |
1494 | local_irq_restore(flags); | 1494 | local_irq_restore(flags); |
1495 | } | 1495 | } |
1496 | } | 1496 | } |
@@ -1513,7 +1513,7 @@ rs_start(struct tty_struct *tty) | |||
1513 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1513 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1514 | } | 1514 | } |
1515 | 1515 | ||
1516 | *((unsigned long *)&info->port[REG_XOFF]) = xoff; | 1516 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; |
1517 | if (!info->uses_dma_out && | 1517 | if (!info->uses_dma_out && |
1518 | info->xmit.head != info->xmit.tail && info->xmit.buf) | 1518 | info->xmit.head != info->xmit.tail && info->xmit.buf) |
1519 | e100_enable_serial_tx_ready_irq(info); | 1519 | e100_enable_serial_tx_ready_irq(info); |
@@ -1888,7 +1888,7 @@ static void receive_chars_dma(struct e100_serial *info) | |||
1888 | handle_all_descr_data(info); | 1888 | handle_all_descr_data(info); |
1889 | 1889 | ||
1890 | /* Read the status register to detect errors */ | 1890 | /* Read the status register to detect errors */ |
1891 | rstat = info->port[REG_STATUS]; | 1891 | rstat = info->ioport[REG_STATUS]; |
1892 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { | 1892 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { |
1893 | DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat)); | 1893 | DFLOW(DEBUG_LOG(info->line, "XOFF detect stat %x\n", rstat)); |
1894 | } | 1894 | } |
@@ -1897,7 +1897,7 @@ static void receive_chars_dma(struct e100_serial *info) | |||
1897 | /* If we got an error, we must reset it by reading the | 1897 | /* If we got an error, we must reset it by reading the |
1898 | * data_in field | 1898 | * data_in field |
1899 | */ | 1899 | */ |
1900 | unsigned char data = info->port[REG_DATA]; | 1900 | unsigned char data = info->ioport[REG_DATA]; |
1901 | 1901 | ||
1902 | PROCSTAT(ser_stat[info->line].errors_cnt++); | 1902 | PROCSTAT(ser_stat[info->line].errors_cnt++); |
1903 | DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n", | 1903 | DEBUG_LOG(info->line, "#dERR: s d 0x%04X\n", |
@@ -2077,7 +2077,7 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2077 | /* We check data_avail bit to determine if data has | 2077 | /* We check data_avail bit to determine if data has |
2078 | * arrived since last time | 2078 | * arrived since last time |
2079 | */ | 2079 | */ |
2080 | unsigned char rstat = info->port[REG_STATUS]; | 2080 | unsigned char rstat = info->ioport[REG_STATUS]; |
2081 | 2081 | ||
2082 | /* error or datavail? */ | 2082 | /* error or datavail? */ |
2083 | if (rstat & SER_ERROR_MASK) { | 2083 | if (rstat & SER_ERROR_MASK) { |
@@ -2096,7 +2096,7 @@ static int force_eop_if_needed(struct e100_serial *info) | |||
2096 | TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n", | 2096 | TIMERD(DEBUG_LOG(info->line, "timeout: rstat 0x%03X\n", |
2097 | rstat | (info->line << 8))); | 2097 | rstat | (info->line << 8))); |
2098 | /* Read data to clear status flags */ | 2098 | /* Read data to clear status flags */ |
2099 | (void)info->port[REG_DATA]; | 2099 | (void)info->ioport[REG_DATA]; |
2100 | 2100 | ||
2101 | info->forced_eop = 0; | 2101 | info->forced_eop = 0; |
2102 | START_FLUSH_FAST_TIMER(info, "magic"); | 2102 | START_FLUSH_FAST_TIMER(info, "magic"); |
@@ -2296,7 +2296,7 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info) | |||
2296 | } | 2296 | } |
2297 | 2297 | ||
2298 | /* Read data and status at the same time */ | 2298 | /* Read data and status at the same time */ |
2299 | data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); | 2299 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); |
2300 | more_data: | 2300 | more_data: |
2301 | if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) { | 2301 | if (data_read & IO_MASK(R_SERIAL0_READ, xoff_detect) ) { |
2302 | DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); | 2302 | DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); |
@@ -2391,7 +2391,7 @@ more_data: | |||
2391 | 2391 | ||
2392 | 2392 | ||
2393 | info->icount.rx++; | 2393 | info->icount.rx++; |
2394 | data_read = *((unsigned long *)&info->port[REG_DATA_STATUS32]); | 2394 | data_read = *((unsigned long *)&info->ioport[REG_DATA_STATUS32]); |
2395 | if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { | 2395 | if (data_read & IO_MASK(R_SERIAL0_READ, data_avail)) { |
2396 | DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)); | 2396 | DEBUG_LOG(info->line, "ser_rx %c in loop\n", IO_EXTRACT(R_SERIAL0_READ, data_in, data_read)); |
2397 | goto more_data; | 2397 | goto more_data; |
@@ -2413,7 +2413,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | |||
2413 | return handle_ser_rx_interrupt_no_dma(info); | 2413 | return handle_ser_rx_interrupt_no_dma(info); |
2414 | } | 2414 | } |
2415 | /* DMA is used */ | 2415 | /* DMA is used */ |
2416 | rstat = info->port[REG_STATUS]; | 2416 | rstat = info->ioport[REG_STATUS]; |
2417 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { | 2417 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) { |
2418 | DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); | 2418 | DFLOW(DEBUG_LOG(info->line, "XOFF detect\n", 0)); |
2419 | } | 2419 | } |
@@ -2426,7 +2426,7 @@ static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info) | |||
2426 | /* If we got an error, we must reset it by reading the | 2426 | /* If we got an error, we must reset it by reading the |
2427 | * data_in field | 2427 | * data_in field |
2428 | */ | 2428 | */ |
2429 | data = info->port[REG_DATA]; | 2429 | data = info->ioport[REG_DATA]; |
2430 | DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data)); | 2430 | DINTR1(DEBUG_LOG(info->line, "ser_rx! %c\n", data)); |
2431 | DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat)); | 2431 | DINTR1(DEBUG_LOG(info->line, "ser_rx err stat %02X\n", rstat)); |
2432 | if (!data && (rstat & SER_FRAMING_ERR_MASK)) { | 2432 | if (!data && (rstat & SER_FRAMING_ERR_MASK)) { |
@@ -2528,10 +2528,10 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) | |||
2528 | unsigned char rstat; | 2528 | unsigned char rstat; |
2529 | DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); | 2529 | DFLOW(DEBUG_LOG(info->line, "tx_int: xchar 0x%02X\n", info->x_char)); |
2530 | local_irq_save(flags); | 2530 | local_irq_save(flags); |
2531 | rstat = info->port[REG_STATUS]; | 2531 | rstat = info->ioport[REG_STATUS]; |
2532 | DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); | 2532 | DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); |
2533 | 2533 | ||
2534 | info->port[REG_TR_DATA] = info->x_char; | 2534 | info->ioport[REG_TR_DATA] = info->x_char; |
2535 | info->icount.tx++; | 2535 | info->icount.tx++; |
2536 | info->x_char = 0; | 2536 | info->x_char = 0; |
2537 | /* We must enable since it is disabled in ser_interrupt */ | 2537 | /* We must enable since it is disabled in ser_interrupt */ |
@@ -2545,7 +2545,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) | |||
2545 | /* We only use normal tx interrupt when sending x_char */ | 2545 | /* We only use normal tx interrupt when sending x_char */ |
2546 | DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); | 2546 | DFLOW(DEBUG_LOG(info->line, "tx_int: xchar sent\n", 0)); |
2547 | local_irq_save(flags); | 2547 | local_irq_save(flags); |
2548 | rstat = info->port[REG_STATUS]; | 2548 | rstat = info->ioport[REG_STATUS]; |
2549 | DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); | 2549 | DFLOW(DEBUG_LOG(info->line, "stat %x\n", rstat)); |
2550 | e100_disable_serial_tx_ready_irq(info); | 2550 | e100_disable_serial_tx_ready_irq(info); |
2551 | if (info->port.tty->stopped) | 2551 | if (info->port.tty->stopped) |
@@ -2573,7 +2573,7 @@ static void handle_ser_tx_interrupt(struct e100_serial *info) | |||
2573 | DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); | 2573 | DINTR2(DEBUG_LOG(info->line, "tx_int %c\n", info->xmit.buf[info->xmit.tail])); |
2574 | /* Send a byte, rs485 timing is critical so turn of ints */ | 2574 | /* Send a byte, rs485 timing is critical so turn of ints */ |
2575 | local_irq_save(flags); | 2575 | local_irq_save(flags); |
2576 | info->port[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; | 2576 | info->ioport[REG_TR_DATA] = info->xmit.buf[info->xmit.tail]; |
2577 | info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); | 2577 | info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1); |
2578 | info->icount.tx++; | 2578 | info->icount.tx++; |
2579 | if (info->xmit.head == info->xmit.tail) { | 2579 | if (info->xmit.head == info->xmit.tail) { |
@@ -2848,7 +2848,7 @@ startup(struct e100_serial * info) | |||
2848 | 2848 | ||
2849 | /* dummy read to reset any serial errors */ | 2849 | /* dummy read to reset any serial errors */ |
2850 | 2850 | ||
2851 | (void)info->port[REG_DATA]; | 2851 | (void)info->ioport[REG_DATA]; |
2852 | 2852 | ||
2853 | /* enable the interrupts */ | 2853 | /* enable the interrupts */ |
2854 | if (info->uses_dma_out) | 2854 | if (info->uses_dma_out) |
@@ -2897,7 +2897,7 @@ shutdown(struct e100_serial * info) | |||
2897 | /* shut down the transmitter and receiver */ | 2897 | /* shut down the transmitter and receiver */ |
2898 | DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line)); | 2898 | DFLOW(DEBUG_LOG(info->line, "shutdown %i\n", info->line)); |
2899 | e100_disable_rx(info); | 2899 | e100_disable_rx(info); |
2900 | info->port[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40); | 2900 | info->ioport[REG_TR_CTRL] = (info->tx_ctrl &= ~0x40); |
2901 | 2901 | ||
2902 | /* disable interrupts, reset dma channels */ | 2902 | /* disable interrupts, reset dma channels */ |
2903 | if (info->uses_dma_in) { | 2903 | if (info->uses_dma_in) { |
@@ -2968,7 +2968,7 @@ change_speed(struct e100_serial *info) | |||
2968 | 2968 | ||
2969 | if (!info->port.tty || !info->port.tty->termios) | 2969 | if (!info->port.tty || !info->port.tty->termios) |
2970 | return; | 2970 | return; |
2971 | if (!info->port) | 2971 | if (!info->ioport) |
2972 | return; | 2972 | return; |
2973 | 2973 | ||
2974 | cflag = info->port.tty->termios->c_cflag; | 2974 | cflag = info->port.tty->termios->c_cflag; |
@@ -3037,7 +3037,7 @@ change_speed(struct e100_serial *info) | |||
3037 | 3037 | ||
3038 | info->baud = cflag_to_baud(cflag); | 3038 | info->baud = cflag_to_baud(cflag); |
3039 | #ifndef CONFIG_SVINTO_SIM | 3039 | #ifndef CONFIG_SVINTO_SIM |
3040 | info->port[REG_BAUD] = cflag_to_etrax_baud(cflag); | 3040 | info->ioport[REG_BAUD] = cflag_to_etrax_baud(cflag); |
3041 | #endif /* CONFIG_SVINTO_SIM */ | 3041 | #endif /* CONFIG_SVINTO_SIM */ |
3042 | } | 3042 | } |
3043 | 3043 | ||
@@ -3097,8 +3097,8 @@ change_speed(struct e100_serial *info) | |||
3097 | 3097 | ||
3098 | /* actually write the control regs to the hardware */ | 3098 | /* actually write the control regs to the hardware */ |
3099 | 3099 | ||
3100 | info->port[REG_TR_CTRL] = info->tx_ctrl; | 3100 | info->ioport[REG_TR_CTRL] = info->tx_ctrl; |
3101 | info->port[REG_REC_CTRL] = info->rx_ctrl; | 3101 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; |
3102 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); | 3102 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); |
3103 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 3103 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
3104 | if (info->port.tty->termios->c_iflag & IXON ) { | 3104 | if (info->port.tty->termios->c_iflag & IXON ) { |
@@ -3107,7 +3107,7 @@ change_speed(struct e100_serial *info) | |||
3107 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 3107 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
3108 | } | 3108 | } |
3109 | 3109 | ||
3110 | *((unsigned long *)&info->port[REG_XOFF]) = xoff; | 3110 | *((unsigned long *)&info->ioport[REG_XOFF]) = xoff; |
3111 | local_irq_restore(flags); | 3111 | local_irq_restore(flags); |
3112 | #endif /* !CONFIG_SVINTO_SIM */ | 3112 | #endif /* !CONFIG_SVINTO_SIM */ |
3113 | 3113 | ||
@@ -3156,7 +3156,7 @@ static int rs_raw_write(struct tty_struct *tty, | |||
3156 | #ifdef SERIAL_DEBUG_DATA | 3156 | #ifdef SERIAL_DEBUG_DATA |
3157 | if (info->line == SERIAL_DEBUG_LINE) | 3157 | if (info->line == SERIAL_DEBUG_LINE) |
3158 | printk("rs_raw_write (%d), status %d\n", | 3158 | printk("rs_raw_write (%d), status %d\n", |
3159 | count, info->port[REG_STATUS]); | 3159 | count, info->ioport[REG_STATUS]); |
3160 | #endif | 3160 | #endif |
3161 | 3161 | ||
3162 | #ifdef CONFIG_SVINTO_SIM | 3162 | #ifdef CONFIG_SVINTO_SIM |
@@ -3427,7 +3427,7 @@ get_serial_info(struct e100_serial * info, | |||
3427 | memset(&tmp, 0, sizeof(tmp)); | 3427 | memset(&tmp, 0, sizeof(tmp)); |
3428 | tmp.type = info->type; | 3428 | tmp.type = info->type; |
3429 | tmp.line = info->line; | 3429 | tmp.line = info->line; |
3430 | tmp.port = (int)info->port; | 3430 | tmp.port = (int)info->ioport; |
3431 | tmp.irq = info->irq; | 3431 | tmp.irq = info->irq; |
3432 | tmp.flags = info->flags; | 3432 | tmp.flags = info->flags; |
3433 | tmp.baud_base = info->baud_base; | 3433 | tmp.baud_base = info->baud_base; |
@@ -3557,14 +3557,14 @@ char *get_control_state_str(int MLines, char *s) | |||
3557 | } | 3557 | } |
3558 | #endif | 3558 | #endif |
3559 | 3559 | ||
3560 | static void | 3560 | static int |
3561 | rs_break(struct tty_struct *tty, int break_state) | 3561 | rs_break(struct tty_struct *tty, int break_state) |
3562 | { | 3562 | { |
3563 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; | 3563 | struct e100_serial *info = (struct e100_serial *)tty->driver_data; |
3564 | unsigned long flags; | 3564 | unsigned long flags; |
3565 | 3565 | ||
3566 | if (!info->port) | 3566 | if (!info->ioport) |
3567 | return; | 3567 | return -EIO; |
3568 | 3568 | ||
3569 | local_irq_save(flags); | 3569 | local_irq_save(flags); |
3570 | if (break_state == -1) { | 3570 | if (break_state == -1) { |
@@ -3575,8 +3575,9 @@ rs_break(struct tty_struct *tty, int break_state) | |||
3575 | /* Set bit 7 (txd) and 6 (tr_enable) */ | 3575 | /* Set bit 7 (txd) and 6 (tr_enable) */ |
3576 | info->tx_ctrl |= (0x80 | 0x40); | 3576 | info->tx_ctrl |= (0x80 | 0x40); |
3577 | } | 3577 | } |
3578 | info->port[REG_TR_CTRL] = info->tx_ctrl; | 3578 | info->ioport[REG_TR_CTRL] = info->tx_ctrl; |
3579 | local_irq_restore(flags); | 3579 | local_irq_restore(flags); |
3580 | return 0; | ||
3580 | } | 3581 | } |
3581 | 3582 | ||
3582 | static int | 3583 | static int |
@@ -4231,9 +4232,9 @@ static int line_info(char *buf, struct e100_serial *info) | |||
4231 | unsigned long tmp; | 4232 | unsigned long tmp; |
4232 | 4233 | ||
4233 | ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d", | 4234 | ret = sprintf(buf, "%d: uart:E100 port:%lX irq:%d", |
4234 | info->line, (unsigned long)info->port, info->irq); | 4235 | info->line, (unsigned long)info->ioport, info->irq); |
4235 | 4236 | ||
4236 | if (!info->port || (info->type == PORT_UNKNOWN)) { | 4237 | if (!info->ioport || (info->type == PORT_UNKNOWN)) { |
4237 | ret += sprintf(buf+ret, "\n"); | 4238 | ret += sprintf(buf+ret, "\n"); |
4238 | return ret; | 4239 | return ret; |
4239 | } | 4240 | } |
@@ -4281,7 +4282,7 @@ static int line_info(char *buf, struct e100_serial *info) | |||
4281 | } | 4282 | } |
4282 | 4283 | ||
4283 | { | 4284 | { |
4284 | unsigned char rstat = info->port[REG_STATUS]; | 4285 | unsigned char rstat = info->ioport[REG_STATUS]; |
4285 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) | 4286 | if (rstat & IO_MASK(R_SERIAL0_STATUS, xoff_detect) ) |
4286 | ret += sprintf(buf+ret, " xoff_detect:1"); | 4287 | ret += sprintf(buf+ret, " xoff_detect:1"); |
4287 | } | 4288 | } |
@@ -4502,7 +4503,7 @@ rs_init(void) | |||
4502 | 4503 | ||
4503 | if (info->enabled) { | 4504 | if (info->enabled) { |
4504 | printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n", | 4505 | printk(KERN_INFO "%s%d at 0x%x is a builtin UART with DMA\n", |
4505 | serial_driver->name, info->line, (unsigned int)info->port); | 4506 | serial_driver->name, info->line, (unsigned int)info->ioport); |
4506 | } | 4507 | } |
4507 | } | 4508 | } |
4508 | #ifdef CONFIG_ETRAX_FAST_TIMER | 4509 | #ifdef CONFIG_ETRAX_FAST_TIMER |
diff --git a/drivers/serial/crisv10.h b/drivers/serial/crisv10.h index ccd0f32b737..e3c5c8c3c09 100644 --- a/drivers/serial/crisv10.h +++ b/drivers/serial/crisv10.h | |||
@@ -36,8 +36,9 @@ struct etrax_recv_buffer { | |||
36 | }; | 36 | }; |
37 | 37 | ||
38 | struct e100_serial { | 38 | struct e100_serial { |
39 | struct tty_port port; | ||
39 | int baud; | 40 | int baud; |
40 | volatile u8 *port; /* R_SERIALx_CTRL */ | 41 | volatile u8 *ioport; /* R_SERIALx_CTRL */ |
41 | u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */ | 42 | u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */ |
42 | 43 | ||
43 | /* Output registers */ | 44 | /* Output registers */ |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 0c716566085..95190c619c1 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -184,7 +184,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
184 | { | 184 | { |
185 | struct atmel_spi *as = spi_master_get_devdata(master); | 185 | struct atmel_spi *as = spi_master_get_devdata(master); |
186 | struct spi_transfer *xfer; | 186 | struct spi_transfer *xfer; |
187 | u32 len, remaining, total; | 187 | u32 len, remaining; |
188 | u32 ieval; | ||
188 | dma_addr_t tx_dma, rx_dma; | 189 | dma_addr_t tx_dma, rx_dma; |
189 | 190 | ||
190 | if (!as->current_transfer) | 191 | if (!as->current_transfer) |
@@ -197,6 +198,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
197 | xfer = NULL; | 198 | xfer = NULL; |
198 | 199 | ||
199 | if (xfer) { | 200 | if (xfer) { |
201 | spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); | ||
202 | |||
200 | len = xfer->len; | 203 | len = xfer->len; |
201 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); | 204 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); |
202 | remaining = xfer->len - len; | 205 | remaining = xfer->len - len; |
@@ -234,6 +237,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
234 | as->next_transfer = xfer; | 237 | as->next_transfer = xfer; |
235 | 238 | ||
236 | if (xfer) { | 239 | if (xfer) { |
240 | u32 total; | ||
241 | |||
237 | total = len; | 242 | total = len; |
238 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); | 243 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); |
239 | as->next_remaining_bytes = total - len; | 244 | as->next_remaining_bytes = total - len; |
@@ -250,9 +255,11 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
250 | " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", | 255 | " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", |
251 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | 256 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, |
252 | xfer->rx_buf, xfer->rx_dma); | 257 | xfer->rx_buf, xfer->rx_dma); |
258 | ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); | ||
253 | } else { | 259 | } else { |
254 | spi_writel(as, RNCR, 0); | 260 | spi_writel(as, RNCR, 0); |
255 | spi_writel(as, TNCR, 0); | 261 | spi_writel(as, TNCR, 0); |
262 | ieval = SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES); | ||
256 | } | 263 | } |
257 | 264 | ||
258 | /* REVISIT: We're waiting for ENDRX before we start the next | 265 | /* REVISIT: We're waiting for ENDRX before we start the next |
@@ -265,7 +272,7 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
265 | * | 272 | * |
266 | * It should be doable, though. Just not now... | 273 | * It should be doable, though. Just not now... |
267 | */ | 274 | */ |
268 | spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); | 275 | spi_writel(as, IER, ieval); |
269 | spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); | 276 | spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); |
270 | } | 277 | } |
271 | 278 | ||
@@ -396,7 +403,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
396 | 403 | ||
397 | ret = IRQ_HANDLED; | 404 | ret = IRQ_HANDLED; |
398 | 405 | ||
399 | spi_writel(as, IDR, (SPI_BIT(ENDTX) | SPI_BIT(ENDRX) | 406 | spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) |
400 | | SPI_BIT(OVRES))); | 407 | | SPI_BIT(OVRES))); |
401 | 408 | ||
402 | /* | 409 | /* |
@@ -418,7 +425,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
418 | if (xfer->delay_usecs) | 425 | if (xfer->delay_usecs) |
419 | udelay(xfer->delay_usecs); | 426 | udelay(xfer->delay_usecs); |
420 | 427 | ||
421 | dev_warn(master->dev.parent, "fifo overrun (%u/%u remaining)\n", | 428 | dev_warn(master->dev.parent, "overrun (%u/%u remaining)\n", |
422 | spi_readl(as, TCR), spi_readl(as, RCR)); | 429 | spi_readl(as, TCR), spi_readl(as, RCR)); |
423 | 430 | ||
424 | /* | 431 | /* |
@@ -442,7 +449,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
442 | spi_readl(as, SR); | 449 | spi_readl(as, SR); |
443 | 450 | ||
444 | atmel_spi_msg_done(master, as, msg, -EIO, 0); | 451 | atmel_spi_msg_done(master, as, msg, -EIO, 0); |
445 | } else if (pending & SPI_BIT(ENDRX)) { | 452 | } else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) { |
446 | ret = IRQ_HANDLED; | 453 | ret = IRQ_HANDLED; |
447 | 454 | ||
448 | spi_writel(as, IDR, pending); | 455 | spi_writel(as, IDR, pending); |
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 1c643c9e1f1..21661c7959c 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c | |||
@@ -236,6 +236,19 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) | |||
236 | return IRQ_HANDLED; | 236 | return IRQ_HANDLED; |
237 | } | 237 | } |
238 | 238 | ||
239 | static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) | ||
240 | { | ||
241 | /* for the moment, permanently enable the clock */ | ||
242 | |||
243 | clk_enable(hw->clk); | ||
244 | |||
245 | /* program defaults into the registers */ | ||
246 | |||
247 | writeb(0xff, hw->regs + S3C2410_SPPRE); | ||
248 | writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); | ||
249 | writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); | ||
250 | } | ||
251 | |||
239 | static int __init s3c24xx_spi_probe(struct platform_device *pdev) | 252 | static int __init s3c24xx_spi_probe(struct platform_device *pdev) |
240 | { | 253 | { |
241 | struct s3c2410_spi_info *pdata; | 254 | struct s3c2410_spi_info *pdata; |
@@ -327,15 +340,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
327 | goto err_no_clk; | 340 | goto err_no_clk; |
328 | } | 341 | } |
329 | 342 | ||
330 | /* for the moment, permanently enable the clock */ | 343 | s3c24xx_spi_initialsetup(hw); |
331 | |||
332 | clk_enable(hw->clk); | ||
333 | |||
334 | /* program defaults into the registers */ | ||
335 | |||
336 | writeb(0xff, hw->regs + S3C2410_SPPRE); | ||
337 | writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); | ||
338 | writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); | ||
339 | 344 | ||
340 | /* setup any gpio we can */ | 345 | /* setup any gpio we can */ |
341 | 346 | ||
@@ -415,7 +420,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev) | |||
415 | { | 420 | { |
416 | struct s3c24xx_spi *hw = platform_get_drvdata(pdev); | 421 | struct s3c24xx_spi *hw = platform_get_drvdata(pdev); |
417 | 422 | ||
418 | clk_enable(hw->clk); | 423 | s3c24xx_spi_initialsetup(hw); |
419 | return 0; | 424 | return 0; |
420 | } | 425 | } |
421 | 426 | ||
diff --git a/drivers/video/console/.gitignore b/drivers/video/console/.gitignore new file mode 100644 index 00000000000..0c258b45439 --- /dev/null +++ b/drivers/video/console/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | # conmakehash generated file | ||
2 | promcon_tbl.c | ||
diff --git a/drivers/watchdog/ar7_wdt.c b/drivers/watchdog/ar7_wdt.c index 2eb48c0df32..ef7b0d67095 100644 --- a/drivers/watchdog/ar7_wdt.c +++ b/drivers/watchdog/ar7_wdt.c | |||
@@ -69,7 +69,8 @@ struct ar7_wdt { | |||
69 | u32 prescale; | 69 | u32 prescale; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static struct semaphore open_semaphore; | 72 | static unsigned long wdt_is_open; |
73 | static spinlock_t wdt_lock; | ||
73 | static unsigned expect_close; | 74 | static unsigned expect_close; |
74 | 75 | ||
75 | /* XXX currently fixed, allows max margin ~68.72 secs */ | 76 | /* XXX currently fixed, allows max margin ~68.72 secs */ |
@@ -154,8 +155,10 @@ static void ar7_wdt_update_margin(int new_margin) | |||
154 | u32 change; | 155 | u32 change; |
155 | 156 | ||
156 | change = new_margin * (ar7_vbus_freq() / prescale_value); | 157 | change = new_margin * (ar7_vbus_freq() / prescale_value); |
157 | if (change < 1) change = 1; | 158 | if (change < 1) |
158 | if (change > 0xffff) change = 0xffff; | 159 | change = 1; |
160 | if (change > 0xffff) | ||
161 | change = 0xffff; | ||
159 | ar7_wdt_change(change); | 162 | ar7_wdt_change(change); |
160 | margin = change * prescale_value / ar7_vbus_freq(); | 163 | margin = change * prescale_value / ar7_vbus_freq(); |
161 | printk(KERN_INFO DRVNAME | 164 | printk(KERN_INFO DRVNAME |
@@ -179,7 +182,7 @@ static void ar7_wdt_disable_wdt(void) | |||
179 | static int ar7_wdt_open(struct inode *inode, struct file *file) | 182 | static int ar7_wdt_open(struct inode *inode, struct file *file) |
180 | { | 183 | { |
181 | /* only allow one at a time */ | 184 | /* only allow one at a time */ |
182 | if (down_trylock(&open_semaphore)) | 185 | if (test_and_set_bit(0, &wdt_is_open)) |
183 | return -EBUSY; | 186 | return -EBUSY; |
184 | ar7_wdt_enable_wdt(); | 187 | ar7_wdt_enable_wdt(); |
185 | expect_close = 0; | 188 | expect_close = 0; |
@@ -195,9 +198,7 @@ static int ar7_wdt_release(struct inode *inode, struct file *file) | |||
195 | "will not disable the watchdog timer\n"); | 198 | "will not disable the watchdog timer\n"); |
196 | else if (!nowayout) | 199 | else if (!nowayout) |
197 | ar7_wdt_disable_wdt(); | 200 | ar7_wdt_disable_wdt(); |
198 | 201 | clear_bit(0, &wdt_is_open); | |
199 | up(&open_semaphore); | ||
200 | |||
201 | return 0; | 202 | return 0; |
202 | } | 203 | } |
203 | 204 | ||
@@ -222,7 +223,9 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, | |||
222 | if (len) { | 223 | if (len) { |
223 | size_t i; | 224 | size_t i; |
224 | 225 | ||
226 | spin_lock(&wdt_lock); | ||
225 | ar7_wdt_kick(1); | 227 | ar7_wdt_kick(1); |
228 | spin_unlock(&wdt_lock); | ||
226 | 229 | ||
227 | expect_close = 0; | 230 | expect_close = 0; |
228 | for (i = 0; i < len; ++i) { | 231 | for (i = 0; i < len; ++i) { |
@@ -237,8 +240,8 @@ static ssize_t ar7_wdt_write(struct file *file, const char *data, | |||
237 | return len; | 240 | return len; |
238 | } | 241 | } |
239 | 242 | ||
240 | static int ar7_wdt_ioctl(struct inode *inode, struct file *file, | 243 | static long ar7_wdt_ioctl(struct file *file, |
241 | unsigned int cmd, unsigned long arg) | 244 | unsigned int cmd, unsigned long arg) |
242 | { | 245 | { |
243 | static struct watchdog_info ident = { | 246 | static struct watchdog_info ident = { |
244 | .identity = LONGNAME, | 247 | .identity = LONGNAME, |
@@ -269,8 +272,10 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file, | |||
269 | if (new_margin < 1) | 272 | if (new_margin < 1) |
270 | return -EINVAL; | 273 | return -EINVAL; |
271 | 274 | ||
275 | spin_lock(&wdt_lock); | ||
272 | ar7_wdt_update_margin(new_margin); | 276 | ar7_wdt_update_margin(new_margin); |
273 | ar7_wdt_kick(1); | 277 | ar7_wdt_kick(1); |
278 | spin_unlock(&wdt_lock); | ||
274 | 279 | ||
275 | case WDIOC_GETTIMEOUT: | 280 | case WDIOC_GETTIMEOUT: |
276 | if (put_user(margin, (int *)arg)) | 281 | if (put_user(margin, (int *)arg)) |
@@ -282,7 +287,7 @@ static int ar7_wdt_ioctl(struct inode *inode, struct file *file, | |||
282 | static const struct file_operations ar7_wdt_fops = { | 287 | static const struct file_operations ar7_wdt_fops = { |
283 | .owner = THIS_MODULE, | 288 | .owner = THIS_MODULE, |
284 | .write = ar7_wdt_write, | 289 | .write = ar7_wdt_write, |
285 | .ioctl = ar7_wdt_ioctl, | 290 | .unlocked_ioctl = ar7_wdt_ioctl, |
286 | .open = ar7_wdt_open, | 291 | .open = ar7_wdt_open, |
287 | .release = ar7_wdt_release, | 292 | .release = ar7_wdt_release, |
288 | }; | 293 | }; |
@@ -297,6 +302,8 @@ static int __init ar7_wdt_init(void) | |||
297 | { | 302 | { |
298 | int rc; | 303 | int rc; |
299 | 304 | ||
305 | spin_lock_init(&wdt_lock); | ||
306 | |||
300 | ar7_wdt_get_regs(); | 307 | ar7_wdt_get_regs(); |
301 | 308 | ||
302 | if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt), | 309 | if (!request_mem_region(ar7_regs_wdt, sizeof(struct ar7_wdt), |
@@ -312,8 +319,6 @@ static int __init ar7_wdt_init(void) | |||
312 | ar7_wdt_prescale(prescale_value); | 319 | ar7_wdt_prescale(prescale_value); |
313 | ar7_wdt_update_margin(margin); | 320 | ar7_wdt_update_margin(margin); |
314 | 321 | ||
315 | sema_init(&open_semaphore, 1); | ||
316 | |||
317 | rc = register_reboot_notifier(&ar7_wdt_notifier); | 322 | rc = register_reboot_notifier(&ar7_wdt_notifier); |
318 | if (rc) { | 323 | if (rc) { |
319 | printk(KERN_ERR DRVNAME | 324 | printk(KERN_ERR DRVNAME |
diff --git a/drivers/watchdog/it8712f_wdt.c b/drivers/watchdog/it8712f_wdt.c index 445b7e81211..51bfd572183 100644 --- a/drivers/watchdog/it8712f_wdt.c +++ b/drivers/watchdog/it8712f_wdt.c | |||
@@ -30,9 +30,8 @@ | |||
30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | 33 | #include <linux/uaccess.h> | |
34 | #include <asm/uaccess.h> | 34 | #include <linux/io.h> |
35 | #include <asm/io.h> | ||
36 | 35 | ||
37 | #define NAME "it8712f_wdt" | 36 | #define NAME "it8712f_wdt" |
38 | 37 | ||
@@ -50,7 +49,7 @@ static int nowayout = WATCHDOG_NOWAYOUT; | |||
50 | module_param(nowayout, int, 0); | 49 | module_param(nowayout, int, 0); |
51 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); | 50 | MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); |
52 | 51 | ||
53 | static struct semaphore it8712f_wdt_sem; | 52 | static unsigned long wdt_open; |
54 | static unsigned expect_close; | 53 | static unsigned expect_close; |
55 | static spinlock_t io_lock; | 54 | static spinlock_t io_lock; |
56 | static unsigned char revision; | 55 | static unsigned char revision; |
@@ -86,22 +85,19 @@ static unsigned short address; | |||
86 | #define WDT_OUT_PWROK 0x10 | 85 | #define WDT_OUT_PWROK 0x10 |
87 | #define WDT_OUT_KRST 0x40 | 86 | #define WDT_OUT_KRST 0x40 |
88 | 87 | ||
89 | static int | 88 | static int superio_inb(int reg) |
90 | superio_inb(int reg) | ||
91 | { | 89 | { |
92 | outb(reg, REG); | 90 | outb(reg, REG); |
93 | return inb(VAL); | 91 | return inb(VAL); |
94 | } | 92 | } |
95 | 93 | ||
96 | static void | 94 | static void superio_outb(int val, int reg) |
97 | superio_outb(int val, int reg) | ||
98 | { | 95 | { |
99 | outb(reg, REG); | 96 | outb(reg, REG); |
100 | outb(val, VAL); | 97 | outb(val, VAL); |
101 | } | 98 | } |
102 | 99 | ||
103 | static int | 100 | static int superio_inw(int reg) |
104 | superio_inw(int reg) | ||
105 | { | 101 | { |
106 | int val; | 102 | int val; |
107 | outb(reg++, REG); | 103 | outb(reg++, REG); |
@@ -111,15 +107,13 @@ superio_inw(int reg) | |||
111 | return val; | 107 | return val; |
112 | } | 108 | } |
113 | 109 | ||
114 | static inline void | 110 | static inline void superio_select(int ldn) |
115 | superio_select(int ldn) | ||
116 | { | 111 | { |
117 | outb(LDN, REG); | 112 | outb(LDN, REG); |
118 | outb(ldn, VAL); | 113 | outb(ldn, VAL); |
119 | } | 114 | } |
120 | 115 | ||
121 | static inline void | 116 | static inline void superio_enter(void) |
122 | superio_enter(void) | ||
123 | { | 117 | { |
124 | spin_lock(&io_lock); | 118 | spin_lock(&io_lock); |
125 | outb(0x87, REG); | 119 | outb(0x87, REG); |
@@ -128,22 +122,19 @@ superio_enter(void) | |||
128 | outb(0x55, REG); | 122 | outb(0x55, REG); |
129 | } | 123 | } |
130 | 124 | ||
131 | static inline void | 125 | static inline void superio_exit(void) |
132 | superio_exit(void) | ||
133 | { | 126 | { |
134 | outb(0x02, REG); | 127 | outb(0x02, REG); |
135 | outb(0x02, VAL); | 128 | outb(0x02, VAL); |
136 | spin_unlock(&io_lock); | 129 | spin_unlock(&io_lock); |
137 | } | 130 | } |
138 | 131 | ||
139 | static inline void | 132 | static inline void it8712f_wdt_ping(void) |
140 | it8712f_wdt_ping(void) | ||
141 | { | 133 | { |
142 | inb(address); | 134 | inb(address); |
143 | } | 135 | } |
144 | 136 | ||
145 | static void | 137 | static void it8712f_wdt_update_margin(void) |
146 | it8712f_wdt_update_margin(void) | ||
147 | { | 138 | { |
148 | int config = WDT_OUT_KRST | WDT_OUT_PWROK; | 139 | int config = WDT_OUT_KRST | WDT_OUT_PWROK; |
149 | int units = margin; | 140 | int units = margin; |
@@ -165,8 +156,7 @@ it8712f_wdt_update_margin(void) | |||
165 | superio_outb(units, WDT_TIMEOUT); | 156 | superio_outb(units, WDT_TIMEOUT); |
166 | } | 157 | } |
167 | 158 | ||
168 | static int | 159 | static int it8712f_wdt_get_status(void) |
169 | it8712f_wdt_get_status(void) | ||
170 | { | 160 | { |
171 | if (superio_inb(WDT_CONTROL) & 0x01) | 161 | if (superio_inb(WDT_CONTROL) & 0x01) |
172 | return WDIOF_CARDRESET; | 162 | return WDIOF_CARDRESET; |
@@ -174,8 +164,7 @@ it8712f_wdt_get_status(void) | |||
174 | return 0; | 164 | return 0; |
175 | } | 165 | } |
176 | 166 | ||
177 | static void | 167 | static void it8712f_wdt_enable(void) |
178 | it8712f_wdt_enable(void) | ||
179 | { | 168 | { |
180 | printk(KERN_DEBUG NAME ": enabling watchdog timer\n"); | 169 | printk(KERN_DEBUG NAME ": enabling watchdog timer\n"); |
181 | superio_enter(); | 170 | superio_enter(); |
@@ -190,8 +179,7 @@ it8712f_wdt_enable(void) | |||
190 | it8712f_wdt_ping(); | 179 | it8712f_wdt_ping(); |
191 | } | 180 | } |
192 | 181 | ||
193 | static void | 182 | static void it8712f_wdt_disable(void) |
194 | it8712f_wdt_disable(void) | ||
195 | { | 183 | { |
196 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); | 184 | printk(KERN_DEBUG NAME ": disabling watchdog timer\n"); |
197 | 185 | ||
@@ -207,8 +195,7 @@ it8712f_wdt_disable(void) | |||
207 | superio_exit(); | 195 | superio_exit(); |
208 | } | 196 | } |
209 | 197 | ||
210 | static int | 198 | static int it8712f_wdt_notify(struct notifier_block *this, |
211 | it8712f_wdt_notify(struct notifier_block *this, | ||
212 | unsigned long code, void *unused) | 199 | unsigned long code, void *unused) |
213 | { | 200 | { |
214 | if (code == SYS_HALT || code == SYS_POWER_OFF) | 201 | if (code == SYS_HALT || code == SYS_POWER_OFF) |
@@ -222,9 +209,8 @@ static struct notifier_block it8712f_wdt_notifier = { | |||
222 | .notifier_call = it8712f_wdt_notify, | 209 | .notifier_call = it8712f_wdt_notify, |
223 | }; | 210 | }; |
224 | 211 | ||
225 | static ssize_t | 212 | static ssize_t it8712f_wdt_write(struct file *file, const char __user *data, |
226 | it8712f_wdt_write(struct file *file, const char __user *data, | 213 | size_t len, loff_t *ppos) |
227 | size_t len, loff_t *ppos) | ||
228 | { | 214 | { |
229 | /* check for a magic close character */ | 215 | /* check for a magic close character */ |
230 | if (len) { | 216 | if (len) { |
@@ -245,9 +231,8 @@ it8712f_wdt_write(struct file *file, const char __user *data, | |||
245 | return len; | 231 | return len; |
246 | } | 232 | } |
247 | 233 | ||
248 | static int | 234 | static long it8712f_wdt_ioctl(struct file *file, unsigned int cmd, |
249 | it8712f_wdt_ioctl(struct inode *inode, struct file *file, | 235 | unsigned long arg) |
250 | unsigned int cmd, unsigned long arg) | ||
251 | { | 236 | { |
252 | void __user *argp = (void __user *)arg; | 237 | void __user *argp = (void __user *)arg; |
253 | int __user *p = argp; | 238 | int __user *p = argp; |
@@ -302,19 +287,16 @@ it8712f_wdt_ioctl(struct inode *inode, struct file *file, | |||
302 | } | 287 | } |
303 | } | 288 | } |
304 | 289 | ||
305 | static int | 290 | static int it8712f_wdt_open(struct inode *inode, struct file *file) |
306 | it8712f_wdt_open(struct inode *inode, struct file *file) | ||
307 | { | 291 | { |
308 | /* only allow one at a time */ | 292 | /* only allow one at a time */ |
309 | if (down_trylock(&it8712f_wdt_sem)) | 293 | if (test_and_set_bit(0, &wdt_open)) |
310 | return -EBUSY; | 294 | return -EBUSY; |
311 | it8712f_wdt_enable(); | 295 | it8712f_wdt_enable(); |
312 | |||
313 | return nonseekable_open(inode, file); | 296 | return nonseekable_open(inode, file); |
314 | } | 297 | } |
315 | 298 | ||
316 | static int | 299 | static int it8712f_wdt_release(struct inode *inode, struct file *file) |
317 | it8712f_wdt_release(struct inode *inode, struct file *file) | ||
318 | { | 300 | { |
319 | if (expect_close != 42) { | 301 | if (expect_close != 42) { |
320 | printk(KERN_WARNING NAME | 302 | printk(KERN_WARNING NAME |
@@ -324,7 +306,7 @@ it8712f_wdt_release(struct inode *inode, struct file *file) | |||
324 | it8712f_wdt_disable(); | 306 | it8712f_wdt_disable(); |
325 | } | 307 | } |
326 | expect_close = 0; | 308 | expect_close = 0; |
327 | up(&it8712f_wdt_sem); | 309 | clear_bit(0, &wdt_open); |
328 | 310 | ||
329 | return 0; | 311 | return 0; |
330 | } | 312 | } |
@@ -333,7 +315,7 @@ static const struct file_operations it8712f_wdt_fops = { | |||
333 | .owner = THIS_MODULE, | 315 | .owner = THIS_MODULE, |
334 | .llseek = no_llseek, | 316 | .llseek = no_llseek, |
335 | .write = it8712f_wdt_write, | 317 | .write = it8712f_wdt_write, |
336 | .ioctl = it8712f_wdt_ioctl, | 318 | .unlocked_ioctl = it8712f_wdt_ioctl, |
337 | .open = it8712f_wdt_open, | 319 | .open = it8712f_wdt_open, |
338 | .release = it8712f_wdt_release, | 320 | .release = it8712f_wdt_release, |
339 | }; | 321 | }; |
@@ -344,8 +326,7 @@ static struct miscdevice it8712f_wdt_miscdev = { | |||
344 | .fops = &it8712f_wdt_fops, | 326 | .fops = &it8712f_wdt_fops, |
345 | }; | 327 | }; |
346 | 328 | ||
347 | static int __init | 329 | static int __init it8712f_wdt_find(unsigned short *address) |
348 | it8712f_wdt_find(unsigned short *address) | ||
349 | { | 330 | { |
350 | int err = -ENODEV; | 331 | int err = -ENODEV; |
351 | int chip_type; | 332 | int chip_type; |
@@ -387,8 +368,7 @@ exit: | |||
387 | return err; | 368 | return err; |
388 | } | 369 | } |
389 | 370 | ||
390 | static int __init | 371 | static int __init it8712f_wdt_init(void) |
391 | it8712f_wdt_init(void) | ||
392 | { | 372 | { |
393 | int err = 0; | 373 | int err = 0; |
394 | 374 | ||
@@ -404,8 +384,6 @@ it8712f_wdt_init(void) | |||
404 | 384 | ||
405 | it8712f_wdt_disable(); | 385 | it8712f_wdt_disable(); |
406 | 386 | ||
407 | sema_init(&it8712f_wdt_sem, 1); | ||
408 | |||
409 | err = register_reboot_notifier(&it8712f_wdt_notifier); | 387 | err = register_reboot_notifier(&it8712f_wdt_notifier); |
410 | if (err) { | 388 | if (err) { |
411 | printk(KERN_ERR NAME ": unable to register reboot notifier\n"); | 389 | printk(KERN_ERR NAME ": unable to register reboot notifier\n"); |
@@ -430,8 +408,7 @@ out: | |||
430 | return err; | 408 | return err; |
431 | } | 409 | } |
432 | 410 | ||
433 | static void __exit | 411 | static void __exit it8712f_wdt_exit(void) |
434 | it8712f_wdt_exit(void) | ||
435 | { | 412 | { |
436 | misc_deregister(&it8712f_wdt_miscdev); | 413 | misc_deregister(&it8712f_wdt_miscdev); |
437 | unregister_reboot_notifier(&it8712f_wdt_notifier); | 414 | unregister_reboot_notifier(&it8712f_wdt_notifier); |
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 98532c0e068..97b4a2e8eb0 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -46,9 +46,8 @@ | |||
46 | #include <linux/platform_device.h> | 46 | #include <linux/platform_device.h> |
47 | #include <linux/interrupt.h> | 47 | #include <linux/interrupt.h> |
48 | #include <linux/clk.h> | 48 | #include <linux/clk.h> |
49 | 49 | #include <linux/uaccess.h> | |
50 | #include <asm/uaccess.h> | 50 | #include <linux/io.h> |
51 | #include <asm/io.h> | ||
52 | 51 | ||
53 | #include <asm/arch/map.h> | 52 | #include <asm/arch/map.h> |
54 | 53 | ||
@@ -65,8 +64,8 @@ | |||
65 | static int nowayout = WATCHDOG_NOWAYOUT; | 64 | static int nowayout = WATCHDOG_NOWAYOUT; |
66 | static int tmr_margin = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME; | 65 | static int tmr_margin = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME; |
67 | static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; | 66 | static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; |
68 | static int soft_noboot = 0; | 67 | static int soft_noboot; |
69 | static int debug = 0; | 68 | static int debug; |
70 | 69 | ||
71 | module_param(tmr_margin, int, 0); | 70 | module_param(tmr_margin, int, 0); |
72 | module_param(tmr_atboot, int, 0); | 71 | module_param(tmr_atboot, int, 0); |
@@ -74,24 +73,23 @@ module_param(nowayout, int, 0); | |||
74 | module_param(soft_noboot, int, 0); | 73 | module_param(soft_noboot, int, 0); |
75 | module_param(debug, int, 0); | 74 | module_param(debug, int, 0); |
76 | 75 | ||
77 | MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME) ")"); | 76 | MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. default=" |
78 | 77 | __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME) ")"); | |
79 | MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); | 78 | MODULE_PARM_DESC(tmr_atboot, |
80 | 79 | "Watchdog is started at boot time if set to 1, default=" | |
81 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 80 | __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); |
82 | 81 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | |
82 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
83 | MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); | 83 | MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default depends on ONLY_TESTING)"); |
84 | |||
85 | MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)"); | 84 | MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug, (default 0)"); |
86 | 85 | ||
87 | 86 | ||
88 | typedef enum close_state { | 87 | typedef enum close_state { |
89 | CLOSE_STATE_NOT, | 88 | CLOSE_STATE_NOT, |
90 | CLOSE_STATE_ALLOW=0x4021 | 89 | CLOSE_STATE_ALLOW = 0x4021 |
91 | } close_state_t; | 90 | } close_state_t; |
92 | 91 | ||
93 | static DECLARE_MUTEX(open_lock); | 92 | static unsigned long open_lock; |
94 | |||
95 | static struct device *wdt_dev; /* platform device attached to */ | 93 | static struct device *wdt_dev; /* platform device attached to */ |
96 | static struct resource *wdt_mem; | 94 | static struct resource *wdt_mem; |
97 | static struct resource *wdt_irq; | 95 | static struct resource *wdt_irq; |
@@ -99,38 +97,58 @@ static struct clk *wdt_clock; | |||
99 | static void __iomem *wdt_base; | 97 | static void __iomem *wdt_base; |
100 | static unsigned int wdt_count; | 98 | static unsigned int wdt_count; |
101 | static close_state_t allow_close; | 99 | static close_state_t allow_close; |
100 | static DEFINE_SPINLOCK(wdt_lock); | ||
102 | 101 | ||
103 | /* watchdog control routines */ | 102 | /* watchdog control routines */ |
104 | 103 | ||
105 | #define DBG(msg...) do { \ | 104 | #define DBG(msg...) do { \ |
106 | if (debug) \ | 105 | if (debug) \ |
107 | printk(KERN_INFO msg); \ | 106 | printk(KERN_INFO msg); \ |
108 | } while(0) | 107 | } while (0) |
109 | 108 | ||
110 | /* functions */ | 109 | /* functions */ |
111 | 110 | ||
112 | static int s3c2410wdt_keepalive(void) | 111 | static void s3c2410wdt_keepalive(void) |
113 | { | 112 | { |
113 | spin_lock(&wdt_lock); | ||
114 | writel(wdt_count, wdt_base + S3C2410_WTCNT); | 114 | writel(wdt_count, wdt_base + S3C2410_WTCNT); |
115 | return 0; | 115 | spin_unlock(&wdt_lock); |
116 | } | 116 | } |
117 | 117 | ||
118 | static int s3c2410wdt_stop(void) | 118 | static void __s3c2410wdt_stop(void) |
119 | { | 119 | { |
120 | unsigned long wtcon; | 120 | unsigned long wtcon; |
121 | 121 | ||
122 | spin_lock(&wdt_lock); | ||
122 | wtcon = readl(wdt_base + S3C2410_WTCON); | 123 | wtcon = readl(wdt_base + S3C2410_WTCON); |
123 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); | 124 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); |
124 | writel(wtcon, wdt_base + S3C2410_WTCON); | 125 | writel(wtcon, wdt_base + S3C2410_WTCON); |
126 | spin_unlock(&wdt_lock); | ||
127 | } | ||
125 | 128 | ||
126 | return 0; | 129 | static void __s3c2410wdt_stop(void) |
130 | { | ||
131 | unsigned long wtcon; | ||
132 | |||
133 | wtcon = readl(wdt_base + S3C2410_WTCON); | ||
134 | wtcon &= ~(S3C2410_WTCON_ENABLE | S3C2410_WTCON_RSTEN); | ||
135 | writel(wtcon, wdt_base + S3C2410_WTCON); | ||
136 | } | ||
137 | |||
138 | static void s3c2410wdt_stop(void) | ||
139 | { | ||
140 | spin_lock(&wdt_lock); | ||
141 | __s3c2410wdt_stop(); | ||
142 | spin_unlock(&wdt_lock); | ||
127 | } | 143 | } |
128 | 144 | ||
129 | static int s3c2410wdt_start(void) | 145 | static void s3c2410wdt_start(void) |
130 | { | 146 | { |
131 | unsigned long wtcon; | 147 | unsigned long wtcon; |
132 | 148 | ||
133 | s3c2410wdt_stop(); | 149 | spin_lock(&wdt_lock); |
150 | |||
151 | __s3c2410wdt_stop(); | ||
134 | 152 | ||
135 | wtcon = readl(wdt_base + S3C2410_WTCON); | 153 | wtcon = readl(wdt_base + S3C2410_WTCON); |
136 | wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128; | 154 | wtcon |= S3C2410_WTCON_ENABLE | S3C2410_WTCON_DIV128; |
@@ -149,6 +167,7 @@ static int s3c2410wdt_start(void) | |||
149 | writel(wdt_count, wdt_base + S3C2410_WTDAT); | 167 | writel(wdt_count, wdt_base + S3C2410_WTDAT); |
150 | writel(wdt_count, wdt_base + S3C2410_WTCNT); | 168 | writel(wdt_count, wdt_base + S3C2410_WTCNT); |
151 | writel(wtcon, wdt_base + S3C2410_WTCON); | 169 | writel(wtcon, wdt_base + S3C2410_WTCON); |
170 | spin_unlock(&wdt_lock); | ||
152 | 171 | ||
153 | return 0; | 172 | return 0; |
154 | } | 173 | } |
@@ -211,7 +230,7 @@ static int s3c2410wdt_set_heartbeat(int timeout) | |||
211 | 230 | ||
212 | static int s3c2410wdt_open(struct inode *inode, struct file *file) | 231 | static int s3c2410wdt_open(struct inode *inode, struct file *file) |
213 | { | 232 | { |
214 | if(down_trylock(&open_lock)) | 233 | if (test_and_set_bit(0, &open_lock)) |
215 | return -EBUSY; | 234 | return -EBUSY; |
216 | 235 | ||
217 | if (nowayout) | 236 | if (nowayout) |
@@ -231,15 +250,14 @@ static int s3c2410wdt_release(struct inode *inode, struct file *file) | |||
231 | * Lock it in if it's a module and we set nowayout | 250 | * Lock it in if it's a module and we set nowayout |
232 | */ | 251 | */ |
233 | 252 | ||
234 | if (allow_close == CLOSE_STATE_ALLOW) { | 253 | if (allow_close == CLOSE_STATE_ALLOW) |
235 | s3c2410wdt_stop(); | 254 | s3c2410wdt_stop(); |
236 | } else { | 255 | else { |
237 | dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); | 256 | dev_err(wdt_dev, "Unexpected close, not stopping watchdog\n"); |
238 | s3c2410wdt_keepalive(); | 257 | s3c2410wdt_keepalive(); |
239 | } | 258 | } |
240 | |||
241 | allow_close = CLOSE_STATE_NOT; | 259 | allow_close = CLOSE_STATE_NOT; |
242 | up(&open_lock); | 260 | clear_bit(0, &open_lock); |
243 | return 0; | 261 | return 0; |
244 | } | 262 | } |
245 | 263 | ||
@@ -249,7 +267,7 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, | |||
249 | /* | 267 | /* |
250 | * Refresh the timer. | 268 | * Refresh the timer. |
251 | */ | 269 | */ |
252 | if(len) { | 270 | if (len) { |
253 | if (!nowayout) { | 271 | if (!nowayout) { |
254 | size_t i; | 272 | size_t i; |
255 | 273 | ||
@@ -265,7 +283,6 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, | |||
265 | allow_close = CLOSE_STATE_ALLOW; | 283 | allow_close = CLOSE_STATE_ALLOW; |
266 | } | 284 | } |
267 | } | 285 | } |
268 | |||
269 | s3c2410wdt_keepalive(); | 286 | s3c2410wdt_keepalive(); |
270 | } | 287 | } |
271 | return len; | 288 | return len; |
@@ -273,48 +290,41 @@ static ssize_t s3c2410wdt_write(struct file *file, const char __user *data, | |||
273 | 290 | ||
274 | #define OPTIONS WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | 291 | #define OPTIONS WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE |
275 | 292 | ||
276 | static struct watchdog_info s3c2410_wdt_ident = { | 293 | static const struct watchdog_info s3c2410_wdt_ident = { |
277 | .options = OPTIONS, | 294 | .options = OPTIONS, |
278 | .firmware_version = 0, | 295 | .firmware_version = 0, |
279 | .identity = "S3C2410 Watchdog", | 296 | .identity = "S3C2410 Watchdog", |
280 | }; | 297 | }; |
281 | 298 | ||
282 | 299 | ||
283 | static int s3c2410wdt_ioctl(struct inode *inode, struct file *file, | 300 | static long s3c2410wdt_ioctl(struct file *file, unsigned int cmd, |
284 | unsigned int cmd, unsigned long arg) | 301 | unsigned long arg) |
285 | { | 302 | { |
286 | void __user *argp = (void __user *)arg; | 303 | void __user *argp = (void __user *)arg; |
287 | int __user *p = argp; | 304 | int __user *p = argp; |
288 | int new_margin; | 305 | int new_margin; |
289 | 306 | ||
290 | switch (cmd) { | 307 | switch (cmd) { |
291 | default: | 308 | default: |
292 | return -ENOTTY; | 309 | return -ENOTTY; |
293 | 310 | case WDIOC_GETSUPPORT: | |
294 | case WDIOC_GETSUPPORT: | 311 | return copy_to_user(argp, &s3c2410_wdt_ident, |
295 | return copy_to_user(argp, &s3c2410_wdt_ident, | 312 | sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; |
296 | sizeof(s3c2410_wdt_ident)) ? -EFAULT : 0; | 313 | case WDIOC_GETSTATUS: |
297 | 314 | case WDIOC_GETBOOTSTATUS: | |
298 | case WDIOC_GETSTATUS: | 315 | return put_user(0, p); |
299 | case WDIOC_GETBOOTSTATUS: | 316 | case WDIOC_KEEPALIVE: |
300 | return put_user(0, p); | 317 | s3c2410wdt_keepalive(); |
301 | 318 | return 0; | |
302 | case WDIOC_KEEPALIVE: | 319 | case WDIOC_SETTIMEOUT: |
303 | s3c2410wdt_keepalive(); | 320 | if (get_user(new_margin, p)) |
304 | return 0; | 321 | return -EFAULT; |
305 | 322 | if (s3c2410wdt_set_heartbeat(new_margin)) | |
306 | case WDIOC_SETTIMEOUT: | 323 | return -EINVAL; |
307 | if (get_user(new_margin, p)) | 324 | s3c2410wdt_keepalive(); |
308 | return -EFAULT; | 325 | return put_user(tmr_margin, p); |
309 | 326 | case WDIOC_GETTIMEOUT: | |
310 | if (s3c2410wdt_set_heartbeat(new_margin)) | 327 | return put_user(tmr_margin, p); |
311 | return -EINVAL; | ||
312 | |||
313 | s3c2410wdt_keepalive(); | ||
314 | return put_user(tmr_margin, p); | ||
315 | |||
316 | case WDIOC_GETTIMEOUT: | ||
317 | return put_user(tmr_margin, p); | ||
318 | } | 328 | } |
319 | } | 329 | } |
320 | 330 | ||
@@ -324,7 +334,7 @@ static const struct file_operations s3c2410wdt_fops = { | |||
324 | .owner = THIS_MODULE, | 334 | .owner = THIS_MODULE, |
325 | .llseek = no_llseek, | 335 | .llseek = no_llseek, |
326 | .write = s3c2410wdt_write, | 336 | .write = s3c2410wdt_write, |
327 | .ioctl = s3c2410wdt_ioctl, | 337 | .unlocked_ioctl = s3c2410wdt_ioctl, |
328 | .open = s3c2410wdt_open, | 338 | .open = s3c2410wdt_open, |
329 | .release = s3c2410wdt_release, | 339 | .release = s3c2410wdt_release, |
330 | }; | 340 | }; |
@@ -411,14 +421,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
411 | * not, try the default value */ | 421 | * not, try the default value */ |
412 | 422 | ||
413 | if (s3c2410wdt_set_heartbeat(tmr_margin)) { | 423 | if (s3c2410wdt_set_heartbeat(tmr_margin)) { |
414 | started = s3c2410wdt_set_heartbeat(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); | 424 | started = s3c2410wdt_set_heartbeat( |
425 | CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); | ||
415 | 426 | ||
416 | if (started == 0) { | 427 | if (started == 0) |
417 | dev_info(dev,"tmr_margin value out of range, default %d used\n", | 428 | dev_info(dev, |
429 | "tmr_margin value out of range, default %d used\n", | ||
418 | CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); | 430 | CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); |
419 | } else { | 431 | else |
420 | dev_info(dev, "default timer value is out of range, cannot start\n"); | 432 | dev_info(dev, "default timer value is out of range, cannot start\n"); |
421 | } | ||
422 | } | 433 | } |
423 | 434 | ||
424 | ret = misc_register(&s3c2410wdt_miscdev); | 435 | ret = misc_register(&s3c2410wdt_miscdev); |
@@ -447,7 +458,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) | |||
447 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", | 458 | (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", |
448 | (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", | 459 | (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", |
449 | (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); | 460 | (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); |
450 | 461 | ||
451 | return 0; | 462 | return 0; |
452 | 463 | ||
453 | err_clk: | 464 | err_clk: |
@@ -487,7 +498,7 @@ static int s3c2410wdt_remove(struct platform_device *dev) | |||
487 | 498 | ||
488 | static void s3c2410wdt_shutdown(struct platform_device *dev) | 499 | static void s3c2410wdt_shutdown(struct platform_device *dev) |
489 | { | 500 | { |
490 | s3c2410wdt_stop(); | 501 | s3c2410wdt_stop(); |
491 | } | 502 | } |
492 | 503 | ||
493 | #ifdef CONFIG_PM | 504 | #ifdef CONFIG_PM |
@@ -540,7 +551,8 @@ static struct platform_driver s3c2410wdt_driver = { | |||
540 | }; | 551 | }; |
541 | 552 | ||
542 | 553 | ||
543 | static char banner[] __initdata = KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n"; | 554 | static char banner[] __initdata = |
555 | KERN_INFO "S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics\n"; | ||
544 | 556 | ||
545 | static int __init watchdog_init(void) | 557 | static int __init watchdog_init(void) |
546 | { | 558 | { |
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c index 35cddff7020..621ebad56d8 100644 --- a/drivers/watchdog/sc1200wdt.c +++ b/drivers/watchdog/sc1200wdt.c | |||
@@ -15,14 +15,18 @@ | |||
15 | * | 15 | * |
16 | * Changelog: | 16 | * Changelog: |
17 | * 20020220 Zwane Mwaikambo Code based on datasheet, no hardware. | 17 | * 20020220 Zwane Mwaikambo Code based on datasheet, no hardware. |
18 | * 20020221 Zwane Mwaikambo Cleanups as suggested by Jeff Garzik and Alan Cox. | 18 | * 20020221 Zwane Mwaikambo Cleanups as suggested by Jeff Garzik |
19 | * and Alan Cox. | ||
19 | * 20020222 Zwane Mwaikambo Added probing. | 20 | * 20020222 Zwane Mwaikambo Added probing. |
20 | * 20020225 Zwane Mwaikambo Added ISAPNP support. | 21 | * 20020225 Zwane Mwaikambo Added ISAPNP support. |
21 | * 20020412 Rob Radez Broke out start/stop functions | 22 | * 20020412 Rob Radez Broke out start/stop functions |
22 | * <rob@osinvestor.com> Return proper status instead of temperature warning | 23 | * <rob@osinvestor.com> Return proper status instead of |
23 | * Add WDIOC_GETBOOTSTATUS and WDIOC_SETOPTIONS ioctls | 24 | * temperature warning |
25 | * Add WDIOC_GETBOOTSTATUS and | ||
26 | * WDIOC_SETOPTIONS ioctls | ||
24 | * Fix CONFIG_WATCHDOG_NOWAYOUT | 27 | * Fix CONFIG_WATCHDOG_NOWAYOUT |
25 | * 20020530 Joel Becker Add Matt Domsch's nowayout module option | 28 | * 20020530 Joel Becker Add Matt Domsch's nowayout module |
29 | * option | ||
26 | * 20030116 Adam Belay Updated to the latest pnp code | 30 | * 20030116 Adam Belay Updated to the latest pnp code |
27 | * | 31 | * |
28 | */ | 32 | */ |
@@ -39,9 +43,8 @@ | |||
39 | #include <linux/pnp.h> | 43 | #include <linux/pnp.h> |
40 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
41 | #include <linux/semaphore.h> | 45 | #include <linux/semaphore.h> |
42 | 46 | #include <linux/io.h> | |
43 | #include <asm/io.h> | 47 | #include <linux/uaccess.h> |
44 | #include <asm/uaccess.h> | ||
45 | 48 | ||
46 | #define SC1200_MODULE_VER "build 20020303" | 49 | #define SC1200_MODULE_VER "build 20020303" |
47 | #define SC1200_MODULE_NAME "sc1200wdt" | 50 | #define SC1200_MODULE_NAME "sc1200wdt" |
@@ -72,7 +75,7 @@ static char banner[] __initdata = KERN_INFO PFX SC1200_MODULE_VER; | |||
72 | static int timeout = 1; | 75 | static int timeout = 1; |
73 | static int io = -1; | 76 | static int io = -1; |
74 | static int io_len = 2; /* for non plug and play */ | 77 | static int io_len = 2; /* for non plug and play */ |
75 | static struct semaphore open_sem; | 78 | static unsigned long open_flag; |
76 | static char expect_close; | 79 | static char expect_close; |
77 | static DEFINE_SPINLOCK(sc1200wdt_lock); /* io port access serialisation */ | 80 | static DEFINE_SPINLOCK(sc1200wdt_lock); /* io port access serialisation */ |
78 | 81 | ||
@@ -81,7 +84,8 @@ static int isapnp = 1; | |||
81 | static struct pnp_dev *wdt_dev; | 84 | static struct pnp_dev *wdt_dev; |
82 | 85 | ||
83 | module_param(isapnp, int, 0); | 86 | module_param(isapnp, int, 0); |
84 | MODULE_PARM_DESC(isapnp, "When set to 0 driver ISA PnP support will be disabled"); | 87 | MODULE_PARM_DESC(isapnp, |
88 | "When set to 0 driver ISA PnP support will be disabled"); | ||
85 | #endif | 89 | #endif |
86 | 90 | ||
87 | module_param(io, int, 0); | 91 | module_param(io, int, 0); |
@@ -91,26 +95,40 @@ MODULE_PARM_DESC(timeout, "range is 0-255 minutes, default is 1"); | |||
91 | 95 | ||
92 | static int nowayout = WATCHDOG_NOWAYOUT; | 96 | static int nowayout = WATCHDOG_NOWAYOUT; |
93 | module_param(nowayout, int, 0); | 97 | module_param(nowayout, int, 0); |
94 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 98 | MODULE_PARM_DESC(nowayout, |
99 | "Watchdog cannot be stopped once started (default=" | ||
100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
95 | 101 | ||
96 | 102 | ||
97 | 103 | ||
98 | /* Read from Data Register */ | 104 | /* Read from Data Register */ |
99 | static inline void sc1200wdt_read_data(unsigned char index, unsigned char *data) | 105 | static inline void __sc1200wdt_read_data(unsigned char index, |
106 | unsigned char *data) | ||
100 | { | 107 | { |
101 | spin_lock(&sc1200wdt_lock); | ||
102 | outb_p(index, PMIR); | 108 | outb_p(index, PMIR); |
103 | *data = inb(PMDR); | 109 | *data = inb(PMDR); |
104 | spin_unlock(&sc1200wdt_lock); | ||
105 | } | 110 | } |
106 | 111 | ||
112 | static void sc1200wdt_read_data(unsigned char index, unsigned char *data) | ||
113 | { | ||
114 | spin_lock(&sc1200wdt_lock); | ||
115 | __sc1200wdt_read_data(index, data); | ||
116 | spin_unlock(&sc1200wdt_lock); | ||
117 | } | ||
107 | 118 | ||
108 | /* Write to Data Register */ | 119 | /* Write to Data Register */ |
109 | static inline void sc1200wdt_write_data(unsigned char index, unsigned char data) | 120 | static inline void __sc1200wdt_write_data(unsigned char index, |
121 | unsigned char data) | ||
110 | { | 122 | { |
111 | spin_lock(&sc1200wdt_lock); | ||
112 | outb_p(index, PMIR); | 123 | outb_p(index, PMIR); |
113 | outb(data, PMDR); | 124 | outb(data, PMDR); |
125 | } | ||
126 | |||
127 | static inline void sc1200wdt_write_data(unsigned char index, | ||
128 | unsigned char data) | ||
129 | { | ||
130 | spin_lock(&sc1200wdt_lock); | ||
131 | __sc1200wdt_write_data(index, data); | ||
114 | spin_unlock(&sc1200wdt_lock); | 132 | spin_unlock(&sc1200wdt_lock); |
115 | } | 133 | } |
116 | 134 | ||
@@ -118,22 +136,23 @@ static inline void sc1200wdt_write_data(unsigned char index, unsigned char data) | |||
118 | static void sc1200wdt_start(void) | 136 | static void sc1200wdt_start(void) |
119 | { | 137 | { |
120 | unsigned char reg; | 138 | unsigned char reg; |
139 | spin_lock(&sc1200wdt_lock); | ||
121 | 140 | ||
122 | sc1200wdt_read_data(WDCF, ®); | 141 | __sc1200wdt_read_data(WDCF, ®); |
123 | /* assert WDO when any of the following interrupts are triggered too */ | 142 | /* assert WDO when any of the following interrupts are triggered too */ |
124 | reg |= (KBC_IRQ | MSE_IRQ | UART1_IRQ | UART2_IRQ); | 143 | reg |= (KBC_IRQ | MSE_IRQ | UART1_IRQ | UART2_IRQ); |
125 | sc1200wdt_write_data(WDCF, reg); | 144 | __sc1200wdt_write_data(WDCF, reg); |
126 | /* set the timeout and get the ball rolling */ | 145 | /* set the timeout and get the ball rolling */ |
127 | sc1200wdt_write_data(WDTO, timeout); | 146 | __sc1200wdt_write_data(WDTO, timeout); |
128 | } | ||
129 | 147 | ||
148 | spin_unlock(&sc1200wdt_lock); | ||
149 | } | ||
130 | 150 | ||
131 | static void sc1200wdt_stop(void) | 151 | static void sc1200wdt_stop(void) |
132 | { | 152 | { |
133 | sc1200wdt_write_data(WDTO, 0); | 153 | sc1200wdt_write_data(WDTO, 0); |
134 | } | 154 | } |
135 | 155 | ||
136 | |||
137 | /* This returns the status of the WDO signal, inactive high. */ | 156 | /* This returns the status of the WDO signal, inactive high. */ |
138 | static inline int sc1200wdt_status(void) | 157 | static inline int sc1200wdt_status(void) |
139 | { | 158 | { |
@@ -144,14 +163,13 @@ static inline int sc1200wdt_status(void) | |||
144 | * KEEPALIVEPING which is a bit of a kludge because there's nothing | 163 | * KEEPALIVEPING which is a bit of a kludge because there's nothing |
145 | * else for enabled/disabled status | 164 | * else for enabled/disabled status |
146 | */ | 165 | */ |
147 | return (ret & 0x01) ? 0 : WDIOF_KEEPALIVEPING; /* bits 1 - 7 are undefined */ | 166 | return (ret & 0x01) ? 0 : WDIOF_KEEPALIVEPING; |
148 | } | 167 | } |
149 | 168 | ||
150 | |||
151 | static int sc1200wdt_open(struct inode *inode, struct file *file) | 169 | static int sc1200wdt_open(struct inode *inode, struct file *file) |
152 | { | 170 | { |
153 | /* allow one at a time */ | 171 | /* allow one at a time */ |
154 | if (down_trylock(&open_sem)) | 172 | if (test_and_set_bit(0, &open_flag)) |
155 | return -EBUSY; | 173 | return -EBUSY; |
156 | 174 | ||
157 | if (timeout > MAX_TIMEOUT) | 175 | if (timeout > MAX_TIMEOUT) |
@@ -164,71 +182,71 @@ static int sc1200wdt_open(struct inode *inode, struct file *file) | |||
164 | } | 182 | } |
165 | 183 | ||
166 | 184 | ||
167 | static int sc1200wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | 185 | static long sc1200wdt_ioctl(struct file *file, unsigned int cmd, |
186 | unsigned long arg) | ||
168 | { | 187 | { |
169 | int new_timeout; | 188 | int new_timeout; |
170 | void __user *argp = (void __user *)arg; | 189 | void __user *argp = (void __user *)arg; |
171 | int __user *p = argp; | 190 | int __user *p = argp; |
172 | static struct watchdog_info ident = { | 191 | static const struct watchdog_info ident = { |
173 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE, | 192 | .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | |
193 | WDIOF_MAGICCLOSE, | ||
174 | .firmware_version = 0, | 194 | .firmware_version = 0, |
175 | .identity = "PC87307/PC97307", | 195 | .identity = "PC87307/PC97307", |
176 | }; | 196 | }; |
177 | 197 | ||
178 | switch (cmd) { | 198 | switch (cmd) { |
179 | default: | ||
180 | return -ENOTTY; | ||
181 | |||
182 | case WDIOC_GETSUPPORT: | ||
183 | if (copy_to_user(argp, &ident, sizeof ident)) | ||
184 | return -EFAULT; | ||
185 | return 0; | ||
186 | |||
187 | case WDIOC_GETSTATUS: | ||
188 | return put_user(sc1200wdt_status(), p); | ||
189 | |||
190 | case WDIOC_GETBOOTSTATUS: | ||
191 | return put_user(0, p); | ||
192 | |||
193 | case WDIOC_KEEPALIVE: | ||
194 | sc1200wdt_write_data(WDTO, timeout); | ||
195 | return 0; | ||
196 | 199 | ||
197 | case WDIOC_SETTIMEOUT: | 200 | case WDIOC_GETSUPPORT: |
198 | if (get_user(new_timeout, p)) | 201 | if (copy_to_user(argp, &ident, sizeof ident)) |
199 | return -EFAULT; | 202 | return -EFAULT; |
203 | return 0; | ||
200 | 204 | ||
201 | /* the API states this is given in secs */ | 205 | case WDIOC_GETSTATUS: |
202 | new_timeout /= 60; | 206 | return put_user(sc1200wdt_status(), p); |
203 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
204 | return -EINVAL; | ||
205 | 207 | ||
206 | timeout = new_timeout; | 208 | case WDIOC_GETBOOTSTATUS: |
207 | sc1200wdt_write_data(WDTO, timeout); | 209 | return put_user(0, p); |
208 | /* fall through and return the new timeout */ | ||
209 | 210 | ||
210 | case WDIOC_GETTIMEOUT: | 211 | case WDIOC_KEEPALIVE: |
211 | return put_user(timeout * 60, p); | 212 | sc1200wdt_write_data(WDTO, timeout); |
213 | return 0; | ||
214 | |||
215 | case WDIOC_SETTIMEOUT: | ||
216 | if (get_user(new_timeout, p)) | ||
217 | return -EFAULT; | ||
218 | /* the API states this is given in secs */ | ||
219 | new_timeout /= 60; | ||
220 | if (new_timeout < 0 || new_timeout > MAX_TIMEOUT) | ||
221 | return -EINVAL; | ||
222 | timeout = new_timeout; | ||
223 | sc1200wdt_write_data(WDTO, timeout); | ||
224 | /* fall through and return the new timeout */ | ||
212 | 225 | ||
213 | case WDIOC_SETOPTIONS: | 226 | case WDIOC_GETTIMEOUT: |
214 | { | 227 | return put_user(timeout * 60, p); |
215 | int options, retval = -EINVAL; | ||
216 | 228 | ||
217 | if (get_user(options, p)) | 229 | case WDIOC_SETOPTIONS: |
218 | return -EFAULT; | 230 | { |
231 | int options, retval = -EINVAL; | ||
219 | 232 | ||
220 | if (options & WDIOS_DISABLECARD) { | 233 | if (get_user(options, p)) |
221 | sc1200wdt_stop(); | 234 | return -EFAULT; |
222 | retval = 0; | ||
223 | } | ||
224 | 235 | ||
225 | if (options & WDIOS_ENABLECARD) { | 236 | if (options & WDIOS_DISABLECARD) { |
226 | sc1200wdt_start(); | 237 | sc1200wdt_stop(); |
227 | retval = 0; | 238 | retval = 0; |
228 | } | 239 | } |
229 | 240 | ||
230 | return retval; | 241 | if (options & WDIOS_ENABLECARD) { |
242 | sc1200wdt_start(); | ||
243 | retval = 0; | ||
231 | } | 244 | } |
245 | |||
246 | return retval; | ||
247 | } | ||
248 | default: | ||
249 | return -ENOTTY; | ||
232 | } | 250 | } |
233 | } | 251 | } |
234 | 252 | ||
@@ -240,16 +258,18 @@ static int sc1200wdt_release(struct inode *inode, struct file *file) | |||
240 | printk(KERN_INFO PFX "Watchdog disabled\n"); | 258 | printk(KERN_INFO PFX "Watchdog disabled\n"); |
241 | } else { | 259 | } else { |
242 | sc1200wdt_write_data(WDTO, timeout); | 260 | sc1200wdt_write_data(WDTO, timeout); |
243 | printk(KERN_CRIT PFX "Unexpected close!, timeout = %d min(s)\n", timeout); | 261 | printk(KERN_CRIT PFX |
262 | "Unexpected close!, timeout = %d min(s)\n", timeout); | ||
244 | } | 263 | } |
245 | up(&open_sem); | 264 | clear_bit(0, &open_flag); |
246 | expect_close = 0; | 265 | expect_close = 0; |
247 | 266 | ||
248 | return 0; | 267 | return 0; |
249 | } | 268 | } |
250 | 269 | ||
251 | 270 | ||
252 | static ssize_t sc1200wdt_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) | 271 | static ssize_t sc1200wdt_write(struct file *file, const char __user *data, |
272 | size_t len, loff_t *ppos) | ||
253 | { | 273 | { |
254 | if (len) { | 274 | if (len) { |
255 | if (!nowayout) { | 275 | if (!nowayout) { |
@@ -275,7 +295,8 @@ static ssize_t sc1200wdt_write(struct file *file, const char __user *data, size_ | |||
275 | } | 295 | } |
276 | 296 | ||
277 | 297 | ||
278 | static int sc1200wdt_notify_sys(struct notifier_block *this, unsigned long code, void *unused) | 298 | static int sc1200wdt_notify_sys(struct notifier_block *this, |
299 | unsigned long code, void *unused) | ||
279 | { | 300 | { |
280 | if (code == SYS_DOWN || code == SYS_HALT) | 301 | if (code == SYS_DOWN || code == SYS_HALT) |
281 | sc1200wdt_stop(); | 302 | sc1200wdt_stop(); |
@@ -284,23 +305,20 @@ static int sc1200wdt_notify_sys(struct notifier_block *this, unsigned long code, | |||
284 | } | 305 | } |
285 | 306 | ||
286 | 307 | ||
287 | static struct notifier_block sc1200wdt_notifier = | 308 | static struct notifier_block sc1200wdt_notifier = { |
288 | { | ||
289 | .notifier_call = sc1200wdt_notify_sys, | 309 | .notifier_call = sc1200wdt_notify_sys, |
290 | }; | 310 | }; |
291 | 311 | ||
292 | static const struct file_operations sc1200wdt_fops = | 312 | static const struct file_operations sc1200wdt_fops = { |
293 | { | ||
294 | .owner = THIS_MODULE, | 313 | .owner = THIS_MODULE, |
295 | .llseek = no_llseek, | 314 | .llseek = no_llseek, |
296 | .write = sc1200wdt_write, | 315 | .write = sc1200wdt_write, |
297 | .ioctl = sc1200wdt_ioctl, | 316 | .unlocked_ioctl = sc1200wdt_ioctl, |
298 | .open = sc1200wdt_open, | 317 | .open = sc1200wdt_open, |
299 | .release = sc1200wdt_release, | 318 | .release = sc1200wdt_release, |
300 | }; | 319 | }; |
301 | 320 | ||
302 | static struct miscdevice sc1200wdt_miscdev = | 321 | static struct miscdevice sc1200wdt_miscdev = { |
303 | { | ||
304 | .minor = WATCHDOG_MINOR, | 322 | .minor = WATCHDOG_MINOR, |
305 | .name = "watchdog", | 323 | .name = "watchdog", |
306 | .fops = &sc1200wdt_fops, | 324 | .fops = &sc1200wdt_fops, |
@@ -312,14 +330,14 @@ static int __init sc1200wdt_probe(void) | |||
312 | /* The probe works by reading the PMC3 register's default value of 0x0e | 330 | /* The probe works by reading the PMC3 register's default value of 0x0e |
313 | * there is one caveat, if the device disables the parallel port or any | 331 | * there is one caveat, if the device disables the parallel port or any |
314 | * of the UARTs we won't be able to detect it. | 332 | * of the UARTs we won't be able to detect it. |
315 | * Nb. This could be done with accuracy by reading the SID registers, but | 333 | * NB. This could be done with accuracy by reading the SID registers, |
316 | * we don't have access to those io regions. | 334 | * but we don't have access to those io regions. |
317 | */ | 335 | */ |
318 | 336 | ||
319 | unsigned char reg; | 337 | unsigned char reg; |
320 | 338 | ||
321 | sc1200wdt_read_data(PMC3, ®); | 339 | sc1200wdt_read_data(PMC3, ®); |
322 | reg &= 0x0f; /* we don't want the UART busy bits */ | 340 | reg &= 0x0f; /* we don't want the UART busy bits */ |
323 | return (reg == 0x0e) ? 0 : -ENODEV; | 341 | return (reg == 0x0e) ? 0 : -ENODEV; |
324 | } | 342 | } |
325 | 343 | ||
@@ -332,7 +350,8 @@ static struct pnp_device_id scl200wdt_pnp_devices[] = { | |||
332 | {.id = ""}, | 350 | {.id = ""}, |
333 | }; | 351 | }; |
334 | 352 | ||
335 | static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) | 353 | static int scl200wdt_pnp_probe(struct pnp_dev *dev, |
354 | const struct pnp_device_id *dev_id) | ||
336 | { | 355 | { |
337 | /* this driver only supports one card at a time */ | 356 | /* this driver only supports one card at a time */ |
338 | if (wdt_dev || !isapnp) | 357 | if (wdt_dev || !isapnp) |
@@ -347,13 +366,14 @@ static int scl200wdt_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id | |||
347 | return -EBUSY; | 366 | return -EBUSY; |
348 | } | 367 | } |
349 | 368 | ||
350 | printk(KERN_INFO "scl200wdt: PnP device found at io port %#x/%d\n", io, io_len); | 369 | printk(KERN_INFO "scl200wdt: PnP device found at io port %#x/%d\n", |
370 | io, io_len); | ||
351 | return 0; | 371 | return 0; |
352 | } | 372 | } |
353 | 373 | ||
354 | static void scl200wdt_pnp_remove(struct pnp_dev * dev) | 374 | static void scl200wdt_pnp_remove(struct pnp_dev *dev) |
355 | { | 375 | { |
356 | if (wdt_dev){ | 376 | if (wdt_dev) { |
357 | release_region(io, io_len); | 377 | release_region(io, io_len); |
358 | wdt_dev = NULL; | 378 | wdt_dev = NULL; |
359 | } | 379 | } |
@@ -375,8 +395,6 @@ static int __init sc1200wdt_init(void) | |||
375 | 395 | ||
376 | printk("%s\n", banner); | 396 | printk("%s\n", banner); |
377 | 397 | ||
378 | sema_init(&open_sem, 1); | ||
379 | |||
380 | #if defined CONFIG_PNP | 398 | #if defined CONFIG_PNP |
381 | if (isapnp) { | 399 | if (isapnp) { |
382 | ret = pnp_register_driver(&scl200wdt_pnp_driver); | 400 | ret = pnp_register_driver(&scl200wdt_pnp_driver); |
@@ -410,13 +428,16 @@ static int __init sc1200wdt_init(void) | |||
410 | 428 | ||
411 | ret = register_reboot_notifier(&sc1200wdt_notifier); | 429 | ret = register_reboot_notifier(&sc1200wdt_notifier); |
412 | if (ret) { | 430 | if (ret) { |
413 | printk(KERN_ERR PFX "Unable to register reboot notifier err = %d\n", ret); | 431 | printk(KERN_ERR PFX |
432 | "Unable to register reboot notifier err = %d\n", ret); | ||
414 | goto out_io; | 433 | goto out_io; |
415 | } | 434 | } |
416 | 435 | ||
417 | ret = misc_register(&sc1200wdt_miscdev); | 436 | ret = misc_register(&sc1200wdt_miscdev); |
418 | if (ret) { | 437 | if (ret) { |
419 | printk(KERN_ERR PFX "Unable to register miscdev on minor %d\n", WATCHDOG_MINOR); | 438 | printk(KERN_ERR PFX |
439 | "Unable to register miscdev on minor %d\n", | ||
440 | WATCHDOG_MINOR); | ||
420 | goto out_rbt; | 441 | goto out_rbt; |
421 | } | 442 | } |
422 | 443 | ||
@@ -446,7 +467,7 @@ static void __exit sc1200wdt_exit(void) | |||
446 | unregister_reboot_notifier(&sc1200wdt_notifier); | 467 | unregister_reboot_notifier(&sc1200wdt_notifier); |
447 | 468 | ||
448 | #if defined CONFIG_PNP | 469 | #if defined CONFIG_PNP |
449 | if(isapnp) | 470 | if (isapnp) |
450 | pnp_unregister_driver(&scl200wdt_pnp_driver); | 471 | pnp_unregister_driver(&scl200wdt_pnp_driver); |
451 | else | 472 | else |
452 | #endif | 473 | #endif |
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 756fb15fdce..53a6b18bcb9 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c | |||
@@ -24,9 +24,10 @@ | |||
24 | * Matt Crocker). | 24 | * Matt Crocker). |
25 | * Alan Cox : Added wdt= boot option | 25 | * Alan Cox : Added wdt= boot option |
26 | * Alan Cox : Cleaned up copy/user stuff | 26 | * Alan Cox : Cleaned up copy/user stuff |
27 | * Tim Hockin : Added insmod parameters, comment cleanup | 27 | * Tim Hockin : Added insmod parameters, comment |
28 | * Parameterized timeout | 28 | * cleanup, parameterized timeout |
29 | * Tigran Aivazian : Restructured wdt_init() to handle failures | 29 | * Tigran Aivazian : Restructured wdt_init() to handle |
30 | * failures | ||
30 | * Joel Becker : Added WDIOC_GET/SETTIMEOUT | 31 | * Joel Becker : Added WDIOC_GET/SETTIMEOUT |
31 | * Matt Domsch : Added nowayout module option | 32 | * Matt Domsch : Added nowayout module option |
32 | */ | 33 | */ |
@@ -42,9 +43,9 @@ | |||
42 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
43 | #include <linux/reboot.h> | 44 | #include <linux/reboot.h> |
44 | #include <linux/init.h> | 45 | #include <linux/init.h> |
46 | #include <linux/io.h> | ||
47 | #include <linux/uaccess.h> | ||
45 | 48 | ||
46 | #include <asm/io.h> | ||
47 | #include <asm/uaccess.h> | ||
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
49 | #include "wd501p.h" | 50 | #include "wd501p.h" |
50 | 51 | ||
@@ -60,15 +61,19 @@ static char expect_close; | |||
60 | static int heartbeat = WD_TIMO; | 61 | static int heartbeat = WD_TIMO; |
61 | static int wd_heartbeat; | 62 | static int wd_heartbeat; |
62 | module_param(heartbeat, int, 0); | 63 | module_param(heartbeat, int, 0); |
63 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); | 64 | MODULE_PARM_DESC(heartbeat, |
65 | "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" | ||
66 | __MODULE_STRING(WD_TIMO) ")"); | ||
64 | 67 | ||
65 | static int nowayout = WATCHDOG_NOWAYOUT; | 68 | static int nowayout = WATCHDOG_NOWAYOUT; |
66 | module_param(nowayout, int, 0); | 69 | module_param(nowayout, int, 0); |
67 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 70 | MODULE_PARM_DESC(nowayout, |
71 | "Watchdog cannot be stopped once started (default=" | ||
72 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
68 | 73 | ||
69 | /* You must set these - there is no sane way to probe for this board. */ | 74 | /* You must set these - there is no sane way to probe for this board. */ |
70 | static int io=0x240; | 75 | static int io = 0x240; |
71 | static int irq=11; | 76 | static int irq = 11; |
72 | 77 | ||
73 | static DEFINE_SPINLOCK(wdt_lock); | 78 | static DEFINE_SPINLOCK(wdt_lock); |
74 | 79 | ||
@@ -82,7 +87,8 @@ MODULE_PARM_DESC(irq, "WDT irq (default=11)"); | |||
82 | static int tachometer; | 87 | static int tachometer; |
83 | 88 | ||
84 | module_param(tachometer, int, 0); | 89 | module_param(tachometer, int, 0); |
85 | MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, default=0)"); | 90 | MODULE_PARM_DESC(tachometer, |
91 | "WDT501-P Fan Tachometer support (0=disable, default=0)"); | ||
86 | #endif /* CONFIG_WDT_501 */ | 92 | #endif /* CONFIG_WDT_501 */ |
87 | 93 | ||
88 | /* | 94 | /* |
@@ -91,9 +97,9 @@ MODULE_PARM_DESC(tachometer, "WDT501-P Fan Tachometer support (0=disable, defaul | |||
91 | 97 | ||
92 | static void wdt_ctr_mode(int ctr, int mode) | 98 | static void wdt_ctr_mode(int ctr, int mode) |
93 | { | 99 | { |
94 | ctr<<=6; | 100 | ctr <<= 6; |
95 | ctr|=0x30; | 101 | ctr |= 0x30; |
96 | ctr|=(mode<<1); | 102 | ctr |= (mode << 1); |
97 | outb_p(ctr, WDT_CR); | 103 | outb_p(ctr, WDT_CR); |
98 | } | 104 | } |
99 | 105 | ||
@@ -114,12 +120,15 @@ static int wdt_start(void) | |||
114 | unsigned long flags; | 120 | unsigned long flags; |
115 | spin_lock_irqsave(&wdt_lock, flags); | 121 | spin_lock_irqsave(&wdt_lock, flags); |
116 | inb_p(WDT_DC); /* Disable watchdog */ | 122 | inb_p(WDT_DC); /* Disable watchdog */ |
117 | wdt_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ | 123 | wdt_ctr_mode(0, 3); /* Program CTR0 for Mode 3: |
118 | wdt_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ | 124 | Square Wave Generator */ |
119 | wdt_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ | 125 | wdt_ctr_mode(1, 2); /* Program CTR1 for Mode 2: |
126 | Rate Generator */ | ||
127 | wdt_ctr_mode(2, 0); /* Program CTR2 for Mode 0: | ||
128 | Pulse on Terminal Count */ | ||
120 | wdt_ctr_load(0, 8948); /* Count at 100Hz */ | 129 | wdt_ctr_load(0, 8948); /* Count at 100Hz */ |
121 | wdt_ctr_load(1,wd_heartbeat); /* Heartbeat */ | 130 | wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ |
122 | wdt_ctr_load(2,65535); /* Length of reset pulse */ | 131 | wdt_ctr_load(2, 65535); /* Length of reset pulse */ |
123 | outb_p(0, WDT_DC); /* Enable watchdog */ | 132 | outb_p(0, WDT_DC); /* Enable watchdog */ |
124 | spin_unlock_irqrestore(&wdt_lock, flags); | 133 | spin_unlock_irqrestore(&wdt_lock, flags); |
125 | return 0; | 134 | return 0; |
@@ -131,13 +140,13 @@ static int wdt_start(void) | |||
131 | * Stop the watchdog driver. | 140 | * Stop the watchdog driver. |
132 | */ | 141 | */ |
133 | 142 | ||
134 | static int wdt_stop (void) | 143 | static int wdt_stop(void) |
135 | { | 144 | { |
136 | unsigned long flags; | 145 | unsigned long flags; |
137 | spin_lock_irqsave(&wdt_lock, flags); | 146 | spin_lock_irqsave(&wdt_lock, flags); |
138 | /* Turn the card off */ | 147 | /* Turn the card off */ |
139 | inb_p(WDT_DC); /* Disable watchdog */ | 148 | inb_p(WDT_DC); /* Disable watchdog */ |
140 | wdt_ctr_load(2,0); /* 0 length reset pulses now */ | 149 | wdt_ctr_load(2, 0); /* 0 length reset pulses now */ |
141 | spin_unlock_irqrestore(&wdt_lock, flags); | 150 | spin_unlock_irqrestore(&wdt_lock, flags); |
142 | return 0; | 151 | return 0; |
143 | } | 152 | } |
@@ -145,8 +154,8 @@ static int wdt_stop (void) | |||
145 | /** | 154 | /** |
146 | * wdt_ping: | 155 | * wdt_ping: |
147 | * | 156 | * |
148 | * Reload counter one with the watchdog heartbeat. We don't bother reloading | 157 | * Reload counter one with the watchdog heartbeat. We don't bother |
149 | * the cascade counter. | 158 | * reloading the cascade counter. |
150 | */ | 159 | */ |
151 | 160 | ||
152 | static int wdt_ping(void) | 161 | static int wdt_ping(void) |
@@ -155,8 +164,9 @@ static int wdt_ping(void) | |||
155 | spin_lock_irqsave(&wdt_lock, flags); | 164 | spin_lock_irqsave(&wdt_lock, flags); |
156 | /* Write a watchdog value */ | 165 | /* Write a watchdog value */ |
157 | inb_p(WDT_DC); /* Disable watchdog */ | 166 | inb_p(WDT_DC); /* Disable watchdog */ |
158 | wdt_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ | 167 | wdt_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: |
159 | wdt_ctr_load(1,wd_heartbeat); /* Heartbeat */ | 168 | Rate Generator */ |
169 | wdt_ctr_load(1, wd_heartbeat); /* Heartbeat */ | ||
160 | outb_p(0, WDT_DC); /* Enable watchdog */ | 170 | outb_p(0, WDT_DC); /* Enable watchdog */ |
161 | spin_unlock_irqrestore(&wdt_lock, flags); | 171 | spin_unlock_irqrestore(&wdt_lock, flags); |
162 | return 0; | 172 | return 0; |
@@ -166,13 +176,14 @@ static int wdt_ping(void) | |||
166 | * wdt_set_heartbeat: | 176 | * wdt_set_heartbeat: |
167 | * @t: the new heartbeat value that needs to be set. | 177 | * @t: the new heartbeat value that needs to be set. |
168 | * | 178 | * |
169 | * Set a new heartbeat value for the watchdog device. If the heartbeat value is | 179 | * Set a new heartbeat value for the watchdog device. If the heartbeat |
170 | * incorrect we keep the old value and return -EINVAL. If successfull we | 180 | * value is incorrect we keep the old value and return -EINVAL. If |
171 | * return 0. | 181 | * successful we return 0. |
172 | */ | 182 | */ |
183 | |||
173 | static int wdt_set_heartbeat(int t) | 184 | static int wdt_set_heartbeat(int t) |
174 | { | 185 | { |
175 | if ((t < 1) || (t > 65535)) | 186 | if (t < 1 || t > 65535) |
176 | return -EINVAL; | 187 | return -EINVAL; |
177 | 188 | ||
178 | heartbeat = t; | 189 | heartbeat = t; |
@@ -200,7 +211,7 @@ static int wdt_get_status(int *status) | |||
200 | new_status = inb_p(WDT_SR); | 211 | new_status = inb_p(WDT_SR); |
201 | spin_unlock_irqrestore(&wdt_lock, flags); | 212 | spin_unlock_irqrestore(&wdt_lock, flags); |
202 | 213 | ||
203 | *status=0; | 214 | *status = 0; |
204 | if (new_status & WDC_SR_ISOI0) | 215 | if (new_status & WDC_SR_ISOI0) |
205 | *status |= WDIOF_EXTERN1; | 216 | *status |= WDIOF_EXTERN1; |
206 | if (new_status & WDC_SR_ISII1) | 217 | if (new_status & WDC_SR_ISII1) |
@@ -266,7 +277,7 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id) | |||
266 | 277 | ||
267 | #ifdef CONFIG_WDT_501 | 278 | #ifdef CONFIG_WDT_501 |
268 | if (!(status & WDC_SR_TGOOD)) | 279 | if (!(status & WDC_SR_TGOOD)) |
269 | printk(KERN_CRIT "Overheat alarm.(%d)\n",inb_p(WDT_RT)); | 280 | printk(KERN_CRIT "Overheat alarm.(%d)\n", inb_p(WDT_RT)); |
270 | if (!(status & WDC_SR_PSUOVER)) | 281 | if (!(status & WDC_SR_PSUOVER)) |
271 | printk(KERN_CRIT "PSU over voltage.\n"); | 282 | printk(KERN_CRIT "PSU over voltage.\n"); |
272 | if (!(status & WDC_SR_PSUUNDR)) | 283 | if (!(status & WDC_SR_PSUUNDR)) |
@@ -304,9 +315,10 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id) | |||
304 | * write of data will do, as we we don't define content meaning. | 315 | * write of data will do, as we we don't define content meaning. |
305 | */ | 316 | */ |
306 | 317 | ||
307 | static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 318 | static ssize_t wdt_write(struct file *file, const char __user *buf, |
319 | size_t count, loff_t *ppos) | ||
308 | { | 320 | { |
309 | if(count) { | 321 | if (count) { |
310 | if (!nowayout) { | 322 | if (!nowayout) { |
311 | size_t i; | 323 | size_t i; |
312 | 324 | ||
@@ -328,7 +340,6 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count | |||
328 | 340 | ||
329 | /** | 341 | /** |
330 | * wdt_ioctl: | 342 | * wdt_ioctl: |
331 | * @inode: inode of the device | ||
332 | * @file: file handle to the device | 343 | * @file: file handle to the device |
333 | * @cmd: watchdog command | 344 | * @cmd: watchdog command |
334 | * @arg: argument pointer | 345 | * @arg: argument pointer |
@@ -338,8 +349,7 @@ static ssize_t wdt_write(struct file *file, const char __user *buf, size_t count | |||
338 | * querying capabilities and current status. | 349 | * querying capabilities and current status. |
339 | */ | 350 | */ |
340 | 351 | ||
341 | static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 352 | static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
342 | unsigned long arg) | ||
343 | { | 353 | { |
344 | void __user *argp = (void __user *)arg; | 354 | void __user *argp = (void __user *)arg; |
345 | int __user *p = argp; | 355 | int __user *p = argp; |
@@ -362,32 +372,28 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
362 | ident.options |= WDIOF_FANFAULT; | 372 | ident.options |= WDIOF_FANFAULT; |
363 | #endif /* CONFIG_WDT_501 */ | 373 | #endif /* CONFIG_WDT_501 */ |
364 | 374 | ||
365 | switch(cmd) | 375 | switch (cmd) { |
366 | { | 376 | default: |
367 | default: | 377 | return -ENOTTY; |
368 | return -ENOTTY; | 378 | case WDIOC_GETSUPPORT: |
369 | case WDIOC_GETSUPPORT: | 379 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
370 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 380 | case WDIOC_GETSTATUS: |
371 | 381 | wdt_get_status(&status); | |
372 | case WDIOC_GETSTATUS: | 382 | return put_user(status, p); |
373 | wdt_get_status(&status); | 383 | case WDIOC_GETBOOTSTATUS: |
374 | return put_user(status, p); | 384 | return put_user(0, p); |
375 | case WDIOC_GETBOOTSTATUS: | 385 | case WDIOC_KEEPALIVE: |
376 | return put_user(0, p); | 386 | wdt_ping(); |
377 | case WDIOC_KEEPALIVE: | 387 | return 0; |
378 | wdt_ping(); | 388 | case WDIOC_SETTIMEOUT: |
379 | return 0; | 389 | if (get_user(new_heartbeat, p)) |
380 | case WDIOC_SETTIMEOUT: | 390 | return -EFAULT; |
381 | if (get_user(new_heartbeat, p)) | 391 | if (wdt_set_heartbeat(new_heartbeat)) |
382 | return -EFAULT; | 392 | return -EINVAL; |
383 | 393 | wdt_ping(); | |
384 | if (wdt_set_heartbeat(new_heartbeat)) | 394 | /* Fall */ |
385 | return -EINVAL; | 395 | case WDIOC_GETTIMEOUT: |
386 | 396 | return put_user(heartbeat, p); | |
387 | wdt_ping(); | ||
388 | /* Fall */ | ||
389 | case WDIOC_GETTIMEOUT: | ||
390 | return put_user(heartbeat, p); | ||
391 | } | 397 | } |
392 | } | 398 | } |
393 | 399 | ||
@@ -405,7 +411,7 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
405 | 411 | ||
406 | static int wdt_open(struct inode *inode, struct file *file) | 412 | static int wdt_open(struct inode *inode, struct file *file) |
407 | { | 413 | { |
408 | if(test_and_set_bit(0, &wdt_is_open)) | 414 | if (test_and_set_bit(0, &wdt_is_open)) |
409 | return -EBUSY; | 415 | return -EBUSY; |
410 | /* | 416 | /* |
411 | * Activate | 417 | * Activate |
@@ -432,7 +438,8 @@ static int wdt_release(struct inode *inode, struct file *file) | |||
432 | wdt_stop(); | 438 | wdt_stop(); |
433 | clear_bit(0, &wdt_is_open); | 439 | clear_bit(0, &wdt_is_open); |
434 | } else { | 440 | } else { |
435 | printk(KERN_CRIT "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); | 441 | printk(KERN_CRIT |
442 | "wdt: WDT device closed unexpectedly. WDT will not stop!\n"); | ||
436 | wdt_ping(); | 443 | wdt_ping(); |
437 | } | 444 | } |
438 | expect_close = 0; | 445 | expect_close = 0; |
@@ -451,14 +458,15 @@ static int wdt_release(struct inode *inode, struct file *file) | |||
451 | * farenheit. It was designed by an imperial measurement luddite. | 458 | * farenheit. It was designed by an imperial measurement luddite. |
452 | */ | 459 | */ |
453 | 460 | ||
454 | static ssize_t wdt_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) | 461 | static ssize_t wdt_temp_read(struct file *file, char __user *buf, |
462 | size_t count, loff_t *ptr) | ||
455 | { | 463 | { |
456 | int temperature; | 464 | int temperature; |
457 | 465 | ||
458 | if (wdt_get_temperature(&temperature)) | 466 | if (wdt_get_temperature(&temperature)) |
459 | return -EFAULT; | 467 | return -EFAULT; |
460 | 468 | ||
461 | if (copy_to_user (buf, &temperature, 1)) | 469 | if (copy_to_user(buf, &temperature, 1)) |
462 | return -EFAULT; | 470 | return -EFAULT; |
463 | 471 | ||
464 | return 1; | 472 | return 1; |
@@ -506,10 +514,8 @@ static int wdt_temp_release(struct inode *inode, struct file *file) | |||
506 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, | 514 | static int wdt_notify_sys(struct notifier_block *this, unsigned long code, |
507 | void *unused) | 515 | void *unused) |
508 | { | 516 | { |
509 | if(code==SYS_DOWN || code==SYS_HALT) { | 517 | if (code == SYS_DOWN || code == SYS_HALT) |
510 | /* Turn the card off */ | ||
511 | wdt_stop(); | 518 | wdt_stop(); |
512 | } | ||
513 | return NOTIFY_DONE; | 519 | return NOTIFY_DONE; |
514 | } | 520 | } |
515 | 521 | ||
@@ -522,7 +528,7 @@ static const struct file_operations wdt_fops = { | |||
522 | .owner = THIS_MODULE, | 528 | .owner = THIS_MODULE, |
523 | .llseek = no_llseek, | 529 | .llseek = no_llseek, |
524 | .write = wdt_write, | 530 | .write = wdt_write, |
525 | .ioctl = wdt_ioctl, | 531 | .unlocked_ioctl = wdt_ioctl, |
526 | .open = wdt_open, | 532 | .open = wdt_open, |
527 | .release = wdt_release, | 533 | .release = wdt_release, |
528 | }; | 534 | }; |
@@ -576,7 +582,7 @@ static void __exit wdt_exit(void) | |||
576 | #endif /* CONFIG_WDT_501 */ | 582 | #endif /* CONFIG_WDT_501 */ |
577 | unregister_reboot_notifier(&wdt_notifier); | 583 | unregister_reboot_notifier(&wdt_notifier); |
578 | free_irq(irq, NULL); | 584 | free_irq(irq, NULL); |
579 | release_region(io,8); | 585 | release_region(io, 8); |
580 | } | 586 | } |
581 | 587 | ||
582 | /** | 588 | /** |
@@ -591,44 +597,49 @@ static int __init wdt_init(void) | |||
591 | { | 597 | { |
592 | int ret; | 598 | int ret; |
593 | 599 | ||
594 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 600 | /* Check that the heartbeat value is within it's range; |
601 | if not reset to the default */ | ||
595 | if (wdt_set_heartbeat(heartbeat)) { | 602 | if (wdt_set_heartbeat(heartbeat)) { |
596 | wdt_set_heartbeat(WD_TIMO); | 603 | wdt_set_heartbeat(WD_TIMO); |
597 | printk(KERN_INFO "wdt: heartbeat value must be 0<heartbeat<65536, using %d\n", | 604 | printk(KERN_INFO "wdt: heartbeat value must be 0 < heartbeat < 65536, using %d\n", |
598 | WD_TIMO); | 605 | WD_TIMO); |
599 | } | 606 | } |
600 | 607 | ||
601 | if (!request_region(io, 8, "wdt501p")) { | 608 | if (!request_region(io, 8, "wdt501p")) { |
602 | printk(KERN_ERR "wdt: I/O address 0x%04x already in use\n", io); | 609 | printk(KERN_ERR |
610 | "wdt: I/O address 0x%04x already in use\n", io); | ||
603 | ret = -EBUSY; | 611 | ret = -EBUSY; |
604 | goto out; | 612 | goto out; |
605 | } | 613 | } |
606 | 614 | ||
607 | ret = request_irq(irq, wdt_interrupt, IRQF_DISABLED, "wdt501p", NULL); | 615 | ret = request_irq(irq, wdt_interrupt, IRQF_DISABLED, "wdt501p", NULL); |
608 | if(ret) { | 616 | if (ret) { |
609 | printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq); | 617 | printk(KERN_ERR "wdt: IRQ %d is not free.\n", irq); |
610 | goto outreg; | 618 | goto outreg; |
611 | } | 619 | } |
612 | 620 | ||
613 | ret = register_reboot_notifier(&wdt_notifier); | 621 | ret = register_reboot_notifier(&wdt_notifier); |
614 | if(ret) { | 622 | if (ret) { |
615 | printk(KERN_ERR "wdt: cannot register reboot notifier (err=%d)\n", ret); | 623 | printk(KERN_ERR |
624 | "wdt: cannot register reboot notifier (err=%d)\n", ret); | ||
616 | goto outirq; | 625 | goto outirq; |
617 | } | 626 | } |
618 | 627 | ||
619 | #ifdef CONFIG_WDT_501 | 628 | #ifdef CONFIG_WDT_501 |
620 | ret = misc_register(&temp_miscdev); | 629 | ret = misc_register(&temp_miscdev); |
621 | if (ret) { | 630 | if (ret) { |
622 | printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", | 631 | printk(KERN_ERR |
623 | TEMP_MINOR, ret); | 632 | "wdt: cannot register miscdev on minor=%d (err=%d)\n", |
633 | TEMP_MINOR, ret); | ||
624 | goto outrbt; | 634 | goto outrbt; |
625 | } | 635 | } |
626 | #endif /* CONFIG_WDT_501 */ | 636 | #endif /* CONFIG_WDT_501 */ |
627 | 637 | ||
628 | ret = misc_register(&wdt_miscdev); | 638 | ret = misc_register(&wdt_miscdev); |
629 | if (ret) { | 639 | if (ret) { |
630 | printk(KERN_ERR "wdt: cannot register miscdev on minor=%d (err=%d)\n", | 640 | printk(KERN_ERR |
631 | WATCHDOG_MINOR, ret); | 641 | "wdt: cannot register miscdev on minor=%d (err=%d)\n", |
642 | WATCHDOG_MINOR, ret); | ||
632 | goto outmisc; | 643 | goto outmisc; |
633 | } | 644 | } |
634 | 645 | ||
@@ -636,7 +647,8 @@ static int __init wdt_init(void) | |||
636 | printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n", | 647 | printk(KERN_INFO "WDT500/501-P driver 0.10 at 0x%04x (Interrupt %d). heartbeat=%d sec (nowayout=%d)\n", |
637 | io, irq, heartbeat, nowayout); | 648 | io, irq, heartbeat, nowayout); |
638 | #ifdef CONFIG_WDT_501 | 649 | #ifdef CONFIG_WDT_501 |
639 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); | 650 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", |
651 | (tachometer ? "Enabled" : "Disabled")); | ||
640 | #endif /* CONFIG_WDT_501 */ | 652 | #endif /* CONFIG_WDT_501 */ |
641 | 653 | ||
642 | out: | 654 | out: |
@@ -651,7 +663,7 @@ outrbt: | |||
651 | outirq: | 663 | outirq: |
652 | free_irq(irq, NULL); | 664 | free_irq(irq, NULL); |
653 | outreg: | 665 | outreg: |
654 | release_region(io,8); | 666 | release_region(io, 8); |
655 | goto out; | 667 | goto out; |
656 | } | 668 | } |
657 | 669 | ||
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index 1355608683e..5d922fd6eaf 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c | |||
@@ -29,9 +29,11 @@ | |||
29 | * JP Nollmann : Added support for PCI wdt501p | 29 | * JP Nollmann : Added support for PCI wdt501p |
30 | * Alan Cox : Split ISA and PCI cards into two drivers | 30 | * Alan Cox : Split ISA and PCI cards into two drivers |
31 | * Jeff Garzik : PCI cleanups | 31 | * Jeff Garzik : PCI cleanups |
32 | * Tigran Aivazian : Restructured wdtpci_init_one() to handle failures | 32 | * Tigran Aivazian : Restructured wdtpci_init_one() to handle |
33 | * failures | ||
33 | * Joel Becker : Added WDIOC_GET/SETTIMEOUT | 34 | * Joel Becker : Added WDIOC_GET/SETTIMEOUT |
34 | * Zwane Mwaikambo : Magic char closing, locking changes, cleanups | 35 | * Zwane Mwaikambo : Magic char closing, locking changes, |
36 | * cleanups | ||
35 | * Matt Domsch : nowayout module option | 37 | * Matt Domsch : nowayout module option |
36 | */ | 38 | */ |
37 | 39 | ||
@@ -42,14 +44,15 @@ | |||
42 | #include <linux/miscdevice.h> | 44 | #include <linux/miscdevice.h> |
43 | #include <linux/watchdog.h> | 45 | #include <linux/watchdog.h> |
44 | #include <linux/ioport.h> | 46 | #include <linux/ioport.h> |
47 | #include <linux/delay.h> | ||
45 | #include <linux/notifier.h> | 48 | #include <linux/notifier.h> |
46 | #include <linux/reboot.h> | 49 | #include <linux/reboot.h> |
47 | #include <linux/init.h> | 50 | #include <linux/init.h> |
48 | #include <linux/fs.h> | 51 | #include <linux/fs.h> |
49 | #include <linux/pci.h> | 52 | #include <linux/pci.h> |
53 | #include <linux/io.h> | ||
54 | #include <linux/uaccess.h> | ||
50 | 55 | ||
51 | #include <asm/io.h> | ||
52 | #include <asm/uaccess.h> | ||
53 | #include <asm/system.h> | 56 | #include <asm/system.h> |
54 | 57 | ||
55 | #define WDT_IS_PCI | 58 | #define WDT_IS_PCI |
@@ -73,7 +76,7 @@ | |||
73 | /* We can only use 1 card due to the /dev/watchdog restriction */ | 76 | /* We can only use 1 card due to the /dev/watchdog restriction */ |
74 | static int dev_count; | 77 | static int dev_count; |
75 | 78 | ||
76 | static struct semaphore open_sem; | 79 | static unsigned long open_lock; |
77 | static DEFINE_SPINLOCK(wdtpci_lock); | 80 | static DEFINE_SPINLOCK(wdtpci_lock); |
78 | static char expect_close; | 81 | static char expect_close; |
79 | 82 | ||
@@ -86,18 +89,23 @@ static int irq; | |||
86 | static int heartbeat = WD_TIMO; | 89 | static int heartbeat = WD_TIMO; |
87 | static int wd_heartbeat; | 90 | static int wd_heartbeat; |
88 | module_param(heartbeat, int, 0); | 91 | module_param(heartbeat, int, 0); |
89 | MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" __MODULE_STRING(WD_TIMO) ")"); | 92 | MODULE_PARM_DESC(heartbeat, |
93 | "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" | ||
94 | __MODULE_STRING(WD_TIMO) ")"); | ||
90 | 95 | ||
91 | static int nowayout = WATCHDOG_NOWAYOUT; | 96 | static int nowayout = WATCHDOG_NOWAYOUT; |
92 | module_param(nowayout, int, 0); | 97 | module_param(nowayout, int, 0); |
93 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 98 | MODULE_PARM_DESC(nowayout, |
99 | "Watchdog cannot be stopped once started (default=" | ||
100 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
94 | 101 | ||
95 | #ifdef CONFIG_WDT_501_PCI | 102 | #ifdef CONFIG_WDT_501_PCI |
96 | /* Support for the Fan Tachometer on the PCI-WDT501 */ | 103 | /* Support for the Fan Tachometer on the PCI-WDT501 */ |
97 | static int tachometer; | 104 | static int tachometer; |
98 | 105 | ||
99 | module_param(tachometer, int, 0); | 106 | module_param(tachometer, int, 0); |
100 | MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); | 107 | MODULE_PARM_DESC(tachometer, |
108 | "PCI-WDT501 Fan Tachometer support (0=disable, default=0)"); | ||
101 | #endif /* CONFIG_WDT_501_PCI */ | 109 | #endif /* CONFIG_WDT_501_PCI */ |
102 | 110 | ||
103 | /* | 111 | /* |
@@ -106,16 +114,19 @@ MODULE_PARM_DESC(tachometer, "PCI-WDT501 Fan Tachometer support (0=disable, defa | |||
106 | 114 | ||
107 | static void wdtpci_ctr_mode(int ctr, int mode) | 115 | static void wdtpci_ctr_mode(int ctr, int mode) |
108 | { | 116 | { |
109 | ctr<<=6; | 117 | ctr <<= 6; |
110 | ctr|=0x30; | 118 | ctr |= 0x30; |
111 | ctr|=(mode<<1); | 119 | ctr |= (mode << 1); |
112 | outb_p(ctr, WDT_CR); | 120 | outb(ctr, WDT_CR); |
121 | udelay(8); | ||
113 | } | 122 | } |
114 | 123 | ||
115 | static void wdtpci_ctr_load(int ctr, int val) | 124 | static void wdtpci_ctr_load(int ctr, int val) |
116 | { | 125 | { |
117 | outb_p(val&0xFF, WDT_COUNT0+ctr); | 126 | outb(val & 0xFF, WDT_COUNT0 + ctr); |
118 | outb_p(val>>8, WDT_COUNT0+ctr); | 127 | udelay(8); |
128 | outb(val >> 8, WDT_COUNT0 + ctr); | ||
129 | udelay(8); | ||
119 | } | 130 | } |
120 | 131 | ||
121 | /** | 132 | /** |
@@ -134,23 +145,35 @@ static int wdtpci_start(void) | |||
134 | * "pet" the watchdog, as Access says. | 145 | * "pet" the watchdog, as Access says. |
135 | * This resets the clock outputs. | 146 | * This resets the clock outputs. |
136 | */ | 147 | */ |
137 | inb_p(WDT_DC); /* Disable watchdog */ | 148 | inb(WDT_DC); /* Disable watchdog */ |
138 | wdtpci_ctr_mode(2,0); /* Program CTR2 for Mode 0: Pulse on Terminal Count */ | 149 | udelay(8); |
139 | outb_p(0, WDT_DC); /* Enable watchdog */ | 150 | wdtpci_ctr_mode(2, 0); /* Program CTR2 for Mode 0: |
140 | 151 | Pulse on Terminal Count */ | |
141 | inb_p(WDT_DC); /* Disable watchdog */ | 152 | outb(0, WDT_DC); /* Enable watchdog */ |
142 | outb_p(0, WDT_CLOCK); /* 2.0833MHz clock */ | 153 | udelay(8); |
143 | inb_p(WDT_BUZZER); /* disable */ | 154 | inb(WDT_DC); /* Disable watchdog */ |
144 | inb_p(WDT_OPTONOTRST); /* disable */ | 155 | udelay(8); |
145 | inb_p(WDT_OPTORST); /* disable */ | 156 | outb(0, WDT_CLOCK); /* 2.0833MHz clock */ |
146 | inb_p(WDT_PROGOUT); /* disable */ | 157 | udelay(8); |
147 | wdtpci_ctr_mode(0,3); /* Program CTR0 for Mode 3: Square Wave Generator */ | 158 | inb(WDT_BUZZER); /* disable */ |
148 | wdtpci_ctr_mode(1,2); /* Program CTR1 for Mode 2: Rate Generator */ | 159 | udelay(8); |
149 | wdtpci_ctr_mode(2,1); /* Program CTR2 for Mode 1: Retriggerable One-Shot */ | 160 | inb(WDT_OPTONOTRST); /* disable */ |
150 | wdtpci_ctr_load(0,20833); /* count at 100Hz */ | 161 | udelay(8); |
151 | wdtpci_ctr_load(1,wd_heartbeat);/* Heartbeat */ | 162 | inb(WDT_OPTORST); /* disable */ |
163 | udelay(8); | ||
164 | inb(WDT_PROGOUT); /* disable */ | ||
165 | udelay(8); | ||
166 | wdtpci_ctr_mode(0, 3); /* Program CTR0 for Mode 3: | ||
167 | Square Wave Generator */ | ||
168 | wdtpci_ctr_mode(1, 2); /* Program CTR1 for Mode 2: | ||
169 | Rate Generator */ | ||
170 | wdtpci_ctr_mode(2, 1); /* Program CTR2 for Mode 1: | ||
171 | Retriggerable One-Shot */ | ||
172 | wdtpci_ctr_load(0, 20833); /* count at 100Hz */ | ||
173 | wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ | ||
152 | /* DO NOT LOAD CTR2 on PCI card! -- JPN */ | 174 | /* DO NOT LOAD CTR2 on PCI card! -- JPN */ |
153 | outb_p(0, WDT_DC); /* Enable watchdog */ | 175 | outb(0, WDT_DC); /* Enable watchdog */ |
176 | udelay(8); | ||
154 | 177 | ||
155 | spin_unlock_irqrestore(&wdtpci_lock, flags); | 178 | spin_unlock_irqrestore(&wdtpci_lock, flags); |
156 | return 0; | 179 | return 0; |
@@ -162,14 +185,15 @@ static int wdtpci_start(void) | |||
162 | * Stop the watchdog driver. | 185 | * Stop the watchdog driver. |
163 | */ | 186 | */ |
164 | 187 | ||
165 | static int wdtpci_stop (void) | 188 | static int wdtpci_stop(void) |
166 | { | 189 | { |
167 | unsigned long flags; | 190 | unsigned long flags; |
168 | 191 | ||
169 | /* Turn the card off */ | 192 | /* Turn the card off */ |
170 | spin_lock_irqsave(&wdtpci_lock, flags); | 193 | spin_lock_irqsave(&wdtpci_lock, flags); |
171 | inb_p(WDT_DC); /* Disable watchdog */ | 194 | inb(WDT_DC); /* Disable watchdog */ |
172 | wdtpci_ctr_load(2,0); /* 0 length reset pulses now */ | 195 | udelay(8); |
196 | wdtpci_ctr_load(2, 0); /* 0 length reset pulses now */ | ||
173 | spin_unlock_irqrestore(&wdtpci_lock, flags); | 197 | spin_unlock_irqrestore(&wdtpci_lock, flags); |
174 | return 0; | 198 | return 0; |
175 | } | 199 | } |
@@ -177,20 +201,23 @@ static int wdtpci_stop (void) | |||
177 | /** | 201 | /** |
178 | * wdtpci_ping: | 202 | * wdtpci_ping: |
179 | * | 203 | * |
180 | * Reload counter one with the watchdog heartbeat. We don't bother reloading | 204 | * Reload counter one with the watchdog heartbeat. We don't bother |
181 | * the cascade counter. | 205 | * reloading the cascade counter. |
182 | */ | 206 | */ |
183 | 207 | ||
184 | static int wdtpci_ping(void) | 208 | static int wdtpci_ping(void) |
185 | { | 209 | { |
186 | unsigned long flags; | 210 | unsigned long flags; |
187 | 211 | ||
188 | /* Write a watchdog value */ | ||
189 | spin_lock_irqsave(&wdtpci_lock, flags); | 212 | spin_lock_irqsave(&wdtpci_lock, flags); |
190 | inb_p(WDT_DC); /* Disable watchdog */ | 213 | /* Write a watchdog value */ |
191 | wdtpci_ctr_mode(1,2); /* Re-Program CTR1 for Mode 2: Rate Generator */ | 214 | inb(WDT_DC); /* Disable watchdog */ |
192 | wdtpci_ctr_load(1,wd_heartbeat);/* Heartbeat */ | 215 | udelay(8); |
193 | outb_p(0, WDT_DC); /* Enable watchdog */ | 216 | wdtpci_ctr_mode(1, 2); /* Re-Program CTR1 for Mode 2: |
217 | Rate Generator */ | ||
218 | wdtpci_ctr_load(1, wd_heartbeat);/* Heartbeat */ | ||
219 | outb(0, WDT_DC); /* Enable watchdog */ | ||
220 | udelay(8); | ||
194 | spin_unlock_irqrestore(&wdtpci_lock, flags); | 221 | spin_unlock_irqrestore(&wdtpci_lock, flags); |
195 | return 0; | 222 | return 0; |
196 | } | 223 | } |
@@ -199,14 +226,14 @@ static int wdtpci_ping(void) | |||
199 | * wdtpci_set_heartbeat: | 226 | * wdtpci_set_heartbeat: |
200 | * @t: the new heartbeat value that needs to be set. | 227 | * @t: the new heartbeat value that needs to be set. |
201 | * | 228 | * |
202 | * Set a new heartbeat value for the watchdog device. If the heartbeat value is | 229 | * Set a new heartbeat value for the watchdog device. If the heartbeat |
203 | * incorrect we keep the old value and return -EINVAL. If successfull we | 230 | * value is incorrect we keep the old value and return -EINVAL. |
204 | * return 0. | 231 | * If successful we return 0. |
205 | */ | 232 | */ |
206 | static int wdtpci_set_heartbeat(int t) | 233 | static int wdtpci_set_heartbeat(int t) |
207 | { | 234 | { |
208 | /* Arbitrary, can't find the card's limits */ | 235 | /* Arbitrary, can't find the card's limits */ |
209 | if ((t < 1) || (t > 65535)) | 236 | if (t < 1 || t > 65535) |
210 | return -EINVAL; | 237 | return -EINVAL; |
211 | 238 | ||
212 | heartbeat = t; | 239 | heartbeat = t; |
@@ -227,9 +254,14 @@ static int wdtpci_set_heartbeat(int t) | |||
227 | 254 | ||
228 | static int wdtpci_get_status(int *status) | 255 | static int wdtpci_get_status(int *status) |
229 | { | 256 | { |
230 | unsigned char new_status=inb_p(WDT_SR); | 257 | unsigned char new_status; |
258 | unsigned long flags; | ||
259 | |||
260 | spin_lock_irqsave(&wdtpci_lock, flags); | ||
261 | new_status = inb(WDT_SR); | ||
262 | spin_unlock_irqrestore(&wdtpci_lock, flags); | ||
231 | 263 | ||
232 | *status=0; | 264 | *status = 0; |
233 | if (new_status & WDC_SR_ISOI0) | 265 | if (new_status & WDC_SR_ISOI0) |
234 | *status |= WDIOF_EXTERN1; | 266 | *status |= WDIOF_EXTERN1; |
235 | if (new_status & WDC_SR_ISII1) | 267 | if (new_status & WDC_SR_ISII1) |
@@ -259,8 +291,12 @@ static int wdtpci_get_status(int *status) | |||
259 | 291 | ||
260 | static int wdtpci_get_temperature(int *temperature) | 292 | static int wdtpci_get_temperature(int *temperature) |
261 | { | 293 | { |
262 | unsigned short c=inb_p(WDT_RT); | 294 | unsigned short c; |
263 | 295 | unsigned long flags; | |
296 | spin_lock_irqsave(&wdtpci_lock, flags); | ||
297 | c = inb(WDT_RT); | ||
298 | udelay(8); | ||
299 | spin_unlock_irqrestore(&wdtpci_lock, flags); | ||
264 | *temperature = (c * 11 / 15) + 7; | 300 | *temperature = (c * 11 / 15) + 7; |
265 | return 0; | 301 | return 0; |
266 | } | 302 | } |
@@ -282,17 +318,25 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) | |||
282 | * Read the status register see what is up and | 318 | * Read the status register see what is up and |
283 | * then printk it. | 319 | * then printk it. |
284 | */ | 320 | */ |
285 | unsigned char status=inb_p(WDT_SR); | 321 | unsigned char status; |
322 | |||
323 | spin_lock(&wdtpci_lock); | ||
324 | |||
325 | status = inb(WDT_SR); | ||
326 | udelay(8); | ||
286 | 327 | ||
287 | printk(KERN_CRIT PFX "status %d\n", status); | 328 | printk(KERN_CRIT PFX "status %d\n", status); |
288 | 329 | ||
289 | #ifdef CONFIG_WDT_501_PCI | 330 | #ifdef CONFIG_WDT_501_PCI |
290 | if (!(status & WDC_SR_TGOOD)) | 331 | if (!(status & WDC_SR_TGOOD)) { |
291 | printk(KERN_CRIT PFX "Overheat alarm.(%d)\n",inb_p(WDT_RT)); | 332 | u8 alarm = inb(WDT_RT); |
333 | printk(KERN_CRIT PFX "Overheat alarm.(%d)\n", alarm); | ||
334 | udelay(8); | ||
335 | } | ||
292 | if (!(status & WDC_SR_PSUOVER)) | 336 | if (!(status & WDC_SR_PSUOVER)) |
293 | printk(KERN_CRIT PFX "PSU over voltage.\n"); | 337 | printk(KERN_CRIT PFX "PSU over voltage.\n"); |
294 | if (!(status & WDC_SR_PSUUNDR)) | 338 | if (!(status & WDC_SR_PSUUNDR)) |
295 | printk(KERN_CRIT PFX "PSU under voltage.\n"); | 339 | printk(KERN_CRIT PFX "PSU under voltage.\n"); |
296 | if (tachometer) { | 340 | if (tachometer) { |
297 | if (!(status & WDC_SR_FANGOOD)) | 341 | if (!(status & WDC_SR_FANGOOD)) |
298 | printk(KERN_CRIT PFX "Possible fan fault.\n"); | 342 | printk(KERN_CRIT PFX "Possible fan fault.\n"); |
@@ -310,6 +354,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) | |||
310 | printk(KERN_CRIT PFX "Reset in 5ms.\n"); | 354 | printk(KERN_CRIT PFX "Reset in 5ms.\n"); |
311 | #endif | 355 | #endif |
312 | } | 356 | } |
357 | spin_unlock(&wdtpci_lock); | ||
313 | return IRQ_HANDLED; | 358 | return IRQ_HANDLED; |
314 | } | 359 | } |
315 | 360 | ||
@@ -325,7 +370,8 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) | |||
325 | * write of data will do, as we we don't define content meaning. | 370 | * write of data will do, as we we don't define content meaning. |
326 | */ | 371 | */ |
327 | 372 | ||
328 | static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 373 | static ssize_t wdtpci_write(struct file *file, const char __user *buf, |
374 | size_t count, loff_t *ppos) | ||
329 | { | 375 | { |
330 | if (count) { | 376 | if (count) { |
331 | if (!nowayout) { | 377 | if (!nowayout) { |
@@ -335,7 +381,7 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co | |||
335 | 381 | ||
336 | for (i = 0; i != count; i++) { | 382 | for (i = 0; i != count; i++) { |
337 | char c; | 383 | char c; |
338 | if(get_user(c, buf+i)) | 384 | if (get_user(c, buf+i)) |
339 | return -EFAULT; | 385 | return -EFAULT; |
340 | if (c == 'V') | 386 | if (c == 'V') |
341 | expect_close = 42; | 387 | expect_close = 42; |
@@ -343,13 +389,11 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co | |||
343 | } | 389 | } |
344 | wdtpci_ping(); | 390 | wdtpci_ping(); |
345 | } | 391 | } |
346 | |||
347 | return count; | 392 | return count; |
348 | } | 393 | } |
349 | 394 | ||
350 | /** | 395 | /** |
351 | * wdtpci_ioctl: | 396 | * wdtpci_ioctl: |
352 | * @inode: inode of the device | ||
353 | * @file: file handle to the device | 397 | * @file: file handle to the device |
354 | * @cmd: watchdog command | 398 | * @cmd: watchdog command |
355 | * @arg: argument pointer | 399 | * @arg: argument pointer |
@@ -359,8 +403,8 @@ static ssize_t wdtpci_write(struct file *file, const char __user *buf, size_t co | |||
359 | * querying capabilities and current status. | 403 | * querying capabilities and current status. |
360 | */ | 404 | */ |
361 | 405 | ||
362 | static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 406 | static long wdtpci_ioctl(struct file *file, unsigned int cmd, |
363 | unsigned long arg) | 407 | unsigned long arg) |
364 | { | 408 | { |
365 | int new_heartbeat; | 409 | int new_heartbeat; |
366 | int status; | 410 | int status; |
@@ -383,33 +427,29 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
383 | ident.options |= WDIOF_FANFAULT; | 427 | ident.options |= WDIOF_FANFAULT; |
384 | #endif /* CONFIG_WDT_501_PCI */ | 428 | #endif /* CONFIG_WDT_501_PCI */ |
385 | 429 | ||
386 | switch(cmd) | 430 | switch (cmd) { |
387 | { | 431 | default: |
388 | default: | 432 | return -ENOTTY; |
389 | return -ENOTTY; | 433 | case WDIOC_GETSUPPORT: |
390 | case WDIOC_GETSUPPORT: | 434 | return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0; |
391 | return copy_to_user(argp, &ident, sizeof(ident))?-EFAULT:0; | 435 | case WDIOC_GETSTATUS: |
392 | 436 | wdtpci_get_status(&status); | |
393 | case WDIOC_GETSTATUS: | 437 | return put_user(status, p); |
394 | wdtpci_get_status(&status); | 438 | case WDIOC_GETBOOTSTATUS: |
395 | return put_user(status, p); | 439 | return put_user(0, p); |
396 | case WDIOC_GETBOOTSTATUS: | 440 | case WDIOC_KEEPALIVE: |
397 | return put_user(0, p); | 441 | wdtpci_ping(); |
398 | case WDIOC_KEEPALIVE: | 442 | return 0; |
399 | wdtpci_ping(); | 443 | case WDIOC_SETTIMEOUT: |
400 | return 0; | 444 | if (get_user(new_heartbeat, p)) |
401 | case WDIOC_SETTIMEOUT: | 445 | return -EFAULT; |
402 | if (get_user(new_heartbeat, p)) | 446 | if (wdtpci_set_heartbeat(new_heartbeat)) |
403 | return -EFAULT; | 447 | return -EINVAL; |
404 | 448 | wdtpci_ping(); | |
405 | if (wdtpci_set_heartbeat(new_heartbeat)) | 449 | /* Fall */ |
406 | return -EINVAL; | 450 | case WDIOC_GETTIMEOUT: |
407 | 451 | return put_user(heartbeat, p); | |
408 | wdtpci_ping(); | 452 | } |
409 | /* Fall */ | ||
410 | case WDIOC_GETTIMEOUT: | ||
411 | return put_user(heartbeat, p); | ||
412 | } | ||
413 | } | 453 | } |
414 | 454 | ||
415 | /** | 455 | /** |
@@ -426,12 +466,11 @@ static int wdtpci_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
426 | 466 | ||
427 | static int wdtpci_open(struct inode *inode, struct file *file) | 467 | static int wdtpci_open(struct inode *inode, struct file *file) |
428 | { | 468 | { |
429 | if (down_trylock(&open_sem)) | 469 | if (test_and_set_bit(0, &open_lock)) |
430 | return -EBUSY; | 470 | return -EBUSY; |
431 | 471 | ||
432 | if (nowayout) { | 472 | if (nowayout) |
433 | __module_get(THIS_MODULE); | 473 | __module_get(THIS_MODULE); |
434 | } | ||
435 | /* | 474 | /* |
436 | * Activate | 475 | * Activate |
437 | */ | 476 | */ |
@@ -460,7 +499,7 @@ static int wdtpci_release(struct inode *inode, struct file *file) | |||
460 | wdtpci_ping(); | 499 | wdtpci_ping(); |
461 | } | 500 | } |
462 | expect_close = 0; | 501 | expect_close = 0; |
463 | up(&open_sem); | 502 | clear_bit(0, &open_lock); |
464 | return 0; | 503 | return 0; |
465 | } | 504 | } |
466 | 505 | ||
@@ -476,14 +515,15 @@ static int wdtpci_release(struct inode *inode, struct file *file) | |||
476 | * fahrenheit. It was designed by an imperial measurement luddite. | 515 | * fahrenheit. It was designed by an imperial measurement luddite. |
477 | */ | 516 | */ |
478 | 517 | ||
479 | static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) | 518 | static ssize_t wdtpci_temp_read(struct file *file, char __user *buf, |
519 | size_t count, loff_t *ptr) | ||
480 | { | 520 | { |
481 | int temperature; | 521 | int temperature; |
482 | 522 | ||
483 | if (wdtpci_get_temperature(&temperature)) | 523 | if (wdtpci_get_temperature(&temperature)) |
484 | return -EFAULT; | 524 | return -EFAULT; |
485 | 525 | ||
486 | if (copy_to_user (buf, &temperature, 1)) | 526 | if (copy_to_user(buf, &temperature, 1)) |
487 | return -EFAULT; | 527 | return -EFAULT; |
488 | 528 | ||
489 | return 1; | 529 | return 1; |
@@ -529,12 +569,10 @@ static int wdtpci_temp_release(struct inode *inode, struct file *file) | |||
529 | */ | 569 | */ |
530 | 570 | ||
531 | static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, | 571 | static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code, |
532 | void *unused) | 572 | void *unused) |
533 | { | 573 | { |
534 | if (code==SYS_DOWN || code==SYS_HALT) { | 574 | if (code == SYS_DOWN || code == SYS_HALT) |
535 | /* Turn the card off */ | ||
536 | wdtpci_stop(); | 575 | wdtpci_stop(); |
537 | } | ||
538 | return NOTIFY_DONE; | 576 | return NOTIFY_DONE; |
539 | } | 577 | } |
540 | 578 | ||
@@ -547,7 +585,7 @@ static const struct file_operations wdtpci_fops = { | |||
547 | .owner = THIS_MODULE, | 585 | .owner = THIS_MODULE, |
548 | .llseek = no_llseek, | 586 | .llseek = no_llseek, |
549 | .write = wdtpci_write, | 587 | .write = wdtpci_write, |
550 | .ioctl = wdtpci_ioctl, | 588 | .unlocked_ioctl = wdtpci_ioctl, |
551 | .open = wdtpci_open, | 589 | .open = wdtpci_open, |
552 | .release = wdtpci_release, | 590 | .release = wdtpci_release, |
553 | }; | 591 | }; |
@@ -584,80 +622,85 @@ static struct notifier_block wdtpci_notifier = { | |||
584 | }; | 622 | }; |
585 | 623 | ||
586 | 624 | ||
587 | static int __devinit wdtpci_init_one (struct pci_dev *dev, | 625 | static int __devinit wdtpci_init_one(struct pci_dev *dev, |
588 | const struct pci_device_id *ent) | 626 | const struct pci_device_id *ent) |
589 | { | 627 | { |
590 | int ret = -EIO; | 628 | int ret = -EIO; |
591 | 629 | ||
592 | dev_count++; | 630 | dev_count++; |
593 | if (dev_count > 1) { | 631 | if (dev_count > 1) { |
594 | printk (KERN_ERR PFX "this driver only supports 1 device\n"); | 632 | printk(KERN_ERR PFX "This driver only supports one device\n"); |
595 | return -ENODEV; | 633 | return -ENODEV; |
596 | } | 634 | } |
597 | 635 | ||
598 | if (pci_enable_device (dev)) { | 636 | if (pci_enable_device(dev)) { |
599 | printk (KERN_ERR PFX "Not possible to enable PCI Device\n"); | 637 | printk(KERN_ERR PFX "Not possible to enable PCI Device\n"); |
600 | return -ENODEV; | 638 | return -ENODEV; |
601 | } | 639 | } |
602 | 640 | ||
603 | if (pci_resource_start (dev, 2) == 0x0000) { | 641 | if (pci_resource_start(dev, 2) == 0x0000) { |
604 | printk (KERN_ERR PFX "No I/O-Address for card detected\n"); | 642 | printk(KERN_ERR PFX "No I/O-Address for card detected\n"); |
605 | ret = -ENODEV; | 643 | ret = -ENODEV; |
606 | goto out_pci; | 644 | goto out_pci; |
607 | } | 645 | } |
608 | 646 | ||
609 | sema_init(&open_sem, 1); | ||
610 | |||
611 | irq = dev->irq; | 647 | irq = dev->irq; |
612 | io = pci_resource_start (dev, 2); | 648 | io = pci_resource_start(dev, 2); |
613 | 649 | ||
614 | if (request_region (io, 16, "wdt_pci") == NULL) { | 650 | if (request_region(io, 16, "wdt_pci") == NULL) { |
615 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", io); | 651 | printk(KERN_ERR PFX "I/O address 0x%04x already in use\n", io); |
616 | goto out_pci; | 652 | goto out_pci; |
617 | } | 653 | } |
618 | 654 | ||
619 | if (request_irq (irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED, | 655 | if (request_irq(irq, wdtpci_interrupt, IRQF_DISABLED | IRQF_SHARED, |
620 | "wdt_pci", &wdtpci_miscdev)) { | 656 | "wdt_pci", &wdtpci_miscdev)) { |
621 | printk (KERN_ERR PFX "IRQ %d is not free\n", irq); | 657 | printk(KERN_ERR PFX "IRQ %d is not free\n", irq); |
622 | goto out_reg; | 658 | goto out_reg; |
623 | } | 659 | } |
624 | 660 | ||
625 | printk ("PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", | 661 | printk(KERN_INFO |
626 | io, irq); | 662 | "PCI-WDT500/501 (PCI-WDG-CSM) driver 0.10 at 0x%04x (Interrupt %d)\n", |
663 | io, irq); | ||
627 | 664 | ||
628 | /* Check that the heartbeat value is within it's range ; if not reset to the default */ | 665 | /* Check that the heartbeat value is within its range; |
666 | if not reset to the default */ | ||
629 | if (wdtpci_set_heartbeat(heartbeat)) { | 667 | if (wdtpci_set_heartbeat(heartbeat)) { |
630 | wdtpci_set_heartbeat(WD_TIMO); | 668 | wdtpci_set_heartbeat(WD_TIMO); |
631 | printk(KERN_INFO PFX "heartbeat value must be 0<heartbeat<65536, using %d\n", | 669 | printk(KERN_INFO PFX |
632 | WD_TIMO); | 670 | "heartbeat value must be 0 < heartbeat < 65536, using %d\n", |
671 | WD_TIMO); | ||
633 | } | 672 | } |
634 | 673 | ||
635 | ret = register_reboot_notifier (&wdtpci_notifier); | 674 | ret = register_reboot_notifier(&wdtpci_notifier); |
636 | if (ret) { | 675 | if (ret) { |
637 | printk (KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret); | 676 | printk(KERN_ERR PFX |
677 | "cannot register reboot notifier (err=%d)\n", ret); | ||
638 | goto out_irq; | 678 | goto out_irq; |
639 | } | 679 | } |
640 | 680 | ||
641 | #ifdef CONFIG_WDT_501_PCI | 681 | #ifdef CONFIG_WDT_501_PCI |
642 | ret = misc_register (&temp_miscdev); | 682 | ret = misc_register(&temp_miscdev); |
643 | if (ret) { | 683 | if (ret) { |
644 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 684 | printk(KERN_ERR PFX |
645 | TEMP_MINOR, ret); | 685 | "cannot register miscdev on minor=%d (err=%d)\n", |
686 | TEMP_MINOR, ret); | ||
646 | goto out_rbt; | 687 | goto out_rbt; |
647 | } | 688 | } |
648 | #endif /* CONFIG_WDT_501_PCI */ | 689 | #endif /* CONFIG_WDT_501_PCI */ |
649 | 690 | ||
650 | ret = misc_register (&wdtpci_miscdev); | 691 | ret = misc_register(&wdtpci_miscdev); |
651 | if (ret) { | 692 | if (ret) { |
652 | printk (KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n", | 693 | printk(KERN_ERR PFX |
653 | WATCHDOG_MINOR, ret); | 694 | "cannot register miscdev on minor=%d (err=%d)\n", |
695 | WATCHDOG_MINOR, ret); | ||
654 | goto out_misc; | 696 | goto out_misc; |
655 | } | 697 | } |
656 | 698 | ||
657 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", | 699 | printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n", |
658 | heartbeat, nowayout); | 700 | heartbeat, nowayout); |
659 | #ifdef CONFIG_WDT_501_PCI | 701 | #ifdef CONFIG_WDT_501_PCI |
660 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", (tachometer ? "Enabled" : "Disabled")); | 702 | printk(KERN_INFO "wdt: Fan Tachometer is %s\n", |
703 | (tachometer ? "Enabled" : "Disabled")); | ||
661 | #endif /* CONFIG_WDT_501_PCI */ | 704 | #endif /* CONFIG_WDT_501_PCI */ |
662 | 705 | ||
663 | ret = 0; | 706 | ret = 0; |
@@ -673,14 +716,14 @@ out_rbt: | |||
673 | out_irq: | 716 | out_irq: |
674 | free_irq(irq, &wdtpci_miscdev); | 717 | free_irq(irq, &wdtpci_miscdev); |
675 | out_reg: | 718 | out_reg: |
676 | release_region (io, 16); | 719 | release_region(io, 16); |
677 | out_pci: | 720 | out_pci: |
678 | pci_disable_device(dev); | 721 | pci_disable_device(dev); |
679 | goto out; | 722 | goto out; |
680 | } | 723 | } |
681 | 724 | ||
682 | 725 | ||
683 | static void __devexit wdtpci_remove_one (struct pci_dev *pdev) | 726 | static void __devexit wdtpci_remove_one(struct pci_dev *pdev) |
684 | { | 727 | { |
685 | /* here we assume only one device will ever have | 728 | /* here we assume only one device will ever have |
686 | * been picked up and registered by probe function */ | 729 | * been picked up and registered by probe function */ |
@@ -728,7 +771,7 @@ static struct pci_driver wdtpci_driver = { | |||
728 | 771 | ||
729 | static void __exit wdtpci_cleanup(void) | 772 | static void __exit wdtpci_cleanup(void) |
730 | { | 773 | { |
731 | pci_unregister_driver (&wdtpci_driver); | 774 | pci_unregister_driver(&wdtpci_driver); |
732 | } | 775 | } |
733 | 776 | ||
734 | 777 | ||
@@ -742,7 +785,7 @@ static void __exit wdtpci_cleanup(void) | |||
742 | 785 | ||
743 | static int __init wdtpci_init(void) | 786 | static int __init wdtpci_init(void) |
744 | { | 787 | { |
745 | return pci_register_driver (&wdtpci_driver); | 788 | return pci_register_driver(&wdtpci_driver); |
746 | } | 789 | } |
747 | 790 | ||
748 | 791 | ||