Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bdc8f096 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'acpi-assorted'

* acpi-assorted:
  ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan
  ACPI: Add CMOS RTC Operation Region handler support
  ACPI: Remove unused flags in acpi_device_flags
  ACPI: Remove useless initializers
  ACPI / battery: Make sure all spaces are in correct places
  ACPI: add _STA evaluation at do_acpi_find_child()
  ACPI / EC: access user space with get_user()/put_user()
parents f4c9f402 eff9a4b6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ acpi-y += acpi_platform.o
acpi-y				+= power.o
acpi-y				+= power.o
acpi-y				+= event.o
acpi-y				+= event.o
acpi-y				+= sysfs.o
acpi-y				+= sysfs.o
acpi-$(CONFIG_X86)		+= acpi_cmos_rtc.o
acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
acpi-$(CONFIG_DEBUG_FS)		+= debugfs.o
acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
acpi-$(CONFIG_ACPI_NUMA)	+= numa.o
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+92 −0
Original line number Original line Diff line number Diff line
/*
 * ACPI support for CMOS RTC Address Space access
 *
 * Copyright (C) 2013, Intel Corporation
 * Authors: Lan Tianyu <tianyu.lan@intel.com>
 *
 * 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/acpi.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm-generic/rtc.h>

#include "internal.h"

#define PREFIX "ACPI: "

ACPI_MODULE_NAME("cmos rtc");

static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
	{ "PNP0B00" },
	{ "PNP0B01" },
	{ "PNP0B02" },
	{}
};

static acpi_status
acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
		      u32 bits, u64 *value64,
		      void *handler_context, void *region_context)
{
	int i;
	u8 *value = (u8 *)&value64;

	if (address > 0xff || !value64)
		return AE_BAD_PARAMETER;

	if (function != ACPI_WRITE && function != ACPI_READ)
		return AE_BAD_PARAMETER;

	spin_lock_irq(&rtc_lock);

	for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
		if (function == ACPI_READ)
			*value = CMOS_READ(address);
		else
			CMOS_WRITE(*value, address);

	spin_unlock_irq(&rtc_lock);

	return AE_OK;
}

static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
		const struct acpi_device_id *id)
{
	acpi_status status;

	status = acpi_install_address_space_handler(adev->handle,
			ACPI_ADR_SPACE_CMOS,
			&acpi_cmos_rtc_space_handler,
			NULL, NULL);
	if (ACPI_FAILURE(status)) {
		pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
		return -ENODEV;
	}

	return 0;
}

static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
{
	if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
			ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
		pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
}

static struct acpi_scan_handler cmos_rtc_handler = {
	.ids = acpi_cmos_rtc_ids,
	.attach = acpi_install_cmos_rtc_space_handler,
	.detach = acpi_remove_cmos_rtc_space_handler,
};

void __init acpi_cmos_rtc_init(void)
{
	acpi_scan_add_handler(&cmos_rtc_handler);
}
+8 −9
Original line number Original line Diff line number Diff line
@@ -91,8 +91,7 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = {


int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
{
{
	acpi_status status = AE_OK;
	acpi_status status;



	if (!device)
	if (!device)
		return -EINVAL;
		return -EINVAL;
@@ -162,7 +161,7 @@ EXPORT_SYMBOL(acpi_bus_private_data_handler);


int acpi_bus_get_private_data(acpi_handle handle, void **data)
int acpi_bus_get_private_data(acpi_handle handle, void **data)
{
{
	acpi_status status = AE_OK;
	acpi_status status;


	if (!*data)
	if (!*data)
		return -EINVAL;
		return -EINVAL;
@@ -361,7 +360,7 @@ extern int event_is_open;
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
{
{
	struct acpi_bus_event *event;
	struct acpi_bus_event *event;
	unsigned long flags = 0;
	unsigned long flags;


	/* drop event on the floor if no one's listening */
	/* drop event on the floor if no one's listening */
	if (!event_is_open)
	if (!event_is_open)
