Merge branch 'fortglx/3.4/clocksource' of git://git.linaro.org/people/jstultz/linux into timers/core
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/async.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -179,17 +180,15 @@ static int verify_pmtmr_rate(void)
|
|||||||
/* Number of reads we try to get two different values */
|
/* Number of reads we try to get two different values */
|
||||||
#define ACPI_PM_READ_CHECKS 10000
|
#define ACPI_PM_READ_CHECKS 10000
|
||||||
|
|
||||||
static int __init init_acpi_pm_clocksource(void)
|
static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie)
|
||||||
{
|
{
|
||||||
cycle_t value1, value2;
|
cycle_t value1, value2;
|
||||||
unsigned int i, j = 0;
|
unsigned int i, j = 0;
|
||||||
|
|
||||||
if (!pmtmr_ioport)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
/* "verify" this timing source: */
|
/* "verify" this timing source: */
|
||||||
for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
|
for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
|
||||||
udelay(100 * j);
|
usleep_range(100 * j, 100 * j + 100);
|
||||||
value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
|
value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
|
||||||
for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
|
for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
|
||||||
value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
|
value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm);
|
||||||
@@ -203,25 +202,34 @@ static int __init init_acpi_pm_clocksource(void)
|
|||||||
" 0x%#llx, 0x%#llx - aborting.\n",
|
" 0x%#llx, 0x%#llx - aborting.\n",
|
||||||
value1, value2);
|
value1, value2);
|
||||||
pmtmr_ioport = 0;
|
pmtmr_ioport = 0;
|
||||||
return -EINVAL;
|
return;
|
||||||
}
|
}
|
||||||
if (i == ACPI_PM_READ_CHECKS) {
|
if (i == ACPI_PM_READ_CHECKS) {
|
||||||
printk(KERN_INFO "PM-Timer failed consistency check "
|
printk(KERN_INFO "PM-Timer failed consistency check "
|
||||||
" (0x%#llx) - aborting.\n", value1);
|
" (0x%#llx) - aborting.\n", value1);
|
||||||
pmtmr_ioport = 0;
|
pmtmr_ioport = 0;
|
||||||
return -ENODEV;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify_pmtmr_rate() != 0){
|
if (verify_pmtmr_rate() != 0){
|
||||||
pmtmr_ioport = 0;
|
pmtmr_ioport = 0;
|
||||||
return -ENODEV;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clocksource_register_hz(&clocksource_acpi_pm,
|
clocksource_register_hz(&clocksource_acpi_pm,
|
||||||
PMTMR_TICKS_PER_SEC);
|
PMTMR_TICKS_PER_SEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init init_acpi_pm_clocksource(void)
|
||||||
|
{
|
||||||
|
if (!pmtmr_ioport)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
async_schedule(acpi_pm_clocksource_async, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* We use fs_initcall because we want the PCI fixups to have run
|
/* We use fs_initcall because we want the PCI fixups to have run
|
||||||
* but we still need to load before device_initcall
|
* but we still need to load before device_initcall
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ static struct clocksource clocksource_dbx500_prcmu = {
|
|||||||
.name = "dbx500-prcmu-timer",
|
.name = "dbx500-prcmu-timer",
|
||||||
.rating = 300,
|
.rating = 300,
|
||||||
.read = clksrc_dbx500_prcmu_read,
|
.read = clksrc_dbx500_prcmu_read,
|
||||||
.shift = 10,
|
|
||||||
.mask = CLOCKSOURCE_MASK(32),
|
.mask = CLOCKSOURCE_MASK(32),
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
};
|
};
|
||||||
@@ -90,7 +89,5 @@ void __init clksrc_dbx500_prcmu_init(void __iomem *base)
|
|||||||
setup_sched_clock(dbx500_prcmu_sched_clock_read,
|
setup_sched_clock(dbx500_prcmu_sched_clock_read,
|
||||||
32, RATE_32K);
|
32, RATE_32K);
|
||||||
#endif
|
#endif
|
||||||
clocksource_calc_mult_shift(&clocksource_dbx500_prcmu,
|
clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K);
|
||||||
RATE_32K, SCHED_CLOCK_MIN_WRAP);
|
|
||||||
clocksource_register(&clocksource_dbx500_prcmu);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,11 +55,11 @@ static int __init init_cyclone_clocksource(void)
|
|||||||
}
|
}
|
||||||
/* even on 64bit systems, this is only 32bits: */
|
/* even on 64bit systems, this is only 32bits: */
|
||||||
base = readl(reg);
|
base = readl(reg);
|
||||||
|
iounmap(reg);
|
||||||
if (!base) {
|
if (!base) {
|
||||||
printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
|
printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
iounmap(reg);
|
|
||||||
|
|
||||||
/* setup PMCC: */
|
/* setup PMCC: */
|
||||||
offset = base + CYCLONE_PMCC_OFFSET;
|
offset = base + CYCLONE_PMCC_OFFSET;
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ static cycle_t read_hrt(struct clocksource *cs)
|
|||||||
return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
|
return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HRT_SHIFT_1 22
|
|
||||||
#define HRT_SHIFT_27 26
|
|
||||||
|
|
||||||
static struct clocksource cs_hrt = {
|
static struct clocksource cs_hrt = {
|
||||||
.name = "scx200_hrt",
|
.name = "scx200_hrt",
|
||||||
.rating = 250,
|
.rating = 250,
|
||||||
@@ -63,6 +60,7 @@ static struct clocksource cs_hrt = {
|
|||||||
|
|
||||||
static int __init init_hrt_clocksource(void)
|
static int __init init_hrt_clocksource(void)
|
||||||
{
|
{
|
||||||
|
u32 freq;
|
||||||
/* Make sure scx200 has initialized the configuration block */
|
/* Make sure scx200 has initialized the configuration block */
|
||||||
if (!scx200_cb_present())
|
if (!scx200_cb_present())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@@ -71,7 +69,7 @@ static int __init init_hrt_clocksource(void)
|
|||||||
if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET,
|
if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET,
|
||||||
SCx200_TIMER_SIZE,
|
SCx200_TIMER_SIZE,
|
||||||
"NatSemi SCx200 High-Resolution Timer")) {
|
"NatSemi SCx200 High-Resolution Timer")) {
|
||||||
printk(KERN_WARNING NAME ": unable to lock timer region\n");
|
pr_warn("unable to lock timer region\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,19 +77,15 @@ static int __init init_hrt_clocksource(void)
|
|||||||
outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
|
outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
|
||||||
scx200_cb_base + SCx200_TMCNFG_OFFSET);
|
scx200_cb_base + SCx200_TMCNFG_OFFSET);
|
||||||
|
|
||||||
if (mhz27) {
|
freq = (HRT_FREQ + ppm);
|
||||||
cs_hrt.shift = HRT_SHIFT_27;
|
if (mhz27)
|
||||||
cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27,
|
freq *= 27;
|
||||||
cs_hrt.shift);
|
|
||||||
} else {
|
pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n",
|
||||||
cs_hrt.shift = HRT_SHIFT_1;
|
|
||||||
cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm,
|
|
||||||
cs_hrt.shift);
|
|
||||||
}
|
|
||||||
printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n",
|
printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n",
|
||||||
mhz27 ? "27":"1", ppm);
|
mhz27 ? "27":"1", ppm);
|
||||||
|
|
||||||
return clocksource_register(&cs_hrt);
|
return clocksource_register_hz(&cs_hrt, freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init_hrt_clocksource);
|
module_init(init_hrt_clocksource);
|
||||||
|
|||||||
@@ -319,13 +319,6 @@ static inline void __clocksource_updatefreq_khz(struct clocksource *cs, u32 khz)
|
|||||||
__clocksource_updatefreq_scale(cs, 1000, khz);
|
__clocksource_updatefreq_scale(cs, 1000, khz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
clocksource_calc_mult_shift(struct clocksource *cs, u32 freq, u32 minsec)
|
|
||||||
{
|
|
||||||
return clocks_calc_mult_shift(&cs->mult, &cs->shift, freq,
|
|
||||||
NSEC_PER_SEC, minsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
#ifdef CONFIG_GENERIC_TIME_VSYSCALL
|
||||||
extern void
|
extern void
|
||||||
update_vsyscall(struct timespec *ts, struct timespec *wtm,
|
update_vsyscall(struct timespec *ts, struct timespec *wtm,
|
||||||
|
|||||||
Reference in New Issue
Block a user