cregit-Linux how code gets into the kernel

Release 4.14 arch/x86/kernel/rtc.c

Directory: arch/x86/kernel
// SPDX-License-Identifier: GPL-2.0
/*
 * RTC related functions
 */
#include <linux/platform_device.h>
#include <linux/mc146818rtc.h>
#include <linux/acpi.h>
#include <linux/bcd.h>
#include <linux/export.h>
#include <linux/pnp.h>
#include <linux/of.h>

#include <asm/vsyscall.h>
#include <asm/x86_init.h>
#include <asm/time.h>
#include <asm/intel-mid.h>
#include <asm/setup.h>

#ifdef CONFIG_X86_32
/*
 * This is a special lock that is owned by the CPU and holds the index
 * register we are working with.  It is required for NMI access to the
 * CMOS/RTC registers.  See include/asm-i386/mc146818rtc.h for details.
 */

volatile unsigned long cmos_lock;

EXPORT_SYMBOL(cmos_lock);
#endif /* CONFIG_X86_32 */

/* For two digit years assume time is always after that */

#define CMOS_YEARS_OFFS 2000


DEFINE_SPINLOCK(rtc_lock);

EXPORT_SYMBOL(rtc_lock);

/*
 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
 * called 500 ms after the second nowtime has started, because when
 * nowtime is written into the registers of the CMOS clock, it will
 * jump to the next second precisely 500 ms later. Check the Motorola
 * MC146818A or Dallas DS12887 data sheet for details.
 */

