Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/acpi/acpi_cmos_rtc.c

  1 /*
  2  * ACPI support for CMOS RTC Address Space access
  3  *
  4  * Copyright (C) 2013, Intel Corporation
  5  * Authors: Lan Tianyu <tianyu.lan@intel.com>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License version 2 as
  9  * published by the Free Software Foundation.
 10  */
 11 
 12 #include <linux/acpi.h>
 13 #include <linux/device.h>
 14 #include <linux/err.h>
 15 #include <linux/kernel.h>
 16 #include <linux/module.h>
 17 #include <asm-generic/rtc.h>
 18 
 19 #include "internal.h"
 20 
 21 ACPI_MODULE_NAME("cmos rtc");
 22 
 23 static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
 24         { "PNP0B00" },
 25         { "PNP0B01" },
 26         { "PNP0B02" },
 27         {}
 28 };
 29 
 30 static acpi_status
 31 acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
 32                       u32 bits, u64 *value64,
 33                       void *handler_context, void *region_context)
 34 {
 35         int i;
 36         u8 *value = (u8 *)&value64;
 37 
 38         if (address > 0xff || !value64)
 39                 return AE_BAD_PARAMETER;
 40 
 41         if (function != ACPI_WRITE && function != ACPI_READ)
 42                 return AE_BAD_PARAMETER;
 43 
 44         spin_lock_irq(&rtc_lock);
 45 
 46         for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
 47                 if (function == ACPI_READ)
 48                         *value = CMOS_READ(address);
 49                 else
 50                         CMOS_WRITE(*value, address);
 51 
 52         spin_unlock_irq(&rtc_lock);
 53 
 54         return AE_OK;
 55 }
 56 
 57 static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
 58                 const struct acpi_device_id *id)
 59 {
 60         acpi_status status;
 61 
 62         status = acpi_install_address_space_handler(adev->handle,
 63                         ACPI_ADR_SPACE_CMOS,
 64                         &acpi_cmos_rtc_space_handler,
 65                         NULL, NULL);
 66         if (ACPI_FAILURE(status)) {
 67                 pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
 68                 return -ENODEV;
 69         }
 70 
 71         return 1;
 72 }
 73 
 74 static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
 75 {
 76         if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
 77                         ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
 78                 pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
 79 }
 80 
 81 static struct acpi_scan_handler cmos_rtc_handler = {
 82         .ids = acpi_cmos_rtc_ids,
 83         .attach = acpi_install_cmos_rtc_space_handler,
 84         .detach = acpi_remove_cmos_rtc_space_handler,
 85 };
 86 
 87 void __init acpi_cmos_rtc_init(void)
 88 {
 89         acpi_scan_add_handler(&cmos_rtc_handler);
 90 }
 91 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us