diff options
| -rw-r--r-- | arch/ppc64/kernel/mf.c | 85 | ||||
| -rw-r--r-- | arch/ppc64/kernel/rtc.c | 39 | ||||
| -rw-r--r-- | arch/ppc64/kernel/time.c | 1 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 2 | ||||
| -rw-r--r-- | drivers/usb/atm/speedtch.c | 2 | ||||
| -rw-r--r-- | include/asm-ppc64/iSeries/mf.h | 1 |
6 files changed, 71 insertions, 59 deletions
diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 1bd52ece497c..5aca7e8005a8 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * mf.c | 2 | * mf.c |
| 3 | * Copyright (C) 2001 Troy D. Armstrong IBM Corporation | 3 | * Copyright (C) 2001 Troy D. Armstrong IBM Corporation |
| 4 | * Copyright (C) 2004 Stephen Rothwell IBM Corporation | 4 | * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation |
| 5 | * | 5 | * |
| 6 | * This modules exists as an interface between a Linux secondary partition | 6 | * This modules exists as an interface between a Linux secondary partition |
| 7 | * running on an iSeries and the primary partition's Virtual Service | 7 | * running on an iSeries and the primary partition's Virtual Service |
| @@ -36,10 +36,12 @@ | |||
| 36 | 36 | ||
| 37 | #include <asm/time.h> | 37 | #include <asm/time.h> |
| 38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
| 39 | #include <asm/paca.h> | ||
| 39 | #include <asm/iSeries/vio.h> | 40 | #include <asm/iSeries/vio.h> |
| 40 | #include <asm/iSeries/mf.h> | 41 | #include <asm/iSeries/mf.h> |
| 41 | #include <asm/iSeries/HvLpConfig.h> | 42 | #include <asm/iSeries/HvLpConfig.h> |
| 42 | #include <asm/iSeries/ItSpCommArea.h> | 43 | #include <asm/iSeries/ItSpCommArea.h> |
| 44 | #include <asm/iSeries/ItLpQueue.h> | ||
| 43 | 45 | ||
| 44 | /* | 46 | /* |
| 45 | * This is the structure layout for the Machine Facilites LPAR event | 47 | * This is the structure layout for the Machine Facilites LPAR event |
| @@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg) | |||
| 696 | complete(&rtc->com); | 698 | complete(&rtc->com); |
| 697 | } | 699 | } |
| 698 | 700 | ||
| 699 | int mf_get_rtc(struct rtc_time *tm) | 701 | static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm) |
| 700 | { | 702 | { |
| 701 | struct ce_msg_comp_data ce_complete; | ||
| 702 | struct rtc_time_data rtc_data; | ||
| 703 | int rc; | ||
| 704 | |||
| 705 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
| 706 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
| 707 | init_completion(&rtc_data.com); | ||
| 708 | ce_complete.handler = &get_rtc_time_complete; | ||
| 709 | ce_complete.token = &rtc_data; | ||
| 710 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
| 711 | if (rc) | ||
| 712 | return rc; | ||
| 713 | wait_for_completion(&rtc_data.com); | ||
| 714 | tm->tm_wday = 0; | 703 | tm->tm_wday = 0; |
| 715 | tm->tm_yday = 0; | 704 | tm->tm_yday = 0; |
| 716 | tm->tm_isdst = 0; | 705 | tm->tm_isdst = 0; |
| 717 | if (rtc_data.rc) { | 706 | if (rc) { |
| 718 | tm->tm_sec = 0; | 707 | tm->tm_sec = 0; |
| 719 | tm->tm_min = 0; | 708 | tm->tm_min = 0; |
| 720 | tm->tm_hour = 0; | 709 | tm->tm_hour = 0; |
| 721 | tm->tm_mday = 15; | 710 | tm->tm_mday = 15; |
| 722 | tm->tm_mon = 5; | 711 | tm->tm_mon = 5; |
| 723 | tm->tm_year = 52; | 712 | tm->tm_year = 52; |
| 724 | return rtc_data.rc; | 713 | return rc; |
| 725 | } | 714 | } |
| 726 | 715 | ||
| 727 | if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) || | 716 | if ((ce_msg[2] == 0xa9) || |
| 728 | (rtc_data.ce_msg.ce_msg[2] == 0xaf)) { | 717 | (ce_msg[2] == 0xaf)) { |
| 729 | /* TOD clock is not set */ | 718 | /* TOD clock is not set */ |
| 730 | tm->tm_sec = 1; | 719 | tm->tm_sec = 1; |
| 731 | tm->tm_min = 1; | 720 | tm->tm_min = 1; |
| @@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm) | |||
| 736 | mf_set_rtc(tm); | 725 | mf_set_rtc(tm); |
| 737 | } | 726 | } |
| 738 | { | 727 | { |
| 739 | u8 *ce_msg = rtc_data.ce_msg.ce_msg; | ||
| 740 | u8 year = ce_msg[5]; | 728 | u8 year = ce_msg[5]; |
| 741 | u8 sec = ce_msg[6]; | 729 | u8 sec = ce_msg[6]; |
| 742 | u8 min = ce_msg[7]; | 730 | u8 min = ce_msg[7]; |
| @@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm) | |||
| 765 | return 0; | 753 | return 0; |
| 766 | } | 754 | } |
| 767 | 755 | ||
| 756 | int mf_get_rtc(struct rtc_time *tm) | ||
| 757 | { | ||
| 758 | struct ce_msg_comp_data ce_complete; | ||
| 759 | struct rtc_time_data rtc_data; | ||
| 760 | int rc; | ||
| 761 | |||
| 762 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
| 763 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
| 764 | init_completion(&rtc_data.com); | ||
| 765 | ce_complete.handler = &get_rtc_time_complete; | ||
| 766 | ce_complete.token = &rtc_data; | ||
| 767 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
| 768 | if (rc) | ||
| 769 | return rc; | ||
| 770 | wait_for_completion(&rtc_data.com); | ||
| 771 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); | ||
| 772 | } | ||
| 773 | |||
| 774 | struct boot_rtc_time_data { | ||
| 775 | int busy; | ||
| 776 | struct ce_msg_data ce_msg; | ||
| 777 | int rc; | ||
| 778 | }; | ||
| 779 | |||
| 780 | static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg) | ||
| 781 | { | ||
| 782 | struct boot_rtc_time_data *rtc = token; | ||
| 783 | |||
| 784 | memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg)); | ||
| 785 | rtc->rc = 0; | ||
| 786 | rtc->busy = 0; | ||
| 787 | } | ||
| 788 | |||
| 789 | int mf_get_boot_rtc(struct rtc_time *tm) | ||
| 790 | { | ||
| 791 | struct ce_msg_comp_data ce_complete; | ||
| 792 | struct boot_rtc_time_data rtc_data; | ||
| 793 | int rc; | ||
| 794 | |||
| 795 | memset(&ce_complete, 0, sizeof(ce_complete)); | ||
| 796 | memset(&rtc_data, 0, sizeof(rtc_data)); | ||
| 797 | rtc_data.busy = 1; | ||
| 798 | ce_complete.handler = &get_boot_rtc_time_complete; | ||
| 799 | ce_complete.token = &rtc_data; | ||
| 800 | rc = signal_ce_msg_simple(0x40, &ce_complete); | ||
| 801 | if (rc) | ||
| 802 | return rc; | ||
| 803 | /* We need to poll here as we are not yet taking interrupts */ | ||
| 804 | while (rtc_data.busy) { | ||
| 805 | extern unsigned long lpevent_count; | ||
| 806 | struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; | ||
| 807 | if (lpq && ItLpQueue_isLpIntPending(lpq)) | ||
| 808 | lpevent_count += ItLpQueue_process(lpq, NULL); | ||
| 809 | } | ||
| 810 | return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); | ||
| 811 | } | ||
| 812 | |||
| 768 | int mf_set_rtc(struct rtc_time *tm) | 813 | int mf_set_rtc(struct rtc_time *tm) |
| 769 | { | 814 | { |
| 770 | char ce_time[12]; | 815 | char ce_time[12]; |
diff --git a/arch/ppc64/kernel/rtc.c b/arch/ppc64/kernel/rtc.c index 3e70b91375fc..67989055a9fe 100644 --- a/arch/ppc64/kernel/rtc.c +++ b/arch/ppc64/kernel/rtc.c | |||
| @@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm) | |||
| 292 | 292 | ||
| 293 | void iSeries_get_boot_time(struct rtc_time *tm) | 293 | void iSeries_get_boot_time(struct rtc_time *tm) |
| 294 | { | 294 | { |
| 295 | unsigned long time; | ||
| 296 | static unsigned long lastsec = 1; | ||
| 297 | |||
| 298 | u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart)); | ||
| 299 | u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1); | ||
| 300 | int year = 1970; | ||
| 301 | int year1 = ( dataWord1 >> 24 ) & 0x000000FF; | ||
| 302 | int year2 = ( dataWord1 >> 16 ) & 0x000000FF; | ||
| 303 | int sec = ( dataWord1 >> 8 ) & 0x000000FF; | ||
| 304 | int min = dataWord1 & 0x000000FF; | ||
| 305 | int hour = ( dataWord2 >> 24 ) & 0x000000FF; | ||
| 306 | int day = ( dataWord2 >> 8 ) & 0x000000FF; | ||
| 307 | int mon = dataWord2 & 0x000000FF; | ||
| 308 | |||
| 309 | if ( piranha_simulator ) | 295 | if ( piranha_simulator ) |
| 310 | return; | 296 | return; |
| 311 | 297 | ||
| 312 | BCD_TO_BIN(sec); | 298 | mf_get_boot_rtc(tm); |
| 313 | BCD_TO_BIN(min); | ||
| 314 | BCD_TO_BIN(hour); | ||
| 315 | BCD_TO_BIN(day); | ||
| 316 | BCD_TO_BIN(mon); | ||
| 317 | BCD_TO_BIN(year1); | ||
| 318 | BCD_TO_BIN(year2); | ||
| 319 | year = year1 * 100 + year2; | ||
| 320 | |||
| 321 | time = mktime(year, mon, day, hour, min, sec); | ||
| 322 | time += ( jiffies / HZ ); | ||
| 323 | |||
| 324 | /* Now THIS is a nasty hack! | ||
| 325 | * It ensures that the first two calls get different answers. | ||
| 326 | * That way the loop in init_time (time.c) will not think | ||
| 327 | * the clock is stuck. | ||
| 328 | */ | ||
| 329 | if ( lastsec ) { | ||
| 330 | time -= lastsec; | ||
| 331 | --lastsec; | ||
| 332 | } | ||
| 333 | |||
| 334 | to_tm(time, tm); | ||
| 335 | tm->tm_year -= 1900; | ||
| 336 | tm->tm_mon -= 1; | 299 | tm->tm_mon -= 1; |
| 337 | } | 300 | } |
| 338 | #endif | 301 | #endif |
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 772a465b49f9..3d54745108c7 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c | |||
| @@ -515,6 +515,7 @@ void __init time_init(void) | |||
| 515 | do_gtod.varp = &do_gtod.vars[0]; | 515 | do_gtod.varp = &do_gtod.vars[0]; |
| 516 | do_gtod.var_idx = 0; | 516 | do_gtod.var_idx = 0; |
| 517 | do_gtod.varp->tb_orig_stamp = tb_last_stamp; | 517 | do_gtod.varp->tb_orig_stamp = tb_last_stamp; |
| 518 | get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy; | ||
| 518 | do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; | 519 | do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC; |
| 519 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | 520 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; |
| 520 | do_gtod.varp->tb_to_xs = tb_to_xs; | 521 | do_gtod.varp->tb_to_xs = tb_to_xs; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 33a020faeabd..4f7ce7056228 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -1933,7 +1933,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
| 1933 | /* | 1933 | /* |
| 1934 | * check if dma is safe | 1934 | * check if dma is safe |
| 1935 | */ | 1935 | */ |
| 1936 | if ((rq->data_len & mask) || (addr & mask)) | 1936 | if ((rq->data_len & 3) || (addr & mask)) |
| 1937 | info->dma = 0; | 1937 | info->dma = 0; |
| 1938 | } | 1938 | } |
| 1939 | 1939 | ||
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 233f9229badb..2a1697bfd695 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
| @@ -386,6 +386,8 @@ static void speedtch_poll_status(struct speedtch_instance_data *instance) | |||
| 386 | if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { | 386 | if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { |
| 387 | instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; | 387 | instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; |
| 388 | printk(KERN_NOTICE "ADSL line is down\n"); | 388 | printk(KERN_NOTICE "ADSL line is down\n"); |
| 389 | /* It'll never resync again unless we ask it to... */ | ||
| 390 | speedtch_start_synchro(instance); | ||
| 389 | } | 391 | } |
| 390 | break; | 392 | break; |
| 391 | 393 | ||
diff --git a/include/asm-ppc64/iSeries/mf.h b/include/asm-ppc64/iSeries/mf.h index 2e59a8e15a0b..db333e1ee216 100644 --- a/include/asm-ppc64/iSeries/mf.h +++ b/include/asm-ppc64/iSeries/mf.h | |||
| @@ -52,6 +52,7 @@ extern void mf_clear_src(void); | |||
| 52 | extern void mf_init(void); | 52 | extern void mf_init(void); |
| 53 | 53 | ||
| 54 | extern int mf_get_rtc(struct rtc_time *tm); | 54 | extern int mf_get_rtc(struct rtc_time *tm); |
| 55 | extern int mf_get_boot_rtc(struct rtc_time *tm); | ||
| 55 | extern int mf_set_rtc(struct rtc_time *tm); | 56 | extern int mf_set_rtc(struct rtc_time *tm); |
| 56 | 57 | ||
| 57 | #endif /* _ASM_PPC64_ISERIES_MF_H */ | 58 | #endif /* _ASM_PPC64_ISERIES_MF_H */ |
