diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/drivers/clocksource | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/drivers/clocksource')
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/Kconfig | 31 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/Makefile | 12 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/acpi_pm.c | 250 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/clksrc-dbx500-prcmu.c | 93 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/cs5535-clockevt.c | 198 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/cyclone.c | 113 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/dw_apb_timer.c | 401 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/i8253.c | 186 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/mmio.c | 73 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/scx200_hrt.c | 93 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/sh_cmt.c | 744 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/sh_mtu2.c | 361 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/sh_tmu.c | 465 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/clocksource/tcb_clksrc.c | 334 |
14 files changed, 0 insertions, 3354 deletions
diff --git a/ANDROID_3.4.5/drivers/clocksource/Kconfig b/ANDROID_3.4.5/drivers/clocksource/Kconfig deleted file mode 100644 index 5138927a..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/Kconfig +++ /dev/null @@ -1,31 +0,0 @@ -config CLKSRC_I8253 - bool - -config CLKEVT_I8253 - bool - -config I8253_LOCK - bool - -config CLKBLD_I8253 - def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK - -config CLKSRC_MMIO - bool - -config DW_APB_TIMER - bool - -config CLKSRC_DBX500_PRCMU - bool "Clocksource PRCMU Timer" - depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 - default y - help - Use the always on PRCMU Timer as clocksource - -config CLKSRC_DBX500_PRCMU_SCHED_CLOCK - bool "Clocksource PRCMU Timer sched_clock" - depends on (CLKSRC_DBX500_PRCMU && !NOMADIK_MTU_SCHED_CLOCK) - default y - help - Use the always on PRCMU Timer as sched_clock diff --git a/ANDROID_3.4.5/drivers/clocksource/Makefile b/ANDROID_3.4.5/drivers/clocksource/Makefile deleted file mode 100644 index 8d81a1d3..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o -obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o -obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o -obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o -obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o -obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o -obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o -obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o -obj-$(CONFIG_CLKBLD_I8253) += i8253.o -obj-$(CONFIG_CLKSRC_MMIO) += mmio.o -obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o -obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
\ No newline at end of file diff --git a/ANDROID_3.4.5/drivers/clocksource/acpi_pm.c b/ANDROID_3.4.5/drivers/clocksource/acpi_pm.c deleted file mode 100644 index 6b5cf02c..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/acpi_pm.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * linux/drivers/clocksource/acpi_pm.c - * - * This file contains the ACPI PM based clocksource. - * - * This code was largely moved from the i386 timer_pm.c file - * which was (C) Dominik Brodowski <linux@brodo.de> 2003 - * and contained the following comments: - * - * Driver to use the Power Management Timer (PMTMR) available in some - * southbridges as primary timing source for the Linux kernel. - * - * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, - * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. - * - * This file is licensed under the GPL v2. - */ - -#include <linux/acpi_pmtmr.h> -#include <linux/clocksource.h> -#include <linux/timex.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <asm/io.h> - -/* - * The I/O port the PMTMR resides at. - * The location is detected during setup_arch(), - * in arch/i386/kernel/acpi/boot.c - */ -u32 pmtmr_ioport __read_mostly; - -static inline u32 read_pmtmr(void) -{ - /* mask the output to 24 bits */ - return inl(pmtmr_ioport) & ACPI_PM_MASK; -} - -u32 acpi_pm_read_verified(void) -{ - u32 v1 = 0, v2 = 0, v3 = 0; - - /* - * It has been reported that because of various broken - * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM clock - * source is not latched, you must read it multiple - * times to ensure a safe value is read: - */ - do { - v1 = read_pmtmr(); - v2 = read_pmtmr(); - v3 = read_pmtmr(); - } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) - || (v3 > v1 && v3 < v2))); - - return v2; -} - -static cycle_t acpi_pm_read(struct clocksource *cs) -{ - return (cycle_t)read_pmtmr(); -} - -static struct clocksource clocksource_acpi_pm = { - .name = "acpi_pm", - .rating = 200, - .read = acpi_pm_read, - .mask = (cycle_t)ACPI_PM_MASK, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - - -#ifdef CONFIG_PCI -static int __devinitdata acpi_pm_good; -static int __init acpi_pm_good_setup(char *__str) -{ - acpi_pm_good = 1; - return 1; -} -__setup("acpi_pm_good", acpi_pm_good_setup); - -static cycle_t acpi_pm_read_slow(struct clocksource *cs) -{ - return (cycle_t)acpi_pm_read_verified(); -} - -static inline void acpi_pm_need_workaround(void) -{ - clocksource_acpi_pm.read = acpi_pm_read_slow; - clocksource_acpi_pm.rating = 120; -} - -/* - * PIIX4 Errata: - * - * The power management timer may return improper results when read. - * Although the timer value settles properly after incrementing, - * while incrementing there is a 3 ns window every 69.8 ns where the - * timer value is indeterminate (a 4.2% chance that the data will be - * incorrect when read). As a result, the ACPI free running count up - * timer specification is violated due to erroneous reads. - */ -static void __devinit acpi_pm_check_blacklist(struct pci_dev *dev) -{ - if (acpi_pm_good) - return; - - /* the bug has been fixed in PIIX4M */ - if (dev->revision < 3) { - printk(KERN_WARNING "* Found PM-Timer Bug on the chipset." - " Due to workarounds for a bug,\n" - "* this clock source is slow. Consider trying" - " other clock sources\n"); - - acpi_pm_need_workaround(); - } -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - acpi_pm_check_blacklist); - -static void __devinit acpi_pm_check_graylist(struct pci_dev *dev) -{ - if (acpi_pm_good) - return; - - printk(KERN_WARNING "* The chipset may have PM-Timer Bug. Due to" - " workarounds for a bug,\n" - "* this clock source is slow. If you are sure your timer" - " does not have\n" - "* this bug, please use \"acpi_pm_good\" to disable the" - " workaround\n"); - - acpi_pm_need_workaround(); -} -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, - acpi_pm_check_graylist); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_LE, - acpi_pm_check_graylist); -#endif - -#ifndef CONFIG_X86_64 -#include <asm/mach_timer.h> -#define PMTMR_EXPECTED_RATE \ - ((CALIBRATE_LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (PIT_TICK_RATE>>10)) -/* - * Some boards have the PMTMR running way too fast. We check - * the PMTMR rate against PIT channel 2 to catch these cases. - */ -static int verify_pmtmr_rate(void) -{ - cycle_t value1, value2; - unsigned long count, delta; - - mach_prepare_counter(); - value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); - mach_countup(&count); - value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); - delta = (value2 - value1) & ACPI_PM_MASK; - - /* Check that the PMTMR delta is within 5% of what we expect */ - if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 || - delta > (PMTMR_EXPECTED_RATE * 21) / 20) { - printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% " - "of normal - aborting.\n", - 100UL * delta / PMTMR_EXPECTED_RATE); - return -1; - } - - return 0; -} -#else -#define verify_pmtmr_rate() (0) -#endif - -/* Number of monotonicity checks to perform during initialization */ -#define ACPI_PM_MONOTONICITY_CHECKS 10 -/* Number of reads we try to get two different values */ -#define ACPI_PM_READ_CHECKS 10000 - -static int __init init_acpi_pm_clocksource(void) -{ - cycle_t value1, value2; - unsigned int i, j = 0; - - if (!pmtmr_ioport) - return -ENODEV; - - /* "verify" this timing source: */ - for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - udelay(100 * j); - value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); - for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { - value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); - if (value2 == value1) - continue; - if (value2 > value1) - break; - if ((value2 < value1) && ((value2) < 0xFFF)) - break; - printk(KERN_INFO "PM-Timer had inconsistent results:" - " 0x%#llx, 0x%#llx - aborting.\n", - value1, value2); - pmtmr_ioport = 0; - return -EINVAL; - } - if (i == ACPI_PM_READ_CHECKS) { - printk(KERN_INFO "PM-Timer failed consistency check " - " (0x%#llx) - aborting.\n", value1); - pmtmr_ioport = 0; - return -ENODEV; - } - } - - if (verify_pmtmr_rate() != 0){ - pmtmr_ioport = 0; - return -ENODEV; - } - - return clocksource_register_hz(&clocksource_acpi_pm, - PMTMR_TICKS_PER_SEC); -} - -/* We use fs_initcall because we want the PCI fixups to have run - * but we still need to load before device_initcall - */ -fs_initcall(init_acpi_pm_clocksource); - -/* - * Allow an override of the IOPort. Stupid BIOSes do not tell us about - * the PMTimer, but we might know where it is. - */ -static int __init parse_pmtmr(char *arg) -{ - unsigned long base; - - if (strict_strtoul(arg, 16, &base)) - return -EINVAL; -#ifdef CONFIG_X86_64 - if (base > UINT_MAX) - return -ERANGE; -#endif - printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n", - pmtmr_ioport, base); - pmtmr_ioport = base; - - return 1; -} -__setup("pmtmr=", parse_pmtmr); diff --git a/ANDROID_3.4.5/drivers/clocksource/clksrc-dbx500-prcmu.c b/ANDROID_3.4.5/drivers/clocksource/clksrc-dbx500-prcmu.c deleted file mode 100644 index c26c369e..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/clksrc-dbx500-prcmu.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2011 - * - * License Terms: GNU General Public License v2 - * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson - * Author: Sundar Iyer for ST-Ericsson - * sched_clock implementation is based on: - * plat-nomadik/timer.c Linus Walleij <linus.walleij@stericsson.com> - * - * DBx500-PRCMU Timer - * The PRCMU has 5 timers which are available in a always-on - * power domain. We use the Timer 4 for our always-on clock - * source on DB8500 and Timer 3 on DB5500. - */ -#include <linux/clockchips.h> -#include <linux/clksrc-dbx500-prcmu.h> - -#include <asm/sched_clock.h> - -#include <mach/setup.h> -#include <mach/hardware.h> - -#define RATE_32K 32768 - -#define TIMER_MODE_CONTINOUS 0x1 -#define TIMER_DOWNCOUNT_VAL 0xffffffff - -#define PRCMU_TIMER_REF 0 -#define PRCMU_TIMER_DOWNCOUNT 0x4 -#define PRCMU_TIMER_MODE 0x8 - -#define SCHED_CLOCK_MIN_WRAP 131072 /* 2^32 / 32768 */ - -static void __iomem *clksrc_dbx500_timer_base; - -static cycle_t clksrc_dbx500_prcmu_read(struct clocksource *cs) -{ - u32 count, count2; - - do { - count = readl(clksrc_dbx500_timer_base + - PRCMU_TIMER_DOWNCOUNT); - count2 = readl(clksrc_dbx500_timer_base + - PRCMU_TIMER_DOWNCOUNT); - } while (count2 != count); - - /* Negate because the timer is a decrementing counter */ - return ~count; -} - -static struct clocksource clocksource_dbx500_prcmu = { - .name = "dbx500-prcmu-timer", - .rating = 300, - .read = clksrc_dbx500_prcmu_read, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK - -static u32 notrace dbx500_prcmu_sched_clock_read(void) -{ - if (unlikely(!clksrc_dbx500_timer_base)) - return 0; - - return clksrc_dbx500_prcmu_read(&clocksource_dbx500_prcmu); -} - -#endif - -void __init clksrc_dbx500_prcmu_init(void __iomem *base) -{ - clksrc_dbx500_timer_base = base; - - /* - * The A9 sub system expects the timer to be configured as - * a continous looping timer. - * The PRCMU should configure it but if it for some reason - * don't we do it here. - */ - if (readl(clksrc_dbx500_timer_base + PRCMU_TIMER_MODE) != - TIMER_MODE_CONTINOUS) { - writel(TIMER_MODE_CONTINOUS, - clksrc_dbx500_timer_base + PRCMU_TIMER_MODE); - writel(TIMER_DOWNCOUNT_VAL, - clksrc_dbx500_timer_base + PRCMU_TIMER_REF); - } -#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK - setup_sched_clock(dbx500_prcmu_sched_clock_read, - 32, RATE_32K); -#endif - clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); -} diff --git a/ANDROID_3.4.5/drivers/clocksource/cs5535-clockevt.c b/ANDROID_3.4.5/drivers/clocksource/cs5535-clockevt.c deleted file mode 100644 index 540795cd..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/cs5535-clockevt.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Clock event driver for the CS5535/CS5536 - * - * Copyright (C) 2006, Advanced Micro Devices, Inc. - * Copyright (C) 2007 Andres Salomon <dilinger@debian.org> - * Copyright (C) 2009 Andres Salomon <dilinger@collabora.co.uk> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * - * The MFGPTs are documented in AMD Geode CS5536 Companion Device Data Book. - */ - -#include <linux/kernel.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/module.h> -#include <linux/cs5535.h> -#include <linux/clockchips.h> - -#define DRV_NAME "cs5535-clockevt" - -static int timer_irq; -module_param_named(irq, timer_irq, int, 0644); -MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks."); - -/* - * We are using the 32.768kHz input clock - it's the only one that has the - * ranges we find desirable. The following table lists the suitable - * divisors and the associated Hz, minimum interval and the maximum interval: - * - * Divisor Hz Min Delta (s) Max Delta (s) - * 1 32768 .00048828125 2.000 - * 2 16384 .0009765625 4.000 - * 4 8192 .001953125 8.000 - * 8 4096 .00390625 16.000 - * 16 2048 .0078125 32.000 - * 32 1024 .015625 64.000 - * 64 512 .03125 128.000 - * 128 256 .0625 256.000 - * 256 128 .125 512.000 - */ - -static unsigned int cs5535_tick_mode = CLOCK_EVT_MODE_SHUTDOWN; -static struct cs5535_mfgpt_timer *cs5535_event_clock; - -/* Selected from the table above */ - -#define MFGPT_DIVISOR 16 -#define MFGPT_SCALE 4 /* divisor = 2^(scale) */ -#define MFGPT_HZ (32768 / MFGPT_DIVISOR) -#define MFGPT_PERIODIC (MFGPT_HZ / HZ) - -/* - * The MFPGT timers on the CS5536 provide us with suitable timers to use - * as clock event sources - not as good as a HPET or APIC, but certainly - * better than the PIT. This isn't a general purpose MFGPT driver, but - * a simplified one designed specifically to act as a clock event source. - * For full details about the MFGPT, please consult the CS5536 data sheet. - */ - -static void disable_timer(struct cs5535_mfgpt_timer *timer) -{ - /* avoid races by clearing CMP1 and CMP2 unconditionally */ - cs5535_mfgpt_write(timer, MFGPT_REG_SETUP, - (uint16_t) ~MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP1 | - MFGPT_SETUP_CMP2); -} - -static void start_timer(struct cs5535_mfgpt_timer *timer, uint16_t delta) -{ - cs5535_mfgpt_write(timer, MFGPT_REG_CMP2, delta); - cs5535_mfgpt_write(timer, MFGPT_REG_COUNTER, 0); - - cs5535_mfgpt_write(timer, MFGPT_REG_SETUP, - MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); -} - -static void mfgpt_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - disable_timer(cs5535_event_clock); - - if (mode == CLOCK_EVT_MODE_PERIODIC) - start_timer(cs5535_event_clock, MFGPT_PERIODIC); - - cs5535_tick_mode = mode; -} - -static int mfgpt_next_event(unsigned long delta, struct clock_event_device *evt) -{ - start_timer(cs5535_event_clock, delta); - return 0; -} - -static struct clock_event_device cs5535_clockevent = { - .name = DRV_NAME, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = mfgpt_set_mode, - .set_next_event = mfgpt_next_event, - .rating = 250, - .shift = 32 -}; - -static irqreturn_t mfgpt_tick(int irq, void *dev_id) -{ - uint16_t val = cs5535_mfgpt_read(cs5535_event_clock, MFGPT_REG_SETUP); - - /* See if the interrupt was for us */ - if (!(val & (MFGPT_SETUP_SETUP | MFGPT_SETUP_CMP2 | MFGPT_SETUP_CMP1))) - return IRQ_NONE; - - /* Turn off the clock (and clear the event) */ - disable_timer(cs5535_event_clock); - - if (cs5535_tick_mode == CLOCK_EVT_MODE_SHUTDOWN) - return IRQ_HANDLED; - - /* Clear the counter */ - cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_COUNTER, 0); - - /* Restart the clock in periodic mode */ - - if (cs5535_tick_mode == CLOCK_EVT_MODE_PERIODIC) - cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP, - MFGPT_SETUP_CNTEN | MFGPT_SETUP_CMP2); - - cs5535_clockevent.event_handler(&cs5535_clockevent); - return IRQ_HANDLED; -} - -static struct irqaction mfgptirq = { - .handler = mfgpt_tick, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER | IRQF_SHARED, - .name = DRV_NAME, -}; - -static int __init cs5535_mfgpt_init(void) -{ - struct cs5535_mfgpt_timer *timer; - int ret; - uint16_t val; - - timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); - if (!timer) { - printk(KERN_ERR DRV_NAME ": Could not allocate MFPGT timer\n"); - return -ENODEV; - } - cs5535_event_clock = timer; - - /* Set up the IRQ on the MFGPT side */ - if (cs5535_mfgpt_setup_irq(timer, MFGPT_CMP2, &timer_irq)) { - printk(KERN_ERR DRV_NAME ": Could not set up IRQ %d\n", - timer_irq); - goto err_timer; - } - - /* And register it with the kernel */ - ret = setup_irq(timer_irq, &mfgptirq); - if (ret) { - printk(KERN_ERR DRV_NAME ": Unable to set up the interrupt.\n"); - goto err_irq; - } - - /* Set the clock scale and enable the event mode for CMP2 */ - val = MFGPT_SCALE | (3 << 8); - - cs5535_mfgpt_write(cs5535_event_clock, MFGPT_REG_SETUP, val); - - /* Set up the clock event */ - cs5535_clockevent.mult = div_sc(MFGPT_HZ, NSEC_PER_SEC, - cs5535_clockevent.shift); - cs5535_clockevent.min_delta_ns = clockevent_delta2ns(0xF, - &cs5535_clockevent); - cs5535_clockevent.max_delta_ns = clockevent_delta2ns(0xFFFE, - &cs5535_clockevent); - - printk(KERN_INFO DRV_NAME - ": Registering MFGPT timer as a clock event, using IRQ %d\n", - timer_irq); - clockevents_register_device(&cs5535_clockevent); - - return 0; - -err_irq: - cs5535_mfgpt_release_irq(cs5535_event_clock, MFGPT_CMP2, &timer_irq); -err_timer: - cs5535_mfgpt_free_timer(cs5535_event_clock); - printk(KERN_ERR DRV_NAME ": Unable to set up the MFGPT clock source\n"); - return -EIO; -} - -module_init(cs5535_mfgpt_init); - -MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); -MODULE_DESCRIPTION("CS5535/CS5536 MFGPT clock event driver"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/clocksource/cyclone.c b/ANDROID_3.4.5/drivers/clocksource/cyclone.c deleted file mode 100644 index 9e0998f2..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/cyclone.c +++ /dev/null @@ -1,113 +0,0 @@ -#include <linux/clocksource.h> -#include <linux/string.h> -#include <linux/errno.h> -#include <linux/timex.h> -#include <linux/init.h> - -#include <asm/pgtable.h> -#include <asm/io.h> - -#include <asm/mach_timer.h> - -#define CYCLONE_CBAR_ADDR 0xFEB00CD0 /* base address ptr */ -#define CYCLONE_PMCC_OFFSET 0x51A0 /* offset to control register */ -#define CYCLONE_MPCS_OFFSET 0x51A8 /* offset to select register */ -#define CYCLONE_MPMC_OFFSET 0x51D0 /* offset to count register */ -#define CYCLONE_TIMER_FREQ 99780000 /* 100Mhz, but not really */ -#define CYCLONE_TIMER_MASK CLOCKSOURCE_MASK(32) /* 32 bit mask */ - -int use_cyclone = 0; -static void __iomem *cyclone_ptr; - -static cycle_t read_cyclone(struct clocksource *cs) -{ - return (cycle_t)readl(cyclone_ptr); -} - -static struct clocksource clocksource_cyclone = { - .name = "cyclone", - .rating = 250, - .read = read_cyclone, - .mask = CYCLONE_TIMER_MASK, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init init_cyclone_clocksource(void) -{ - unsigned long base; /* saved value from CBAR */ - unsigned long offset; - u32 __iomem* volatile cyclone_timer; /* Cyclone MPMC0 register */ - u32 __iomem* reg; - int i; - - /* make sure we're on a summit box: */ - if (!use_cyclone) - return -ENODEV; - - printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n"); - - /* find base address: */ - offset = CYCLONE_CBAR_ADDR; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); - return -ENODEV; - } - /* even on 64bit systems, this is only 32bits: */ - base = readl(reg); - iounmap(reg); - if (!base) { - printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); - return -ENODEV; - } - - /* setup PMCC: */ - offset = base + CYCLONE_PMCC_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* setup MPCS: */ - offset = base + CYCLONE_MPCS_OFFSET; - reg = ioremap_nocache(offset, sizeof(reg)); - if (!reg) { - printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); - return -ENODEV; - } - writel(0x00000001,reg); - iounmap(reg); - - /* map in cyclone_timer: */ - offset = base + CYCLONE_MPMC_OFFSET; - cyclone_timer = ioremap_nocache(offset, sizeof(u64)); - if (!cyclone_timer) { - printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); - return -ENODEV; - } - - /* quick test to make sure its ticking: */ - for (i = 0; i < 3; i++){ - u32 old = readl(cyclone_timer); - int stall = 100; - - while (stall--) - barrier(); - - if (readl(cyclone_timer) == old) { - printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); - iounmap(cyclone_timer); - cyclone_timer = NULL; - return -ENODEV; - } - } - cyclone_ptr = cyclone_timer; - - return clocksource_register_hz(&clocksource_cyclone, - CYCLONE_TIMER_FREQ); -} - -arch_initcall(init_cyclone_clocksource); diff --git a/ANDROID_3.4.5/drivers/clocksource/dw_apb_timer.c b/ANDROID_3.4.5/drivers/clocksource/dw_apb_timer.c deleted file mode 100644 index 8c2a35f2..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/dw_apb_timer.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * (C) Copyright 2009 Intel Corporation - * Author: Jacob Pan (jacob.jun.pan@intel.com) - * - * Shared with ARM platforms, Jamie Iles, Picochip 2011 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Support for the Synopsys DesignWare APB Timers. - */ -#include <linux/dw_apb_timer.h> -#include <linux/delay.h> -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/io.h> -#include <linux/slab.h> - -#define APBT_MIN_PERIOD 4 -#define APBT_MIN_DELTA_USEC 200 - -#define APBTMR_N_LOAD_COUNT 0x00 -#define APBTMR_N_CURRENT_VALUE 0x04 -#define APBTMR_N_CONTROL 0x08 -#define APBTMR_N_EOI 0x0c -#define APBTMR_N_INT_STATUS 0x10 - -#define APBTMRS_INT_STATUS 0xa0 -#define APBTMRS_EOI 0xa4 -#define APBTMRS_RAW_INT_STATUS 0xa8 -#define APBTMRS_COMP_VERSION 0xac - -#define APBTMR_CONTROL_ENABLE (1 << 0) -/* 1: periodic, 0:free running. */ -#define APBTMR_CONTROL_MODE_PERIODIC (1 << 1) -#define APBTMR_CONTROL_INT (1 << 2) - -static inline struct dw_apb_clock_event_device * -ced_to_dw_apb_ced(struct clock_event_device *evt) -{ - return container_of(evt, struct dw_apb_clock_event_device, ced); -} - -static inline struct dw_apb_clocksource * -clocksource_to_dw_apb_clocksource(struct clocksource *cs) -{ - return container_of(cs, struct dw_apb_clocksource, cs); -} - -static unsigned long apbt_readl(struct dw_apb_timer *timer, unsigned long offs) -{ - return readl(timer->base + offs); -} - -static void apbt_writel(struct dw_apb_timer *timer, unsigned long val, - unsigned long offs) -{ - writel(val, timer->base + offs); -} - -static void apbt_disable_int(struct dw_apb_timer *timer) -{ - unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); - - ctrl |= APBTMR_CONTROL_INT; - apbt_writel(timer, ctrl, APBTMR_N_CONTROL); -} - -/** - * dw_apb_clockevent_pause() - stop the clock_event_device from running - * - * @dw_ced: The APB clock to stop generating events. - */ -void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced) -{ - disable_irq(dw_ced->timer.irq); - apbt_disable_int(&dw_ced->timer); -} - -static void apbt_eoi(struct dw_apb_timer *timer) -{ - apbt_readl(timer, APBTMR_N_EOI); -} - -static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) -{ - struct clock_event_device *evt = data; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - if (!evt->event_handler) { - pr_info("Spurious APBT timer interrupt %d", irq); - return IRQ_NONE; - } - - if (dw_ced->eoi) - dw_ced->eoi(&dw_ced->timer); - - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static void apbt_enable_int(struct dw_apb_timer *timer) -{ - unsigned long ctrl = apbt_readl(timer, APBTMR_N_CONTROL); - /* clear pending intr */ - apbt_readl(timer, APBTMR_N_EOI); - ctrl &= ~APBTMR_CONTROL_INT; - apbt_writel(timer, ctrl, APBTMR_N_CONTROL); -} - -static void apbt_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long ctrl; - unsigned long period; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - pr_debug("%s CPU %d mode=%d\n", __func__, first_cpu(*evt->cpumask), - mode); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - period = DIV_ROUND_UP(dw_ced->timer.freq, HZ); - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl |= APBTMR_CONTROL_MODE_PERIODIC; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* - * DW APB p. 46, have to disable timer before load counter, - * may cause sync problem. - */ - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - udelay(1); - pr_debug("Setting clock period %lu for HZ %d\n", period, HZ); - apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT); - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_ONESHOT: - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - /* - * set free running mode, this mode will let timer reload max - * timeout which will give time (3min on 25MHz clock) to rearm - * the next event, therefore emulate the one-shot mode. - */ - ctrl &= ~APBTMR_CONTROL_ENABLE; - ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; - - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* write again to set free running mode */ - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - - /* - * DW APB p. 46, load counter with all 1s before starting free - * running mode. - */ - apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT); - ctrl &= ~APBTMR_CONTROL_INT; - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - break; - - case CLOCK_EVT_MODE_RESUME: - apbt_enable_int(&dw_ced->timer); - break; - } -} - -static int apbt_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned long ctrl; - struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); - - /* Disable timer */ - ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - /* write new count */ - apbt_writel(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT); - ctrl |= APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); - - return 0; -} - -/** - * dw_apb_clockevent_init() - use an APB timer as a clock_event_device - * - * @cpu: The CPU the events will be targeted at. - * @name: The name used for the timer and the IRQ for it. - * @rating: The rating to give the timer. - * @base: I/O base for the timer registers. - * @irq: The interrupt number to use for the timer. - * @freq: The frequency that the timer counts at. - * - * This creates a clock_event_device for using with the generic clock layer - * but does not start and register it. This should be done with - * dw_apb_clockevent_register() as the next step. If this is the first time - * it has been called for a timer then the IRQ will be requested, if not it - * just be enabled to allow CPU hotplug to avoid repeatedly requesting and - * releasing the IRQ. - */ -struct dw_apb_clock_event_device * -dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, - void __iomem *base, int irq, unsigned long freq) -{ - struct dw_apb_clock_event_device *dw_ced = - kzalloc(sizeof(*dw_ced), GFP_KERNEL); - int err; - - if (!dw_ced) - return NULL; - - dw_ced->timer.base = base; - dw_ced->timer.irq = irq; - dw_ced->timer.freq = freq; - - clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD); - dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff, - &dw_ced->ced); - dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); - dw_ced->ced.cpumask = cpumask_of(cpu); - dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; - dw_ced->ced.set_mode = apbt_set_mode; - dw_ced->ced.set_next_event = apbt_next_event; - dw_ced->ced.irq = dw_ced->timer.irq; - dw_ced->ced.rating = rating; - dw_ced->ced.name = name; - - dw_ced->irqaction.name = dw_ced->ced.name; - dw_ced->irqaction.handler = dw_apb_clockevent_irq; - dw_ced->irqaction.dev_id = &dw_ced->ced; - dw_ced->irqaction.irq = irq; - dw_ced->irqaction.flags = IRQF_TIMER | IRQF_IRQPOLL | - IRQF_NOBALANCING | - IRQF_DISABLED; - - dw_ced->eoi = apbt_eoi; - err = setup_irq(irq, &dw_ced->irqaction); - if (err) { - pr_err("failed to request timer irq\n"); - kfree(dw_ced); - dw_ced = NULL; - } - - return dw_ced; -} - -/** - * dw_apb_clockevent_resume() - resume a clock that has been paused. - * - * @dw_ced: The APB clock to resume. - */ -void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced) -{ - enable_irq(dw_ced->timer.irq); -} - -/** - * dw_apb_clockevent_stop() - stop the clock_event_device and release the IRQ. - * - * @dw_ced: The APB clock to stop generating the events. - */ -void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced) -{ - free_irq(dw_ced->timer.irq, &dw_ced->ced); -} - -/** - * dw_apb_clockevent_register() - register the clock with the generic layer - * - * @dw_ced: The APB clock to register as a clock_event_device. - */ -void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced) -{ - apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL); - clockevents_register_device(&dw_ced->ced); - apbt_enable_int(&dw_ced->timer); -} - -/** - * dw_apb_clocksource_start() - start the clocksource counting. - * - * @dw_cs: The clocksource to start. - * - * This is used to start the clocksource before registration and can be used - * to enable calibration of timers. - */ -void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs) -{ - /* - * start count down from 0xffff_ffff. this is done by toggling the - * enable bit then load initial load count to ~0. - */ - unsigned long ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL); - - ctrl &= ~APBTMR_CONTROL_ENABLE; - apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); - apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT); - /* enable, mask interrupt */ - ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC; - ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT); - apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); - /* read it once to get cached counter value initialized */ - dw_apb_clocksource_read(dw_cs); -} - -static cycle_t __apbt_read_clocksource(struct clocksource *cs) -{ - unsigned long current_count; - struct dw_apb_clocksource *dw_cs = - clocksource_to_dw_apb_clocksource(cs); - - current_count = apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); - - return (cycle_t)~current_count; -} - -static void apbt_restart_clocksource(struct clocksource *cs) -{ - struct dw_apb_clocksource *dw_cs = - clocksource_to_dw_apb_clocksource(cs); - - dw_apb_clocksource_start(dw_cs); -} - -/** - * dw_apb_clocksource_init() - use an APB timer as a clocksource. - * - * @rating: The rating to give the clocksource. - * @name: The name for the clocksource. - * @base: The I/O base for the timer registers. - * @freq: The frequency that the timer counts at. - * - * This creates a clocksource using an APB timer but does not yet register it - * with the clocksource system. This should be done with - * dw_apb_clocksource_register() as the next step. - */ -struct dw_apb_clocksource * -dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, - unsigned long freq) -{ - struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL); - - if (!dw_cs) - return NULL; - - dw_cs->timer.base = base; - dw_cs->timer.freq = freq; - dw_cs->cs.name = name; - dw_cs->cs.rating = rating; - dw_cs->cs.read = __apbt_read_clocksource; - dw_cs->cs.mask = CLOCKSOURCE_MASK(32); - dw_cs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; - dw_cs->cs.resume = apbt_restart_clocksource; - - return dw_cs; -} - -/** - * dw_apb_clocksource_register() - register the APB clocksource. - * - * @dw_cs: The clocksource to register. - */ -void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs) -{ - clocksource_register_hz(&dw_cs->cs, dw_cs->timer.freq); -} - -/** - * dw_apb_clocksource_read() - read the current value of a clocksource. - * - * @dw_cs: The clocksource to read. - */ -cycle_t dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs) -{ - return (cycle_t)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE); -} - -/** - * dw_apb_clocksource_unregister() - unregister and free a clocksource. - * - * @dw_cs: The clocksource to unregister/free. - */ -void dw_apb_clocksource_unregister(struct dw_apb_clocksource *dw_cs) -{ - clocksource_unregister(&dw_cs->cs); - - kfree(dw_cs); -} diff --git a/ANDROID_3.4.5/drivers/clocksource/i8253.c b/ANDROID_3.4.5/drivers/clocksource/i8253.c deleted file mode 100644 index e7cab2da..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/i8253.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * i8253 PIT clocksource - */ -#include <linux/clockchips.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/spinlock.h> -#include <linux/timex.h> -#include <linux/module.h> -#include <linux/i8253.h> -#include <linux/smp.h> - -/* - * Protects access to I/O ports - * - * 0040-0043 : timer0, i8253 / i8254 - * 0061-0061 : NMI Control Register which contains two speaker control bits. - */ -DEFINE_RAW_SPINLOCK(i8253_lock); -EXPORT_SYMBOL(i8253_lock); - -#ifdef CONFIG_CLKSRC_I8253 -/* - * Since the PIT overflows every tick, its not very useful - * to just read by itself. So use jiffies to emulate a free - * running counter: - */ -static cycle_t i8253_read(struct clocksource *cs) -{ - static int old_count; - static u32 old_jifs; - unsigned long flags; - int count; - u32 jifs; - - raw_spin_lock_irqsave(&i8253_lock, flags); - /* - * Although our caller may have the read side of xtime_lock, - * this is now a seqlock, and we are cheating in this routine - * by having side effects on state that we cannot undo if - * there is a collision on the seqlock and our caller has to - * retry. (Namely, old_jifs and old_count.) So we must treat - * jiffies as volatile despite the lock. We read jiffies - * before latching the timer count to guarantee that although - * the jiffies value might be older than the count (that is, - * the counter may underflow between the last point where - * jiffies was incremented and the point where we latch the - * count), it cannot be newer. - */ - jifs = jiffies; - outb_p(0x00, PIT_MODE); /* latch the count ASAP */ - count = inb_p(PIT_CH0); /* read the latched count */ - count |= inb_p(PIT_CH0) << 8; - - /* VIA686a test code... reset the latch if count > max + 1 */ - if (count > PIT_LATCH) { - outb_p(0x34, PIT_MODE); - outb_p(PIT_LATCH & 0xff, PIT_CH0); - outb_p(PIT_LATCH >> 8, PIT_CH0); - count = PIT_LATCH - 1; - } - - /* - * It's possible for count to appear to go the wrong way for a - * couple of reasons: - * - * 1. The timer counter underflows, but we haven't handled the - * resulting interrupt and incremented jiffies yet. - * 2. Hardware problem with the timer, not giving us continuous time, - * the counter does small "jumps" upwards on some Pentium systems, - * (see c't 95/10 page 335 for Neptun bug.) - * - * Previous attempts to handle these cases intelligently were - * buggy, so we just do the simple thing now. - */ - if (count > old_count && jifs == old_jifs) - count = old_count; - - old_count = count; - old_jifs = jifs; - - raw_spin_unlock_irqrestore(&i8253_lock, flags); - - count = (PIT_LATCH - 1) - count; - - return (cycle_t)(jifs * PIT_LATCH) + count; -} - -static struct clocksource i8253_cs = { - .name = "pit", - .rating = 110, - .read = i8253_read, - .mask = CLOCKSOURCE_MASK(32), -}; - -int __init clocksource_i8253_init(void) -{ - return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE); -} -#endif - -#ifdef CONFIG_CLKEVT_I8253 -/* - * Initialize the PIT timer. - * - * This is also called after resume to bring the PIT into operation again. - */ -static void init_pit_timer(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - raw_spin_lock(&i8253_lock); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - /* binary, mode 2, LSB/MSB, ch 0 */ - outb_p(0x34, PIT_MODE); - outb_p(PIT_LATCH & 0xff , PIT_CH0); /* LSB */ - outb_p(PIT_LATCH >> 8 , PIT_CH0); /* MSB */ - break; - - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - if (evt->mode == CLOCK_EVT_MODE_PERIODIC || - evt->mode == CLOCK_EVT_MODE_ONESHOT) { - outb_p(0x30, PIT_MODE); - outb_p(0, PIT_CH0); - outb_p(0, PIT_CH0); - } - break; - - case CLOCK_EVT_MODE_ONESHOT: - /* One shot setup */ - outb_p(0x38, PIT_MODE); - break; - - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do here */ - break; - } - raw_spin_unlock(&i8253_lock); -} - -/* - * Program the next event in oneshot mode - * - * Delta is given in PIT ticks - */ -static int pit_next_event(unsigned long delta, struct clock_event_device *evt) -{ - raw_spin_lock(&i8253_lock); - outb_p(delta & 0xff , PIT_CH0); /* LSB */ - outb_p(delta >> 8 , PIT_CH0); /* MSB */ - raw_spin_unlock(&i8253_lock); - - return 0; -} - -/* - * On UP the PIT can serve all of the possible timer functions. On SMP systems - * it can be solely used for the global tick. - */ -struct clock_event_device i8253_clockevent = { - .name = "pit", - .features = CLOCK_EVT_FEAT_PERIODIC, - .set_mode = init_pit_timer, - .set_next_event = pit_next_event, -}; - -/* - * Initialize the conversion factor and the min/max deltas of the clock event - * structure and register the clock event source with the framework. - */ -void __init clockevent_i8253_init(bool oneshot) -{ - if (oneshot) - i8253_clockevent.features |= CLOCK_EVT_FEAT_ONESHOT; - /* - * Start pit with the boot cpu mask. x86 might make it global - * when it is used as broadcast device later. - */ - i8253_clockevent.cpumask = cpumask_of(smp_processor_id()); - - clockevents_config_and_register(&i8253_clockevent, PIT_TICK_RATE, - 0xF, 0x7FFF); -} -#endif diff --git a/ANDROID_3.4.5/drivers/clocksource/mmio.c b/ANDROID_3.4.5/drivers/clocksource/mmio.c deleted file mode 100644 index c0e25125..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/mmio.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Generic MMIO clocksource support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clocksource.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> - -struct clocksource_mmio { - void __iomem *reg; - struct clocksource clksrc; -}; - -static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c) -{ - return container_of(c, struct clocksource_mmio, clksrc); -} - -cycle_t clocksource_mmio_readl_up(struct clocksource *c) -{ - return readl_relaxed(to_mmio_clksrc(c)->reg); -} - -cycle_t clocksource_mmio_readl_down(struct clocksource *c) -{ - return ~readl_relaxed(to_mmio_clksrc(c)->reg); -} - -cycle_t clocksource_mmio_readw_up(struct clocksource *c) -{ - return readw_relaxed(to_mmio_clksrc(c)->reg); -} - -cycle_t clocksource_mmio_readw_down(struct clocksource *c) -{ - return ~(unsigned)readw_relaxed(to_mmio_clksrc(c)->reg); -} - -/** - * clocksource_mmio_init - Initialize a simple mmio based clocksource - * @base: Virtual address of the clock readout register - * @name: Name of the clocksource - * @hz: Frequency of the clocksource in Hz - * @rating: Rating of the clocksource - * @bits: Number of valid bits - * @read: One of clocksource_mmio_read*() above - */ -int __init clocksource_mmio_init(void __iomem *base, const char *name, - unsigned long hz, int rating, unsigned bits, - cycle_t (*read)(struct clocksource *)) -{ - struct clocksource_mmio *cs; - - if (bits > 32 || bits < 16) - return -EINVAL; - - cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL); - if (!cs) - return -ENOMEM; - - cs->reg = base; - cs->clksrc.name = name; - cs->clksrc.rating = rating; - cs->clksrc.read = read; - cs->clksrc.mask = CLOCKSOURCE_MASK(bits); - cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; - - return clocksource_register_hz(&cs->clksrc, hz); -} diff --git a/ANDROID_3.4.5/drivers/clocksource/scx200_hrt.c b/ANDROID_3.4.5/drivers/clocksource/scx200_hrt.c deleted file mode 100644 index 64f9e829..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/scx200_hrt.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2006 Jim Cromie - * - * This is a clocksource driver for the Geode SCx200's 1 or 27 MHz - * high-resolution timer. The Geode SC-1100 (at least) has a buggy - * time stamp counter (TSC), which loses time unless 'idle=poll' is - * given as a boot-arg. In its absence, the Generic Timekeeping code - * will detect and de-rate the bad TSC, allowing this timer to take - * over timekeeping duties. - * - * Based on work by John Stultz, and Ted Phelps (in a 2.6.12-rc6 patch) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - */ - -#include <linux/clocksource.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/ioport.h> -#include <linux/scx200.h> - -#define NAME "scx200_hrt" - -static int mhz27; -module_param(mhz27, int, 0); /* load time only */ -MODULE_PARM_DESC(mhz27, "count at 27.0 MHz (default is 1.0 MHz)"); - -static int ppm; -module_param(ppm, int, 0); /* load time only */ -MODULE_PARM_DESC(ppm, "+-adjust to actual XO freq (ppm)"); - -/* HiRes Timer configuration register address */ -#define SCx200_TMCNFG_OFFSET (SCx200_TIMER_OFFSET + 5) - -/* and config settings */ -#define HR_TMEN (1 << 0) /* timer interrupt enable */ -#define HR_TMCLKSEL (1 << 1) /* 1|0 counts at 27|1 MHz */ -#define HR_TM27MPD (1 << 2) /* 1 turns off input clock (power-down) */ - -/* The base timer frequency, * 27 if selected */ -#define HRT_FREQ 1000000 - -static cycle_t read_hrt(struct clocksource *cs) -{ - /* Read the timer value */ - return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); -} - -static struct clocksource cs_hrt = { - .name = "scx200_hrt", - .rating = 250, - .read = read_hrt, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - /* mult, shift are set based on mhz27 flag */ -}; - -static int __init init_hrt_clocksource(void) -{ - u32 freq; - /* Make sure scx200 has initialized the configuration block */ - if (!scx200_cb_present()) - return -ENODEV; - - /* Reserve the timer's ISA io-region for ourselves */ - if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET, - SCx200_TIMER_SIZE, - "NatSemi SCx200 High-Resolution Timer")) { - pr_warn("unable to lock timer region\n"); - return -ENODEV; - } - - /* write timer config */ - outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0), - scx200_cb_base + SCx200_TMCNFG_OFFSET); - - freq = (HRT_FREQ + ppm); - if (mhz27) - freq *= 27; - - pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm); - - return clocksource_register_hz(&cs_hrt, freq); -} - -module_init(init_hrt_clocksource); - -MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>"); -MODULE_DESCRIPTION("clocksource on SCx200 HiRes Timer"); -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/clocksource/sh_cmt.c b/ANDROID_3.4.5/drivers/clocksource/sh_cmt.c deleted file mode 100644 index 32fe9ef5..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/sh_cmt.c +++ /dev/null @@ -1,744 +0,0 @@ -/* - * SuperH Timer Support - CMT - * - * Copyright (C) 2008 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/delay.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/sh_timer.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/pm_domain.h> - -struct sh_cmt_priv { - void __iomem *mapbase; - struct clk *clk; - unsigned long width; /* 16 or 32 bit version of hardware block */ - unsigned long overflow_bit; - unsigned long clear_bits; - struct irqaction irqaction; - struct platform_device *pdev; - - unsigned long flags; - unsigned long match_value; - unsigned long next_match_value; - unsigned long max_match_value; - unsigned long rate; - spinlock_t lock; - struct clock_event_device ced; - struct clocksource cs; - unsigned long total_cycles; -}; - -static DEFINE_SPINLOCK(sh_cmt_lock); - -#define CMSTR -1 /* shared register */ -#define CMCSR 0 /* channel register */ -#define CMCNT 1 /* channel register */ -#define CMCOR 2 /* channel register */ - -static inline unsigned long sh_cmt_read(struct sh_cmt_priv *p, int reg_nr) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; - - if (p->width == 16) - offs <<= 1; - else { - offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) - return ioread32(base + offs); - } - - return ioread16(base + offs); -} - -static inline void sh_cmt_write(struct sh_cmt_priv *p, int reg_nr, - unsigned long value) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == CMSTR) { - offs = 0; - base -= cfg->channel_offset; - } else - offs = reg_nr; - - if (p->width == 16) - offs <<= 1; - else { - offs <<= 2; - if ((reg_nr == CMCNT) || (reg_nr == CMCOR)) { - iowrite32(value, base + offs); - return; - } - } - - iowrite16(value, base + offs); -} - -static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p, - int *has_wrapped) -{ - unsigned long v1, v2, v3; - int o1, o2; - - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; - - /* Make sure the timer value is stable. Stolen from acpi_pm.c */ - do { - o2 = o1; - v1 = sh_cmt_read(p, CMCNT); - v2 = sh_cmt_read(p, CMCNT); - v3 = sh_cmt_read(p, CMCNT); - o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit; - } while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3) - || (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2))); - - *has_wrapped = o1; - return v2; -} - - -static void sh_cmt_start_stop_ch(struct sh_cmt_priv *p, int start) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - unsigned long flags, value; - - /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_cmt_lock, flags); - value = sh_cmt_read(p, CMSTR); - - if (start) - value |= 1 << cfg->timer_bit; - else - value &= ~(1 << cfg->timer_bit); - - sh_cmt_write(p, CMSTR, value); - spin_unlock_irqrestore(&sh_cmt_lock, flags); -} - -static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) -{ - int k, ret; - - /* enable clock */ - ret = clk_enable(p->clk); - if (ret) { - dev_err(&p->pdev->dev, "cannot enable clock\n"); - goto err0; - } - - /* make sure channel is disabled */ - sh_cmt_start_stop_ch(p, 0); - - /* configure channel, periodic mode and maximum timeout */ - if (p->width == 16) { - *rate = clk_get_rate(p->clk) / 512; - sh_cmt_write(p, CMCSR, 0x43); - } else { - *rate = clk_get_rate(p->clk) / 8; - sh_cmt_write(p, CMCSR, 0x01a4); - } - - sh_cmt_write(p, CMCOR, 0xffffffff); - sh_cmt_write(p, CMCNT, 0); - - /* - * According to the sh73a0 user's manual, as CMCNT can be operated - * only by the RCLK (Pseudo 32 KHz), there's one restriction on - * modifying CMCNT register; two RCLK cycles are necessary before - * this register is either read or any modification of the value - * it holds is reflected in the LSI's actual operation. - * - * While at it, we're supposed to clear out the CMCNT as of this - * moment, so make sure it's processed properly here. This will - * take RCLKx2 at maximum. - */ - for (k = 0; k < 100; k++) { - if (!sh_cmt_read(p, CMCNT)) - break; - udelay(1); - } - - if (sh_cmt_read(p, CMCNT)) { - dev_err(&p->pdev->dev, "cannot clear CMCNT\n"); - ret = -ETIMEDOUT; - goto err1; - } - - /* enable channel */ - sh_cmt_start_stop_ch(p, 1); - return 0; - err1: - /* stop clock */ - clk_disable(p->clk); - - err0: - return ret; -} - -static void sh_cmt_disable(struct sh_cmt_priv *p) -{ - /* disable channel */ - sh_cmt_start_stop_ch(p, 0); - - /* disable interrupts in CMT block */ - sh_cmt_write(p, CMCSR, 0); - - /* stop clock */ - clk_disable(p->clk); -} - -/* private flags */ -#define FLAG_CLOCKEVENT (1 << 0) -#define FLAG_CLOCKSOURCE (1 << 1) -#define FLAG_REPROGRAM (1 << 2) -#define FLAG_SKIPEVENT (1 << 3) -#define FLAG_IRQCONTEXT (1 << 4) - -static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, - int absolute) -{ - unsigned long new_match; - unsigned long value = p->next_match_value; - unsigned long delay = 0; - unsigned long now = 0; - int has_wrapped; - - now = sh_cmt_get_counter(p, &has_wrapped); - p->flags |= FLAG_REPROGRAM; /* force reprogram */ - - if (has_wrapped) { - /* we're competing with the interrupt handler. - * -> let the interrupt handler reprogram the timer. - * -> interrupt number two handles the event. - */ - p->flags |= FLAG_SKIPEVENT; - return; - } - - if (absolute) - now = 0; - - do { - /* reprogram the timer hardware, - * but don't save the new match value yet. - */ - new_match = now + value + delay; - if (new_match > p->max_match_value) - new_match = p->max_match_value; - - sh_cmt_write(p, CMCOR, new_match); - - now = sh_cmt_get_counter(p, &has_wrapped); - if (has_wrapped && (new_match > p->match_value)) { - /* we are changing to a greater match value, - * so this wrap must be caused by the counter - * matching the old value. - * -> first interrupt reprograms the timer. - * -> interrupt number two handles the event. - */ - p->flags |= FLAG_SKIPEVENT; - break; - } - - if (has_wrapped) { - /* we are changing to a smaller match value, - * so the wrap must be caused by the counter - * matching the new value. - * -> save programmed match value. - * -> let isr handle the event. - */ - p->match_value = new_match; - break; - } - - /* be safe: verify hardware settings */ - if (now < new_match) { - /* timer value is below match value, all good. - * this makes sure we won't miss any match events. - * -> save programmed match value. - * -> let isr handle the event. - */ - p->match_value = new_match; - break; - } - - /* the counter has reached a value greater - * than our new match value. and since the - * has_wrapped flag isn't set we must have - * programmed a too close event. - * -> increase delay and retry. - */ - if (delay) - delay <<= 1; - else - delay = 1; - - if (!delay) - dev_warn(&p->pdev->dev, "too long delay\n"); - - } while (delay); -} - -static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) -{ - if (delta > p->max_match_value) - dev_warn(&p->pdev->dev, "delta out of range\n"); - - p->next_match_value = delta; - sh_cmt_clock_event_program_verify(p, 0); -} - -static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) -{ - unsigned long flags; - - spin_lock_irqsave(&p->lock, flags); - __sh_cmt_set_next(p, delta); - spin_unlock_irqrestore(&p->lock, flags); -} - -static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) -{ - struct sh_cmt_priv *p = dev_id; - - /* clear flags */ - sh_cmt_write(p, CMCSR, sh_cmt_read(p, CMCSR) & p->clear_bits); - - /* update clock source counter to begin with if enabled - * the wrap flag should be cleared by the timer specific - * isr before we end up here. - */ - if (p->flags & FLAG_CLOCKSOURCE) - p->total_cycles += p->match_value + 1; - - if (!(p->flags & FLAG_REPROGRAM)) - p->next_match_value = p->max_match_value; - - p->flags |= FLAG_IRQCONTEXT; - - if (p->flags & FLAG_CLOCKEVENT) { - if (!(p->flags & FLAG_SKIPEVENT)) { - if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) { - p->next_match_value = p->max_match_value; - p->flags |= FLAG_REPROGRAM; - } - - p->ced.event_handler(&p->ced); - } - } - - p->flags &= ~FLAG_SKIPEVENT; - - if (p->flags & FLAG_REPROGRAM) { - p->flags &= ~FLAG_REPROGRAM; - sh_cmt_clock_event_program_verify(p, 1); - - if (p->flags & FLAG_CLOCKEVENT) - if ((p->ced.mode == CLOCK_EVT_MODE_SHUTDOWN) - || (p->match_value == p->next_match_value)) - p->flags &= ~FLAG_REPROGRAM; - } - - p->flags &= ~FLAG_IRQCONTEXT; - - return IRQ_HANDLED; -} - -static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) -{ - int ret = 0; - unsigned long flags; - - spin_lock_irqsave(&p->lock, flags); - - if (!(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) - ret = sh_cmt_enable(p, &p->rate); - - if (ret) - goto out; - p->flags |= flag; - - /* setup timeout if no clockevent */ - if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) - __sh_cmt_set_next(p, p->max_match_value); - out: - spin_unlock_irqrestore(&p->lock, flags); - - return ret; -} - -static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) -{ - unsigned long flags; - unsigned long f; - - spin_lock_irqsave(&p->lock, flags); - - f = p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE); - p->flags &= ~flag; - - if (f && !(p->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) - sh_cmt_disable(p); - - /* adjust the timeout to maximum if only clocksource left */ - if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) - __sh_cmt_set_next(p, p->max_match_value); - - spin_unlock_irqrestore(&p->lock, flags); -} - -static struct sh_cmt_priv *cs_to_sh_cmt(struct clocksource *cs) -{ - return container_of(cs, struct sh_cmt_priv, cs); -} - -static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) -{ - struct sh_cmt_priv *p = cs_to_sh_cmt(cs); - unsigned long flags, raw; - unsigned long value; - int has_wrapped; - - spin_lock_irqsave(&p->lock, flags); - value = p->total_cycles; - raw = sh_cmt_get_counter(p, &has_wrapped); - - if (unlikely(has_wrapped)) - raw += p->match_value + 1; - spin_unlock_irqrestore(&p->lock, flags); - - return value + raw; -} - -static int sh_cmt_clocksource_enable(struct clocksource *cs) -{ - int ret; - struct sh_cmt_priv *p = cs_to_sh_cmt(cs); - - p->total_cycles = 0; - - ret = sh_cmt_start(p, FLAG_CLOCKSOURCE); - if (!ret) - __clocksource_updatefreq_hz(cs, p->rate); - return ret; -} - -static void sh_cmt_clocksource_disable(struct clocksource *cs) -{ - sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); -} - -static void sh_cmt_clocksource_resume(struct clocksource *cs) -{ - sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); -} - -static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, - char *name, unsigned long rating) -{ - struct clocksource *cs = &p->cs; - - cs->name = name; - cs->rating = rating; - cs->read = sh_cmt_clocksource_read; - cs->enable = sh_cmt_clocksource_enable; - cs->disable = sh_cmt_clocksource_disable; - cs->suspend = sh_cmt_clocksource_disable; - cs->resume = sh_cmt_clocksource_resume; - cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); - cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; - - dev_info(&p->pdev->dev, "used as clock source\n"); - - /* Register with dummy 1 Hz value, gets updated in ->enable() */ - clocksource_register_hz(cs, 1); - return 0; -} - -static struct sh_cmt_priv *ced_to_sh_cmt(struct clock_event_device *ced) -{ - return container_of(ced, struct sh_cmt_priv, ced); -} - -static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic) -{ - struct clock_event_device *ced = &p->ced; - - sh_cmt_start(p, FLAG_CLOCKEVENT); - - /* TODO: calculate good shift from rate and counter bit width */ - - ced->shift = 32; - ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); - ced->max_delta_ns = clockevent_delta2ns(p->max_match_value, ced); - ced->min_delta_ns = clockevent_delta2ns(0x1f, ced); - - if (periodic) - sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1); - else - sh_cmt_set_next(p, p->max_match_value); -} - -static void sh_cmt_clock_event_mode(enum clock_event_mode mode, - struct clock_event_device *ced) -{ - struct sh_cmt_priv *p = ced_to_sh_cmt(ced); - - /* deal with old setting first */ - switch (ced->mode) { - case CLOCK_EVT_MODE_PERIODIC: - case CLOCK_EVT_MODE_ONESHOT: - sh_cmt_stop(p, FLAG_CLOCKEVENT); - break; - default: - break; - } - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - dev_info(&p->pdev->dev, "used for periodic clock events\n"); - sh_cmt_clock_event_start(p, 1); - break; - case CLOCK_EVT_MODE_ONESHOT: - dev_info(&p->pdev->dev, "used for oneshot clock events\n"); - sh_cmt_clock_event_start(p, 0); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - sh_cmt_stop(p, FLAG_CLOCKEVENT); - break; - default: - break; - } -} - -static int sh_cmt_clock_event_next(unsigned long delta, - struct clock_event_device *ced) -{ - struct sh_cmt_priv *p = ced_to_sh_cmt(ced); - - BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); - if (likely(p->flags & FLAG_IRQCONTEXT)) - p->next_match_value = delta - 1; - else - sh_cmt_set_next(p, delta - 1); - - return 0; -} - -static void sh_cmt_register_clockevent(struct sh_cmt_priv *p, - char *name, unsigned long rating) -{ - struct clock_event_device *ced = &p->ced; - - memset(ced, 0, sizeof(*ced)); - - ced->name = name; - ced->features = CLOCK_EVT_FEAT_PERIODIC; - ced->features |= CLOCK_EVT_FEAT_ONESHOT; - ced->rating = rating; - ced->cpumask = cpumask_of(0); - ced->set_next_event = sh_cmt_clock_event_next; - ced->set_mode = sh_cmt_clock_event_mode; - - dev_info(&p->pdev->dev, "used for clock events\n"); - clockevents_register_device(ced); -} - -static int sh_cmt_register(struct sh_cmt_priv *p, char *name, - unsigned long clockevent_rating, - unsigned long clocksource_rating) -{ - if (p->width == (sizeof(p->max_match_value) * 8)) - p->max_match_value = ~0; - else - p->max_match_value = (1 << p->width) - 1; - - p->match_value = p->max_match_value; - spin_lock_init(&p->lock); - - if (clockevent_rating) - sh_cmt_register_clockevent(p, name, clockevent_rating); - - if (clocksource_rating) - sh_cmt_register_clocksource(p, name, clocksource_rating); - - return 0; -} - -static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) -{ - struct sh_timer_config *cfg = pdev->dev.platform_data; - struct resource *res; - int irq, ret; - ret = -ENXIO; - - memset(p, 0, sizeof(*p)); - p->pdev = pdev; - - if (!cfg) { - dev_err(&p->pdev->dev, "missing platform data\n"); - goto err0; - } - - platform_set_drvdata(pdev, p); - - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - goto err0; - } - - irq = platform_get_irq(p->pdev, 0); - if (irq < 0) { - dev_err(&p->pdev->dev, "failed to get irq\n"); - goto err0; - } - - /* map memory, let mapbase point to our channel */ - p->mapbase = ioremap_nocache(res->start, resource_size(res)); - if (p->mapbase == NULL) { - dev_err(&p->pdev->dev, "failed to remap I/O memory\n"); - goto err0; - } - - /* request irq using setup_irq() (too early for request_irq()) */ - p->irqaction.name = dev_name(&p->pdev->dev); - p->irqaction.handler = sh_cmt_interrupt; - p->irqaction.dev_id = p; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ - IRQF_IRQPOLL | IRQF_NOBALANCING; - - /* get hold of clock */ - p->clk = clk_get(&p->pdev->dev, "cmt_fck"); - if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; - } - - if (resource_size(res) == 6) { - p->width = 16; - p->overflow_bit = 0x80; - p->clear_bits = ~0x80; - } else { - p->width = 32; - p->overflow_bit = 0x8000; - p->clear_bits = ~0xc000; - } - - ret = sh_cmt_register(p, (char *)dev_name(&p->pdev->dev), - cfg->clockevent_rating, - cfg->clocksource_rating); - if (ret) { - dev_err(&p->pdev->dev, "registration failed\n"); - goto err1; - } - - ret = setup_irq(irq, &p->irqaction); - if (ret) { - dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); - goto err1; - } - - return 0; - -err1: - iounmap(p->mapbase); -err0: - return ret; -} - -static int __devinit sh_cmt_probe(struct platform_device *pdev) -{ - struct sh_cmt_priv *p = platform_get_drvdata(pdev); - int ret; - - if (!is_early_platform_device(pdev)) - pm_genpd_dev_always_on(&pdev->dev, true); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; - } - - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - return -ENOMEM; - } - - ret = sh_cmt_setup(p, pdev); - if (ret) { - kfree(p); - platform_set_drvdata(pdev, NULL); - } - return ret; -} - -static int __devexit sh_cmt_remove(struct platform_device *pdev) -{ - return -EBUSY; /* cannot unregister clockevent and clocksource */ -} - -static struct platform_driver sh_cmt_device_driver = { - .probe = sh_cmt_probe, - .remove = __devexit_p(sh_cmt_remove), - .driver = { - .name = "sh_cmt", - } -}; - -static int __init sh_cmt_init(void) -{ - return platform_driver_register(&sh_cmt_device_driver); -} - -static void __exit sh_cmt_exit(void) -{ - platform_driver_unregister(&sh_cmt_device_driver); -} - -early_platform_init("earlytimer", &sh_cmt_device_driver); -module_init(sh_cmt_init); -module_exit(sh_cmt_exit); - -MODULE_AUTHOR("Magnus Damm"); -MODULE_DESCRIPTION("SuperH CMT Timer Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/clocksource/sh_mtu2.c b/ANDROID_3.4.5/drivers/clocksource/sh_mtu2.c deleted file mode 100644 index a2172f69..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/sh_mtu2.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * SuperH Timer Support - MTU2 - * - * Copyright (C) 2009 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/clockchips.h> -#include <linux/sh_timer.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/pm_domain.h> - -struct sh_mtu2_priv { - void __iomem *mapbase; - struct clk *clk; - struct irqaction irqaction; - struct platform_device *pdev; - unsigned long rate; - unsigned long periodic; - struct clock_event_device ced; -}; - -static DEFINE_SPINLOCK(sh_mtu2_lock); - -#define TSTR -1 /* shared register */ -#define TCR 0 /* channel register */ -#define TMDR 1 /* channel register */ -#define TIOR 2 /* channel register */ -#define TIER 3 /* channel register */ -#define TSR 4 /* channel register */ -#define TCNT 5 /* channel register */ -#define TGR 6 /* channel register */ - -static unsigned long mtu2_reg_offs[] = { - [TCR] = 0, - [TMDR] = 1, - [TIOR] = 2, - [TIER] = 4, - [TSR] = 5, - [TCNT] = 6, - [TGR] = 8, -}; - -static inline unsigned long sh_mtu2_read(struct sh_mtu2_priv *p, int reg_nr) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == TSTR) - return ioread8(base + cfg->channel_offset); - - offs = mtu2_reg_offs[reg_nr]; - - if ((reg_nr == TCNT) || (reg_nr == TGR)) - return ioread16(base + offs); - else - return ioread8(base + offs); -} - -static inline void sh_mtu2_write(struct sh_mtu2_priv *p, int reg_nr, - unsigned long value) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == TSTR) { - iowrite8(value, base + cfg->channel_offset); - return; - } - - offs = mtu2_reg_offs[reg_nr]; - - if ((reg_nr == TCNT) || (reg_nr == TGR)) - iowrite16(value, base + offs); - else - iowrite8(value, base + offs); -} - -static void sh_mtu2_start_stop_ch(struct sh_mtu2_priv *p, int start) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - unsigned long flags, value; - - /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_mtu2_lock, flags); - value = sh_mtu2_read(p, TSTR); - - if (start) - value |= 1 << cfg->timer_bit; - else - value &= ~(1 << cfg->timer_bit); - - sh_mtu2_write(p, TSTR, value); - spin_unlock_irqrestore(&sh_mtu2_lock, flags); -} - -static int sh_mtu2_enable(struct sh_mtu2_priv *p) -{ - int ret; - - /* enable clock */ - ret = clk_enable(p->clk); - if (ret) { - dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; - } - - /* make sure channel is disabled */ - sh_mtu2_start_stop_ch(p, 0); - - p->rate = clk_get_rate(p->clk) / 64; - p->periodic = (p->rate + HZ/2) / HZ; - - /* "Periodic Counter Operation" */ - sh_mtu2_write(p, TCR, 0x23); /* TGRA clear, divide clock by 64 */ - sh_mtu2_write(p, TIOR, 0); - sh_mtu2_write(p, TGR, p->periodic); - sh_mtu2_write(p, TCNT, 0); - sh_mtu2_write(p, TMDR, 0); - sh_mtu2_write(p, TIER, 0x01); - - /* enable channel */ - sh_mtu2_start_stop_ch(p, 1); - - return 0; -} - -static void sh_mtu2_disable(struct sh_mtu2_priv *p) -{ - /* disable channel */ - sh_mtu2_start_stop_ch(p, 0); - - /* stop clock */ - clk_disable(p->clk); -} - -static irqreturn_t sh_mtu2_interrupt(int irq, void *dev_id) -{ - struct sh_mtu2_priv *p = dev_id; - - /* acknowledge interrupt */ - sh_mtu2_read(p, TSR); - sh_mtu2_write(p, TSR, 0xfe); - - /* notify clockevent layer */ - p->ced.event_handler(&p->ced); - return IRQ_HANDLED; -} - -static struct sh_mtu2_priv *ced_to_sh_mtu2(struct clock_event_device *ced) -{ - return container_of(ced, struct sh_mtu2_priv, ced); -} - -static void sh_mtu2_clock_event_mode(enum clock_event_mode mode, - struct clock_event_device *ced) -{ - struct sh_mtu2_priv *p = ced_to_sh_mtu2(ced); - int disabled = 0; - - /* deal with old setting first */ - switch (ced->mode) { - case CLOCK_EVT_MODE_PERIODIC: - sh_mtu2_disable(p); - disabled = 1; - break; - default: - break; - } - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - dev_info(&p->pdev->dev, "used for periodic clock events\n"); - sh_mtu2_enable(p); - break; - case CLOCK_EVT_MODE_UNUSED: - if (!disabled) - sh_mtu2_disable(p); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - default: - break; - } -} - -static void sh_mtu2_register_clockevent(struct sh_mtu2_priv *p, - char *name, unsigned long rating) -{ - struct clock_event_device *ced = &p->ced; - int ret; - - memset(ced, 0, sizeof(*ced)); - - ced->name = name; - ced->features = CLOCK_EVT_FEAT_PERIODIC; - ced->rating = rating; - ced->cpumask = cpumask_of(0); - ced->set_mode = sh_mtu2_clock_event_mode; - - dev_info(&p->pdev->dev, "used for clock events\n"); - clockevents_register_device(ced); - - ret = setup_irq(p->irqaction.irq, &p->irqaction); - if (ret) { - dev_err(&p->pdev->dev, "failed to request irq %d\n", - p->irqaction.irq); - return; - } -} - -static int sh_mtu2_register(struct sh_mtu2_priv *p, char *name, - unsigned long clockevent_rating) -{ - if (clockevent_rating) - sh_mtu2_register_clockevent(p, name, clockevent_rating); - - return 0; -} - -static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) -{ - struct sh_timer_config *cfg = pdev->dev.platform_data; - struct resource *res; - int irq, ret; - ret = -ENXIO; - - memset(p, 0, sizeof(*p)); - p->pdev = pdev; - - if (!cfg) { - dev_err(&p->pdev->dev, "missing platform data\n"); - goto err0; - } - - platform_set_drvdata(pdev, p); - - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - goto err0; - } - - irq = platform_get_irq(p->pdev, 0); - if (irq < 0) { - dev_err(&p->pdev->dev, "failed to get irq\n"); - goto err0; - } - - /* map memory, let mapbase point to our channel */ - p->mapbase = ioremap_nocache(res->start, resource_size(res)); - if (p->mapbase == NULL) { - dev_err(&p->pdev->dev, "failed to remap I/O memory\n"); - goto err0; - } - - /* setup data for setup_irq() (too early for request_irq()) */ - p->irqaction.name = dev_name(&p->pdev->dev); - p->irqaction.handler = sh_mtu2_interrupt; - p->irqaction.dev_id = p; - p->irqaction.irq = irq; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ - IRQF_IRQPOLL | IRQF_NOBALANCING; - - /* get hold of clock */ - p->clk = clk_get(&p->pdev->dev, "mtu2_fck"); - if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; - } - - return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), - cfg->clockevent_rating); - err1: - iounmap(p->mapbase); - err0: - return ret; -} - -static int __devinit sh_mtu2_probe(struct platform_device *pdev) -{ - struct sh_mtu2_priv *p = platform_get_drvdata(pdev); - int ret; - - if (!is_early_platform_device(pdev)) - pm_genpd_dev_always_on(&pdev->dev, true); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; - } - - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - return -ENOMEM; - } - - ret = sh_mtu2_setup(p, pdev); - if (ret) { - kfree(p); - platform_set_drvdata(pdev, NULL); - } - return ret; -} - -static int __devexit sh_mtu2_remove(struct platform_device *pdev) -{ - return -EBUSY; /* cannot unregister clockevent */ -} - -static struct platform_driver sh_mtu2_device_driver = { - .probe = sh_mtu2_probe, - .remove = __devexit_p(sh_mtu2_remove), - .driver = { - .name = "sh_mtu2", - } -}; - -static int __init sh_mtu2_init(void) -{ - return platform_driver_register(&sh_mtu2_device_driver); -} - -static void __exit sh_mtu2_exit(void) -{ - platform_driver_unregister(&sh_mtu2_device_driver); -} - -early_platform_init("earlytimer", &sh_mtu2_device_driver); -module_init(sh_mtu2_init); -module_exit(sh_mtu2_exit); - -MODULE_AUTHOR("Magnus Damm"); -MODULE_DESCRIPTION("SuperH MTU2 Timer Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/clocksource/sh_tmu.c b/ANDROID_3.4.5/drivers/clocksource/sh_tmu.c deleted file mode 100644 index 97f54b63..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/sh_tmu.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * SuperH Timer Support - TMU - * - * Copyright (C) 2009 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/clk.h> -#include <linux/irq.h> -#include <linux/err.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/sh_timer.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/pm_domain.h> - -struct sh_tmu_priv { - void __iomem *mapbase; - struct clk *clk; - struct irqaction irqaction; - struct platform_device *pdev; - unsigned long rate; - unsigned long periodic; - struct clock_event_device ced; - struct clocksource cs; -}; - -static DEFINE_SPINLOCK(sh_tmu_lock); - -#define TSTR -1 /* shared register */ -#define TCOR 0 /* channel register */ -#define TCNT 1 /* channel register */ -#define TCR 2 /* channel register */ - -static inline unsigned long sh_tmu_read(struct sh_tmu_priv *p, int reg_nr) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == TSTR) - return ioread8(base - cfg->channel_offset); - - offs = reg_nr << 2; - - if (reg_nr == TCR) - return ioread16(base + offs); - else - return ioread32(base + offs); -} - -static inline void sh_tmu_write(struct sh_tmu_priv *p, int reg_nr, - unsigned long value) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - void __iomem *base = p->mapbase; - unsigned long offs; - - if (reg_nr == TSTR) { - iowrite8(value, base - cfg->channel_offset); - return; - } - - offs = reg_nr << 2; - - if (reg_nr == TCR) - iowrite16(value, base + offs); - else - iowrite32(value, base + offs); -} - -static void sh_tmu_start_stop_ch(struct sh_tmu_priv *p, int start) -{ - struct sh_timer_config *cfg = p->pdev->dev.platform_data; - unsigned long flags, value; - - /* start stop register shared by multiple timer channels */ - spin_lock_irqsave(&sh_tmu_lock, flags); - value = sh_tmu_read(p, TSTR); - - if (start) - value |= 1 << cfg->timer_bit; - else - value &= ~(1 << cfg->timer_bit); - - sh_tmu_write(p, TSTR, value); - spin_unlock_irqrestore(&sh_tmu_lock, flags); -} - -static int sh_tmu_enable(struct sh_tmu_priv *p) -{ - int ret; - - /* enable clock */ - ret = clk_enable(p->clk); - if (ret) { - dev_err(&p->pdev->dev, "cannot enable clock\n"); - return ret; - } - - /* make sure channel is disabled */ - sh_tmu_start_stop_ch(p, 0); - - /* maximum timeout */ - sh_tmu_write(p, TCOR, 0xffffffff); - sh_tmu_write(p, TCNT, 0xffffffff); - - /* configure channel to parent clock / 4, irq off */ - p->rate = clk_get_rate(p->clk) / 4; - sh_tmu_write(p, TCR, 0x0000); - - /* enable channel */ - sh_tmu_start_stop_ch(p, 1); - - return 0; -} - -static void sh_tmu_disable(struct sh_tmu_priv *p) -{ - /* disable channel */ - sh_tmu_start_stop_ch(p, 0); - - /* disable interrupts in TMU block */ - sh_tmu_write(p, TCR, 0x0000); - - /* stop clock */ - clk_disable(p->clk); -} - -static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, - int periodic) -{ - /* stop timer */ - sh_tmu_start_stop_ch(p, 0); - - /* acknowledge interrupt */ - sh_tmu_read(p, TCR); - - /* enable interrupt */ - sh_tmu_write(p, TCR, 0x0020); - - /* reload delta value in case of periodic timer */ - if (periodic) - sh_tmu_write(p, TCOR, delta); - else - sh_tmu_write(p, TCOR, 0xffffffff); - - sh_tmu_write(p, TCNT, delta); - - /* start timer */ - sh_tmu_start_stop_ch(p, 1); -} - -static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id) -{ - struct sh_tmu_priv *p = dev_id; - - /* disable or acknowledge interrupt */ - if (p->ced.mode == CLOCK_EVT_MODE_ONESHOT) - sh_tmu_write(p, TCR, 0x0000); - else - sh_tmu_write(p, TCR, 0x0020); - - /* notify clockevent layer */ - p->ced.event_handler(&p->ced); - return IRQ_HANDLED; -} - -static struct sh_tmu_priv *cs_to_sh_tmu(struct clocksource *cs) -{ - return container_of(cs, struct sh_tmu_priv, cs); -} - -static cycle_t sh_tmu_clocksource_read(struct clocksource *cs) -{ - struct sh_tmu_priv *p = cs_to_sh_tmu(cs); - - return sh_tmu_read(p, TCNT) ^ 0xffffffff; -} - -static int sh_tmu_clocksource_enable(struct clocksource *cs) -{ - struct sh_tmu_priv *p = cs_to_sh_tmu(cs); - int ret; - - ret = sh_tmu_enable(p); - if (!ret) - __clocksource_updatefreq_hz(cs, p->rate); - return ret; -} - -static void sh_tmu_clocksource_disable(struct clocksource *cs) -{ - sh_tmu_disable(cs_to_sh_tmu(cs)); -} - -static int sh_tmu_register_clocksource(struct sh_tmu_priv *p, - char *name, unsigned long rating) -{ - struct clocksource *cs = &p->cs; - - cs->name = name; - cs->rating = rating; - cs->read = sh_tmu_clocksource_read; - cs->enable = sh_tmu_clocksource_enable; - cs->disable = sh_tmu_clocksource_disable; - cs->mask = CLOCKSOURCE_MASK(32); - cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; - - dev_info(&p->pdev->dev, "used as clock source\n"); - - /* Register with dummy 1 Hz value, gets updated in ->enable() */ - clocksource_register_hz(cs, 1); - return 0; -} - -static struct sh_tmu_priv *ced_to_sh_tmu(struct clock_event_device *ced) -{ - return container_of(ced, struct sh_tmu_priv, ced); -} - -static void sh_tmu_clock_event_start(struct sh_tmu_priv *p, int periodic) -{ - struct clock_event_device *ced = &p->ced; - - sh_tmu_enable(p); - - /* TODO: calculate good shift from rate and counter bit width */ - - ced->shift = 32; - ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift); - ced->max_delta_ns = clockevent_delta2ns(0xffffffff, ced); - ced->min_delta_ns = 5000; - - if (periodic) { - p->periodic = (p->rate + HZ/2) / HZ; - sh_tmu_set_next(p, p->periodic, 1); - } -} - -static void sh_tmu_clock_event_mode(enum clock_event_mode mode, - struct clock_event_device *ced) -{ - struct sh_tmu_priv *p = ced_to_sh_tmu(ced); - int disabled = 0; - - /* deal with old setting first */ - switch (ced->mode) { - case CLOCK_EVT_MODE_PERIODIC: - case CLOCK_EVT_MODE_ONESHOT: - sh_tmu_disable(p); - disabled = 1; - break; - default: - break; - } - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - dev_info(&p->pdev->dev, "used for periodic clock events\n"); - sh_tmu_clock_event_start(p, 1); - break; - case CLOCK_EVT_MODE_ONESHOT: - dev_info(&p->pdev->dev, "used for oneshot clock events\n"); - sh_tmu_clock_event_start(p, 0); - break; - case CLOCK_EVT_MODE_UNUSED: - if (!disabled) - sh_tmu_disable(p); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - default: - break; - } -} - -static int sh_tmu_clock_event_next(unsigned long delta, - struct clock_event_device *ced) -{ - struct sh_tmu_priv *p = ced_to_sh_tmu(ced); - - BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); - - /* program new delta value */ - sh_tmu_set_next(p, delta, 0); - return 0; -} - -static void sh_tmu_register_clockevent(struct sh_tmu_priv *p, - char *name, unsigned long rating) -{ - struct clock_event_device *ced = &p->ced; - int ret; - - memset(ced, 0, sizeof(*ced)); - - ced->name = name; - ced->features = CLOCK_EVT_FEAT_PERIODIC; - ced->features |= CLOCK_EVT_FEAT_ONESHOT; - ced->rating = rating; - ced->cpumask = cpumask_of(0); - ced->set_next_event = sh_tmu_clock_event_next; - ced->set_mode = sh_tmu_clock_event_mode; - - dev_info(&p->pdev->dev, "used for clock events\n"); - clockevents_register_device(ced); - - ret = setup_irq(p->irqaction.irq, &p->irqaction); - if (ret) { - dev_err(&p->pdev->dev, "failed to request irq %d\n", - p->irqaction.irq); - return; - } -} - -static int sh_tmu_register(struct sh_tmu_priv *p, char *name, - unsigned long clockevent_rating, - unsigned long clocksource_rating) -{ - if (clockevent_rating) - sh_tmu_register_clockevent(p, name, clockevent_rating); - else if (clocksource_rating) - sh_tmu_register_clocksource(p, name, clocksource_rating); - - return 0; -} - -static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) -{ - struct sh_timer_config *cfg = pdev->dev.platform_data; - struct resource *res; - int irq, ret; - ret = -ENXIO; - - memset(p, 0, sizeof(*p)); - p->pdev = pdev; - - if (!cfg) { - dev_err(&p->pdev->dev, "missing platform data\n"); - goto err0; - } - - platform_set_drvdata(pdev, p); - - res = platform_get_resource(p->pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&p->pdev->dev, "failed to get I/O memory\n"); - goto err0; - } - - irq = platform_get_irq(p->pdev, 0); - if (irq < 0) { - dev_err(&p->pdev->dev, "failed to get irq\n"); - goto err0; - } - - /* map memory, let mapbase point to our channel */ - p->mapbase = ioremap_nocache(res->start, resource_size(res)); - if (p->mapbase == NULL) { - dev_err(&p->pdev->dev, "failed to remap I/O memory\n"); - goto err0; - } - - /* setup data for setup_irq() (too early for request_irq()) */ - p->irqaction.name = dev_name(&p->pdev->dev); - p->irqaction.handler = sh_tmu_interrupt; - p->irqaction.dev_id = p; - p->irqaction.irq = irq; - p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | \ - IRQF_IRQPOLL | IRQF_NOBALANCING; - - /* get hold of clock */ - p->clk = clk_get(&p->pdev->dev, "tmu_fck"); - if (IS_ERR(p->clk)) { - dev_err(&p->pdev->dev, "cannot get clock\n"); - ret = PTR_ERR(p->clk); - goto err1; - } - - return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), - cfg->clockevent_rating, - cfg->clocksource_rating); - err1: - iounmap(p->mapbase); - err0: - return ret; -} - -static int __devinit sh_tmu_probe(struct platform_device *pdev) -{ - struct sh_tmu_priv *p = platform_get_drvdata(pdev); - int ret; - - if (!is_early_platform_device(pdev)) - pm_genpd_dev_always_on(&pdev->dev, true); - - if (p) { - dev_info(&pdev->dev, "kept as earlytimer\n"); - return 0; - } - - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - return -ENOMEM; - } - - ret = sh_tmu_setup(p, pdev); - if (ret) { - kfree(p); - platform_set_drvdata(pdev, NULL); - } - return ret; -} - -static int __devexit sh_tmu_remove(struct platform_device *pdev) -{ - return -EBUSY; /* cannot unregister clockevent and clocksource */ -} - -static struct platform_driver sh_tmu_device_driver = { - .probe = sh_tmu_probe, - .remove = __devexit_p(sh_tmu_remove), - .driver = { - .name = "sh_tmu", - } -}; - -static int __init sh_tmu_init(void) -{ - return platform_driver_register(&sh_tmu_device_driver); -} - -static void __exit sh_tmu_exit(void) -{ - platform_driver_unregister(&sh_tmu_device_driver); -} - -early_platform_init("earlytimer", &sh_tmu_device_driver); -module_init(sh_tmu_init); -module_exit(sh_tmu_exit); - -MODULE_AUTHOR("Magnus Damm"); -MODULE_DESCRIPTION("SuperH TMU Timer Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/ANDROID_3.4.5/drivers/clocksource/tcb_clksrc.c b/ANDROID_3.4.5/drivers/clocksource/tcb_clksrc.c deleted file mode 100644 index 32cb929b..00000000 --- a/ANDROID_3.4.5/drivers/clocksource/tcb_clksrc.c +++ /dev/null @@ -1,334 +0,0 @@ -#include <linux/init.h> -#include <linux/clocksource.h> -#include <linux/clockchips.h> -#include <linux/interrupt.h> -#include <linux/irq.h> - -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/ioport.h> -#include <linux/io.h> -#include <linux/platform_device.h> -#include <linux/atmel_tc.h> - - -/* - * We're configured to use a specific TC block, one that's not hooked - * up to external hardware, to provide a time solution: - * - * - Two channels combine to create a free-running 32 bit counter - * with a base rate of 5+ MHz, packaged as a clocksource (with - * resolution better than 200 nsec). - * - Some chips support 32 bit counter. A single channel is used for - * this 32 bit free-running counter. the second channel is not used. - * - * - The third channel may be used to provide a 16-bit clockevent - * source, used in either periodic or oneshot mode. This runs - * at 32 KiHZ, and can handle delays of up to two seconds. - * - * A boot clocksource and clockevent source are also currently needed, - * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so - * this code can be used when init_timers() is called, well before most - * devices are set up. (Some low end AT91 parts, which can run uClinux, - * have only the timers in one TC block... they currently don't support - * the tclib code, because of that initialization issue.) - * - * REVISIT behavior during system suspend states... we should disable - * all clocks and save the power. Easily done for clockevent devices, - * but clocksources won't necessarily get the needed notifications. - * For deeper system sleep states, this will be mandatory... - */ - -static void __iomem *tcaddr; - -static cycle_t tc_get_cycles(struct clocksource *cs) -{ - unsigned long flags; - u32 lower, upper; - - raw_local_irq_save(flags); - do { - upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)); - lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); - } while (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV))); - - raw_local_irq_restore(flags); - return (upper << 16) | lower; -} - -static cycle_t tc_get_cycles32(struct clocksource *cs) -{ - return __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); -} - -static struct clocksource clksrc = { - .name = "tcb_clksrc", - .rating = 200, - .read = tc_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -#ifdef CONFIG_GENERIC_CLOCKEVENTS - -struct tc_clkevt_device { - struct clock_event_device clkevt; - struct clk *clk; - void __iomem *regs; -}; - -static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) -{ - return container_of(clkevt, struct tc_clkevt_device, clkevt); -} - -/* For now, we always use the 32K clock ... this optimizes for NO_HZ, - * because using one of the divided clocks would usually mean the - * tick rate can never be less than several dozen Hz (vs 0.5 Hz). - * - * A divided clock could be good for high resolution timers, since - * 30.5 usec resolution can seem "low". - */ -static u32 timer_clock; - -static void tc_mode(enum clock_event_mode m, struct clock_event_device *d) -{ - struct tc_clkevt_device *tcd = to_tc_clkevt(d); - void __iomem *regs = tcd->regs; - - if (tcd->clkevt.mode == CLOCK_EVT_MODE_PERIODIC - || tcd->clkevt.mode == CLOCK_EVT_MODE_ONESHOT) { - __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); - __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); - clk_disable(tcd->clk); - } - - switch (m) { - - /* By not making the gentime core emulate periodic mode on top - * of oneshot, we get lower overhead and improved accuracy. - */ - case CLOCK_EVT_MODE_PERIODIC: - clk_enable(tcd->clk); - - /* slow clock, count up to RC, then irq and restart */ - __raw_writel(timer_clock - | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, - regs + ATMEL_TC_REG(2, CMR)); - __raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); - - /* Enable clock and interrupts on RC compare */ - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); - - /* go go gadget! */ - __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, - regs + ATMEL_TC_REG(2, CCR)); - break; - - case CLOCK_EVT_MODE_ONESHOT: - clk_enable(tcd->clk); - - /* slow clock, count up to RC, then irq and stop */ - __raw_writel(timer_clock | ATMEL_TC_CPCSTOP - | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, - regs + ATMEL_TC_REG(2, CMR)); - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); - - /* set_next_event() configures and starts the timer */ - break; - - default: - break; - } -} - -static int tc_next_event(unsigned long delta, struct clock_event_device *d) -{ - __raw_writel(delta, tcaddr + ATMEL_TC_REG(2, RC)); - - /* go go gadget! */ - __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, - tcaddr + ATMEL_TC_REG(2, CCR)); - return 0; -} - -static struct tc_clkevt_device clkevt = { - .clkevt = { - .name = "tc_clkevt", - .features = CLOCK_EVT_FEAT_PERIODIC - | CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - /* Should be lower than at91rm9200's system timer */ - .rating = 125, - .set_next_event = tc_next_event, - .set_mode = tc_mode, - }, -}; - -static irqreturn_t ch2_irq(int irq, void *handle) -{ - struct tc_clkevt_device *dev = handle; - unsigned int sr; - - sr = __raw_readl(dev->regs + ATMEL_TC_REG(2, SR)); - if (sr & ATMEL_TC_CPCS) { - dev->clkevt.event_handler(&dev->clkevt); - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static struct irqaction tc_irqaction = { - .name = "tc_clkevt", - .flags = IRQF_TIMER | IRQF_DISABLED, - .handler = ch2_irq, -}; - -static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) -{ - struct clk *t2_clk = tc->clk[2]; - int irq = tc->irq[2]; - - clkevt.regs = tc->regs; - clkevt.clk = t2_clk; - tc_irqaction.dev_id = &clkevt; - - timer_clock = clk32k_divisor_idx; - - clkevt.clkevt.mult = div_sc(32768, NSEC_PER_SEC, clkevt.clkevt.shift); - clkevt.clkevt.max_delta_ns - = clockevent_delta2ns(0xffff, &clkevt.clkevt); - clkevt.clkevt.min_delta_ns = clockevent_delta2ns(1, &clkevt.clkevt) + 1; - clkevt.clkevt.cpumask = cpumask_of(0); - - clockevents_register_device(&clkevt.clkevt); - - setup_irq(irq, &tc_irqaction); -} - -#else /* !CONFIG_GENERIC_CLOCKEVENTS */ - -static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) -{ - /* NOTHING */ -} - -#endif - -static void __init tcb_setup_dual_chan(struct atmel_tc *tc, int mck_divisor_idx) -{ - /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ - __raw_writel(mck_divisor_idx /* likely divide-by-8 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP /* free-run */ - | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ - | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ - tcaddr + ATMEL_TC_REG(0, CMR)); - __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); - __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); - __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ - __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); - - /* channel 1: waveform mode, input TIOA0 */ - __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP, /* free-run */ - tcaddr + ATMEL_TC_REG(1, CMR)); - __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ - __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); - - /* chain channel 0 to channel 1*/ - __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); - /* then reset all the timers */ - __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); -} - -static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_idx) -{ - /* channel 0: waveform mode, input mclk/8 */ - __raw_writel(mck_divisor_idx /* likely divide-by-8 */ - | ATMEL_TC_WAVE - | ATMEL_TC_WAVESEL_UP, /* free-run */ - tcaddr + ATMEL_TC_REG(0, CMR)); - __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ - __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); - - /* then reset all the timers */ - __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); -} - -static int __init tcb_clksrc_init(void) -{ - static char bootinfo[] __initdata - = KERN_DEBUG "%s: tc%d at %d.%03d MHz\n"; - - struct platform_device *pdev; - struct atmel_tc *tc; - struct clk *t0_clk; - u32 rate, divided_rate = 0; - int best_divisor_idx = -1; - int clk32k_divisor_idx = -1; - int i; - - tc = atmel_tc_alloc(CONFIG_ATMEL_TCB_CLKSRC_BLOCK, clksrc.name); - if (!tc) { - pr_debug("can't alloc TC for clocksource\n"); - return -ENODEV; - } - tcaddr = tc->regs; - pdev = tc->pdev; - - t0_clk = tc->clk[0]; - clk_enable(t0_clk); - - /* How fast will we be counting? Pick something over 5 MHz. */ - rate = (u32) clk_get_rate(t0_clk); - for (i = 0; i < 5; i++) { - unsigned divisor = atmel_tc_divisors[i]; - unsigned tmp; - - /* remember 32 KiHz clock for later */ - if (!divisor) { - clk32k_divisor_idx = i; - continue; - } - - tmp = rate / divisor; - pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); - if (best_divisor_idx > 0) { - if (tmp < 5 * 1000 * 1000) - continue; - } - divided_rate = tmp; - best_divisor_idx = i; - } - - - printk(bootinfo, clksrc.name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK, - divided_rate / 1000000, - ((divided_rate + 500000) % 1000000) / 1000); - - if (tc->tcb_config && tc->tcb_config->counter_width == 32) { - /* use apropriate function to read 32 bit counter */ - clksrc.read = tc_get_cycles32; - /* setup ony channel 0 */ - tcb_setup_single_chan(tc, best_divisor_idx); - } else { - /* tclib will give us three clocks no matter what the - * underlying platform supports. - */ - clk_enable(tc->clk[1]); - /* setup both channel 0 & 1 */ - tcb_setup_dual_chan(tc, best_divisor_idx); - } - - /* and away we go! */ - clocksource_register_hz(&clksrc, divided_rate); - - /* channel 2: periodic and oneshot timer support */ - setup_clkevents(tc, clk32k_divisor_idx); - - return 0; -} -arch_initcall(tcb_clksrc_init); |