@@ -400,7 +399,7 @@ EXPORT_SYMBOL(acpi_bus_generate_proc_event);


int acpi_bus_receive_event(struct acpi_bus_event *event)
int acpi_bus_receive_event(struct acpi_bus_event *event)
{
{
	unsigned long flags = 0;
	unsigned long flags;
	struct acpi_bus_event *entry = NULL;
	struct acpi_bus_event *entry = NULL;


	DECLARE_WAITQUEUE(wait, current);
	DECLARE_WAITQUEUE(wait, current);
@@ -593,7 +592,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)


static int __init acpi_bus_init_irq(void)
static int __init acpi_bus_init_irq(void)
{
{
	acpi_status status = AE_OK;
	acpi_status status;
	union acpi_object arg = { ACPI_TYPE_INTEGER };
	union acpi_object arg = { ACPI_TYPE_INTEGER };
	struct acpi_object_list arg_list = { 1, &arg };
	struct acpi_object_list arg_list = { 1, &arg };
	char *message = NULL;
	char *message = NULL;
@@ -640,7 +639,7 @@ u8 acpi_gbl_permanent_mmap;


void __init acpi_early_init(void)
void __init acpi_early_init(void)
{
{
	acpi_status status = AE_OK;
	acpi_status status;


	if (acpi_disabled)
	if (acpi_disabled)
		return;
		return;
@@ -714,8 +713,8 @@ void __init acpi_early_init(void)


static int __init acpi_bus_init(void)
static int __init acpi_bus_init(void)
{
{
	int result = 0;
	int result;
	acpi_status status = AE_OK;
	acpi_status status;
	extern acpi_status acpi_os_initialize1(void);
	extern acpi_status acpi_os_initialize1(void);


	acpi_os_initialize1();
	acpi_os_initialize1();
+4 −0
Original line number Original line Diff line number Diff line
@@ -983,6 +983,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
	ec_enlarge_storm_threshold, "CLEVO hardware", {
	ec_enlarge_storm_threshold, "CLEVO hardware", {
	DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
	DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
	DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
	DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
	{
	ec_skip_dsdt_scan, "HP Folio 13", {
	DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
	DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
	{},
	{},
};
};


+14 −4
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/debugfs.h>
#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include "internal.h"
#include "internal.h"


MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
	 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
	 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
	 */
	 */
	unsigned int size = EC_SPACE_SIZE;
	unsigned int size = EC_SPACE_SIZE;
	u8 *data = (u8 *) buf;
	loff_t init_off = *off;
	loff_t init_off = *off;
	int err = 0;
	int err = 0;


@@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
		size = count;
		size = count;


	while (size) {
	while (size) {
		err = ec_read(*off, &data[*off - init_off]);
		u8 byte_read;
		err = ec_read(*off, &byte_read);
		if (err)
		if (err)
			return err;
			return err;
		if (put_user(byte_read, buf + *off - init_off)) {
			if (*off - init_off)
				return *off - init_off; /* partial read */
			return -EFAULT;
		}
		*off += 1;
		*off += 1;
		size--;
		size--;
	}
	}
@@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,


	unsigned int size = count;
	unsigned int size = count;
	loff_t init_off = *off;
	loff_t init_off = *off;
	u8 *data = (u8 *) buf;
	int err = 0;
	int err = 0;


	if (*off >= EC_SPACE_SIZE)
	if (*off >= EC_SPACE_SIZE)
@@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
	}
	}


	while (size) {
	while (size) {
		u8 byte_write = data[*off - init_off];
		u8 byte_write;
		if (get_user(byte_write, buf + *off - init_off)) {
			if (*off - init_off)
				return *off - init_off; /* partial write */
			return -EFAULT;
		}
		err = ec_write(*off, byte_write);
		err = ec_write(*off, byte_write);
		if (err)
		if (err)
			return err;
			return err;
Loading