int mach_set_rtc_mmss(const struct timespec *now) { unsigned long nowtime = now->tv_sec; struct rtc_time tm; int retval = 0; rtc_time_to_tm(nowtime, &tm); if (!rtc_valid_tm(&tm)) { retval = mc146818_set_time(&tm); if (retval) printk(KERN_ERR "%s: RTC write failed with error %d\n", __func__, retval); } else { printk(KERN_ERR "%s: Invalid RTC value: write of %lx to RTC failed\n", __func__, nowtime); retval = -EINVAL; } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
Alan Cox4347.78%112.50%
Prarit Bhargava2527.78%112.50%
David Vrabel1213.33%112.50%
Jaswinder Singh Rajput55.56%112.50%
Rasmus Villemoes22.22%112.50%
Arnd Bergmann11.11%112.50%
Adrian Bunk11.11%112.50%
Matt Fleming11.11%112.50%
Total90100.00%8100.00%


void mach_get_cmos_time(struct timespec *now) { unsigned int status, year, mon, day, hour, min, sec, century = 0; unsigned long flags; /* * If pm_trace abused the RTC as storage, set the timespec to 0, * which tells the caller that this RTC value is unusable. */ if (!pm_trace_rtc_valid()) { now->tv_sec = now->tv_nsec = 0; return; } spin_lock_irqsave(&rtc_lock, flags); /* * If UIP is clear, then we have >= 244 microseconds before * RTC registers will be updated. Spec sheet says that this * is the reliable way to read RTC - registers. If UIP is set * then the register access might be invalid. */ while ((CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) cpu_relax(); sec = CMOS_READ(RTC_SECONDS); min = CMOS_READ(RTC_MINUTES); hour = CMOS_READ(RTC_HOURS); day = CMOS_READ(RTC_DAY_OF_MONTH); mon = CMOS_READ(RTC_MONTH); year = CMOS_READ(RTC_YEAR); #ifdef CONFIG_ACPI if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID && acpi_gbl_FADT.century) century = CMOS_READ(acpi_gbl_FADT.century); #endif status = CMOS_READ(RTC_CONTROL); WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY)); spin_unlock_irqrestore(&rtc_lock, flags); if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) { sec = bcd2bin(sec); min = bcd2bin(min); hour = bcd2bin(hour); day = bcd2bin(day); mon = bcd2bin(mon); year = bcd2bin(year); } if (century) { century = bcd2bin(century); year += century * 100; } else year += CMOS_YEARS_OFFS; now->tv_sec = mktime(year, mon, day, hour, min, sec); now->tv_nsec = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen8831.77%225.00%
Alan Cox7025.27%112.50%
Thomas Gleixner4215.16%112.50%
Adrian Bunk217.58%112.50%
Matt Fleming207.22%112.50%
Chen Yu207.22%112.50%
David Vrabel165.78%112.50%
Total277100.00%8100.00%

/* Routines for accessing the CMOS RAM/RTC. */
unsigned char rtc_cmos_read(unsigned char addr) { unsigned char val; lock_cmos_prefix(addr); outb(addr, RTC_PORT(0)); val = inb(RTC_PORT(1)); lock_cmos_suffix(addr); return val; }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen4391.49%133.33%
Thomas Gleixner24.26%133.33%
David P. Reed24.26%133.33%
Total47100.00%3100.00%

EXPORT_SYMBOL(rtc_cmos_read);
void rtc_cmos_write(unsigned char val, unsigned char addr) { lock_cmos_prefix(addr); outb(addr, RTC_PORT(0)); outb(val, RTC_PORT(1)); lock_cmos_suffix(addr); }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen3990.70%133.33%
Thomas Gleixner24.65%133.33%
David P. Reed24.65%133.33%
Total43100.00%3100.00%

EXPORT_SYMBOL(rtc_cmos_write);
int update_persistent_clock(struct timespec now) { return x86_platform.set_wallclock(&now); }

Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen950.00%125.00%
Feng Tang738.89%125.00%
David Vrabel15.56%125.00%
Matt Fleming15.56%125.00%
Total18100.00%4100.00%

/* not static: needed by APM */
void read_persistent_clock(struct timespec *ts) { x86_platform.get_wallclock(ts); }

Contributors

PersonTokensPropCommitsCommitProp
Martin Schwidefsky741.18%125.00%
Andi Kleen635.29%125.00%
Feng Tang211.76%125.00%
David Vrabel211.76%125.00%
Total17100.00%4100.00%

static struct resource rtc_resources[] = { [0] = { .start = RTC_PORT(0), .end = RTC_PORT(1), .flags = IORESOURCE_IO, }, [1] = { .start = RTC_IRQ, .end = RTC_IRQ, .flags = IORESOURCE_IRQ, } }; static struct platform_device rtc_device = { .name = "rtc_cmos", .id = -1, .resource = rtc_resources, .num_resources = ARRAY_SIZE(rtc_resources), };
static __init int add_rtc_cmos(void) { #ifdef CONFIG_PNP static const char * const ids[] __initconst = { "PNP0b00", "PNP0b01", "PNP0b02", }; struct pnp_dev *dev; struct pnp_id *id; int i; pnp_for_each_dev(dev) { for (id = dev->id; id; id = id->next) { for (i = 0; i < ARRAY_SIZE(ids); i++) { if (compare_pnp_id(id, ids[i]) != 0) return 0; } } } #endif if (!x86_platform.legacy.rtc) return -ENODEV; platform_device_register(&rtc_device); dev_info(&rtc_device.dev, "registered platform RTC device (no PNP device found)\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Björn Helgaas9268.15%116.67%
Stas Sergeev2921.48%116.67%
David Vrabel64.44%116.67%
Luis R. Rodriguez53.70%116.67%
Sebastian Andrzej Siewior21.48%116.67%
Andi Kleen10.74%116.67%
Total135100.00%6100.00%

device_initcall(add_rtc_cmos);

Overall Contributors

PersonTokensPropCommitsCommitProp
Andi Kleen19924.81%414.29%
Stas Sergeev12615.71%13.57%
Alan Cox11514.34%13.57%
Björn Helgaas9211.47%13.57%
Thomas Gleixner8310.35%27.14%
David Vrabel374.61%27.14%
Prarit Bhargava283.49%13.57%
Matt Fleming222.74%13.57%
Adrian Bunk222.74%13.57%
Chen Yu202.49%13.57%
Feng Tang121.50%13.57%
Jaswinder Singh Rajput121.50%13.57%
Martin Schwidefsky70.87%13.57%
Luis R. Rodriguez60.75%13.57%
Sebastian Andrzej Siewior50.62%13.57%
David P. Reed40.50%13.57%
Paul Gortmaker30.37%13.57%
Mathias Nyman20.25%13.57%
Rasmus Villemoes20.25%13.57%
Ingo Molnar20.25%13.57%
Kuppuswamy Sathyanarayanan10.12%13.57%
Greg Kroah-Hartman10.12%13.57%
Arnd Bergmann10.12%13.57%
Total802100.00%28100.00%
Directory: arch/x86/kernel
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.