Re: [PATCH] ACPI: add a dummy ACPI RTC driver to handle BIOS's accesses to registers delcared in OperationRegion.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wednesday, January 16, 2013 11:15:25 AM Alex Hung wrote:
> This is to fix acpica returns an error and terminate AML execution as
> soon as BIOS tries to access ACPI's RTC registers.
> 
> BugLink: http://launchpad.net/bugs/1065066

Can you please describe the problem in more detail in the changelog itself?
Providing a link to the bug report doesn't explain why you think this fix
is the best possible one.  Which quite frankly I'm not sure of.

> Signed-off-by: Alex Hung <alex.hung@xxxxxxxxxxxxx>
> ---
>  drivers/acpi/Kconfig    |    9 +++
>  drivers/acpi/Makefile   |    1 +
>  drivers/acpi/acpi_rtc.c |  140 +++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 150 insertions(+)
>  create mode 100644 drivers/acpi/acpi_rtc.c
> 
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 38c5078..fb90397 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -181,6 +181,15 @@ config ACPI_DOCK
>  	  This driver supports ACPI-controlled docking stations and removable
>  	  drive bays such as the IBM Ultrabay and the Dell Module Bay.
>  
> +config ACPI_RTC
> +	tristate "RTC"
> +	default m
> +	help
> +	  This driver supports an ACPI RTC device. It enables BIOS to read and
> +	  to write ACPI RTC registers declared in an OperationRegion with
> +	  RegionSpace as SYSTEMCMOS. This is required if BIOS needs to access
> +	  RTC registers during run-time such as a number of HP laptops.
> +
>  config ACPI_I2C
>  	def_tristate I2C
>  	depends on I2C
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 2a4502b..383c62b 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -71,6 +71,7 @@ obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
>  obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_I2C)		+= acpi_i2c.o
> +obj-$(CONFIG_ACPI_RTC)          += acpi_rtc.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o processor_throttling.o
> diff --git a/drivers/acpi/acpi_rtc.c b/drivers/acpi/acpi_rtc.c
> new file mode 100644
> index 0000000..0ddcfc8
> --- /dev/null
> +++ b/drivers/acpi/acpi_rtc.c
> @@ -0,0 +1,140 @@
> +/*
> + *  acpi_rtc - ACPI RTC Driver
> + *
> + *  Copyright (C) 2013 Alex Hung <alex.hung@xxxxxxxxxxxxx>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + *
> + *  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.
> + *
> + *  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/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/pci.h>
> +#include <linux/acpi.h>
> +#include <acpi/acpi_bus.h>
> +#include <acpi/acpi_drivers.h>
> +#include <linux/miscdevice.h>
> +
> +#define pr_fmt(fmt) "acpi_rtc: " fmt
> +
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("acpi*:PNP0B00:*");
> +
> +static const struct acpi_device_id rtc_device_ids[] = {
> +	{"PNP0B00", 0},
> +	{"", 0},
> +};
> +
> +static acpi_status acpi_acpi_handle_locate_callback(acpi_handle handle,
> +			u32 level, void *context, void **return_value)
> +{
> +	struct acpi_device *dev = context;
> +	dev->handle = handle;
> +
> +	return AE_CTRL_TERMINATE;
> +}
> +
> +static acpi_status
> +acpi_rtc_space_handler(u32 function, acpi_physical_address address,
> +		      u32 bits, u64 *value64,
> +		      void *handler_context, void *region_context)
> +{
> +	return AE_OK;
> +}
> +
> +static int rtc_install_handlers(struct acpi_device *rtc_dev)
> +{
> +	acpi_status status;
> +	status = acpi_install_address_space_handler(rtc_dev->handle,
> +						    ACPI_ADR_SPACE_CMOS,
> +						    &acpi_rtc_space_handler,
> +						    NULL, rtc_dev);
> +	if (ACPI_FAILURE(status)) {
> +		pr_info("Fail to install ACPI RTC handler\n");
> +		return AE_ERROR;
> +	}
> +
> +	return 0;
> +}
> +
> +static int acpi_rtc_add(struct acpi_device *device)
> +{
> +	int ret;
> +	acpi_status status;
> +	acpi_handle rtc_dev;
> +
> +	status = acpi_get_devices(rtc_device_ids[0].id,
> +				  acpi_acpi_handle_locate_callback,
> +				  &rtc_dev, &rtc_dev);
> +	if (!ACPI_SUCCESS(status))
> +		return AE_NOT_FOUND;
> +
> +	ret = rtc_install_handlers((struct acpi_device *) &rtc_dev);
> +
> +	return ret;
> +}
> +
> +static int acpi_rtc_remove(struct acpi_device *device, int type)
> +{
> +	acpi_status status;
> +	status = acpi_remove_address_space_handler(device->handle,
> +						   ACPI_ADR_SPACE_CMOS,
> +						   &acpi_rtc_space_handler);
> +	if (!ACPI_SUCCESS(status))
> +		return AE_ERROR;
> +
> +	return AE_OK;
> +}
> +
> +static struct acpi_driver acpi_rtc_driver = {
> +	.name = "rtc",
> +	.class = "ACPI_RTC_CLASS",
> +	.ids = rtc_device_ids,
> +	.ops = {
> +		.add = acpi_rtc_add,
> +		.remove = acpi_rtc_remove,
> +		},
> +};
> +
> +static int __init rtc_init(void)
> +{
> +	int err;
> +
> +	pr_info("Initializing ACPI RTC module\n");
> +	err = acpi_bus_register_driver(&acpi_rtc_driver);
> +	if (err) {
> +		pr_err("Unable to register acpi driver.\n");
> +		goto error_acpi_register;
> +	}
> +
> +	return 0;
> +
> +error_acpi_register:
> +
> +	return err;
> +}
> +
> +static void __exit rtc_exit(void)
> +{
> +	pr_info("Exiting ACPI RTC module\n");
> +	acpi_bus_unregister_driver(&acpi_rtc_driver);
> +}
> +
> +module_init(rtc_init);
> +module_exit(rtc_exit);

So all it does is to install an empty address space handler for the CMOS
address space, right?

Bob, I wonder what you think about that?

Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux