aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sn')
-rw-r--r--drivers/sn/Kconfig13
-rw-r--r--drivers/sn/ioc4.c36
2 files changed, 23 insertions, 26 deletions
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig
index a34731625877..34d4fde51a79 100644
--- a/drivers/sn/Kconfig
+++ b/drivers/sn/Kconfig
@@ -7,16 +7,15 @@ menu "SN Devices"
7 7
8config SGI_IOC4 8config SGI_IOC4
9 tristate "SGI IOC4 Base IO support" 9 tristate "SGI IOC4 Base IO support"
10 depends on MMTIMER
11 default m 10 default m
12 ---help--- 11 ---help---
13 This option enables basic support for the SGI IOC4-based Base IO 12 This option enables basic support for the IOC4 chip on certain
14 controller card. This option does not enable any specific 13 SGI IO controller cards (IO9, IO10, and PCI-RT). This option
15 functions on such a card, but provides necessary infrastructure 14 does not enable any specific functions on such a card, but provides
16 for other drivers to utilize. 15 necessary infrastructure for other drivers to utilize.
17 16
18 If you have an SGI Altix with an IOC4-based 17 If you have an SGI Altix with an IOC4-based card say Y.
19 I/O controller say Y. Otherwise say N. 18 Otherwise say N.
20 19
21config SGI_IOC3 20config SGI_IOC3
22 tristate "SGI IOC3 Base IO support" 21 tristate "SGI IOC3 Base IO support"
diff --git a/drivers/sn/ioc4.c b/drivers/sn/ioc4.c
index 8562821e6498..83d2e90c581c 100644
--- a/drivers/sn/ioc4.c
+++ b/drivers/sn/ioc4.c
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 2005 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (C) 2005-2006 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9/* This file contains the master driver module for use by SGI IOC4 subdrivers. 9/* This file contains the master driver module for use by SGI IOC4 subdrivers.
@@ -29,9 +29,9 @@
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/ioc4.h> 31#include <linux/ioc4.h>
32#include <linux/mmtimer.h> 32#include <linux/ktime.h>
33#include <linux/rtc.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/time.h>
35#include <asm/sn/addrs.h> 35#include <asm/sn/addrs.h>
36#include <asm/sn/clksupport.h> 36#include <asm/sn/clksupport.h>
37#include <asm/sn/shub_mmr.h> 37#include <asm/sn/shub_mmr.h>
@@ -43,7 +43,7 @@
43/* Tweakable values */ 43/* Tweakable values */
44 44
45/* PCI bus speed detection/calibration */ 45/* PCI bus speed detection/calibration */
46#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */ 46#define IOC4_CALIBRATE_COUNT 63 /* Calibration cycle period */
47#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */ 47#define IOC4_CALIBRATE_CYCLES 256 /* Average over this many cycles */
48#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */ 48#define IOC4_CALIBRATE_DISCARD 2 /* Discard first few cycles */
49#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */ 49#define IOC4_CALIBRATE_LOW_MHZ 25 /* Lower bound on bus speed sanity */
@@ -143,11 +143,11 @@ ioc4_unregister_submodule(struct ioc4_submodule *is)
143static void 143static void
144ioc4_clock_calibrate(struct ioc4_driver_data *idd) 144ioc4_clock_calibrate(struct ioc4_driver_data *idd)
145{ 145{
146 extern unsigned long sn_rtc_cycles_per_second;
147 union ioc4_int_out int_out; 146 union ioc4_int_out int_out;
148 union ioc4_gpcr gpcr; 147 union ioc4_gpcr gpcr;
149 unsigned int state, last_state = 1; 148 unsigned int state, last_state = 1;
150 uint64_t start = 0, end, period; 149 struct timespec start_ts, end_ts;
150 uint64_t start, end, period;
151 unsigned int count = 0; 151 unsigned int count = 0;
152 152
153 /* Enable output */ 153 /* Enable output */
@@ -175,30 +175,28 @@ ioc4_clock_calibrate(struct ioc4_driver_data *idd)
175 if (!last_state && state) { 175 if (!last_state && state) {
176 count++; 176 count++;
177 if (count == IOC4_CALIBRATE_END) { 177 if (count == IOC4_CALIBRATE_END) {
178 end = rtc_time(); 178 ktime_get_ts(&end_ts);
179 break; 179 break;
180 } else if (count == IOC4_CALIBRATE_DISCARD) 180 } else if (count == IOC4_CALIBRATE_DISCARD)
181 start = rtc_time(); 181 ktime_get_ts(&start_ts);
182 } 182 }
183 last_state = state; 183 last_state = state;
184 } while (1); 184 } while (1);
185 185
186 /* Calculation rearranged to preserve intermediate precision. 186 /* Calculation rearranged to preserve intermediate precision.
187 * Logically: 187 * Logically:
188 * 1. "end - start" gives us number of RTC cycles over all the 188 * 1. "end - start" gives us the measurement period over all
189 * square wave cycles measured. 189 * the square wave cycles.
190 * 2. Divide by number of square wave cycles to get number of 190 * 2. Divide by number of square wave cycles to get the period
191 * RTC cycles per square wave cycle. 191 * of a square wave cycle.
192 * 3. Divide by 2*(int_out.fields.count+1), which is the formula 192 * 3. Divide by 2*(int_out.fields.count+1), which is the formula
193 * by which the IOC4 generates the square wave, to get the 193 * by which the IOC4 generates the square wave, to get the
194 * number of RTC cycles per IOC4 INT_OUT count. 194 * period of an IOC4 INT_OUT count.
195 * 4. Divide by sn_rtc_cycles_per_second to get seconds per
196 * count.
197 * 5. Multiply by 1E9 to get nanoseconds per count.
198 */ 195 */
199 period = ((end - start) * 1000000000) / 196 end = end_ts.tv_sec * NSEC_PER_SEC + end_ts.tv_nsec;
200 (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1) 197 start = start_ts.tv_sec * NSEC_PER_SEC + start_ts.tv_nsec;
201 * sn_rtc_cycles_per_second); 198 period = (end - start) /
199 (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
202 200
203 /* Bounds check the result. */ 201 /* Bounds check the result. */
204 if (period > IOC4_CALIBRATE_LOW_LIMIT || 202 if (period > IOC4_CALIBRATE_LOW_LIMIT ||