cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i2c-core-acpi.c (19640B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Linux I2C core ACPI support code
      4 *
      5 * Copyright (C) 2014 Intel Corp, Author: Lan Tianyu <tianyu.lan@intel.com>
      6 */
      7
      8#include <linux/acpi.h>
      9#include <linux/device.h>
     10#include <linux/err.h>
     11#include <linux/i2c.h>
     12#include <linux/list.h>
     13#include <linux/module.h>
     14#include <linux/slab.h>
     15
     16#include "i2c-core.h"
     17
     18struct i2c_acpi_handler_data {
     19	struct acpi_connection_info info;
     20	struct i2c_adapter *adapter;
     21};
     22
     23struct gsb_buffer {
     24	u8	status;
     25	u8	len;
     26	union {
     27		u16	wdata;
     28		u8	bdata;
     29		u8	data[0];
     30	};
     31} __packed;
     32
     33struct i2c_acpi_lookup {
     34	struct i2c_board_info *info;
     35	acpi_handle adapter_handle;
     36	acpi_handle device_handle;
     37	acpi_handle search_handle;
     38	int n;
     39	int index;
     40	u32 speed;
     41	u32 min_speed;
     42	u32 force_speed;
     43};
     44
     45/**
     46 * i2c_acpi_get_i2c_resource - Gets I2cSerialBus resource if type matches
     47 * @ares:	ACPI resource
     48 * @i2c:	Pointer to I2cSerialBus resource will be returned here
     49 *
     50 * Checks if the given ACPI resource is of type I2cSerialBus.
     51 * In this case, returns a pointer to it to the caller.
     52 *
     53 * Returns true if resource type is of I2cSerialBus, otherwise false.
     54 */
     55bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
     56			       struct acpi_resource_i2c_serialbus **i2c)
     57{
     58	struct acpi_resource_i2c_serialbus *sb;
     59
     60	if (ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS)
     61		return false;
     62
     63	sb = &ares->data.i2c_serial_bus;
     64	if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C)
     65		return false;
     66
     67	*i2c = sb;
     68	return true;
     69}
     70EXPORT_SYMBOL_GPL(i2c_acpi_get_i2c_resource);
     71
     72static int i2c_acpi_resource_count(struct acpi_resource *ares, void *data)
     73{
     74	struct acpi_resource_i2c_serialbus *sb;
     75	int *count = data;
     76
     77	if (i2c_acpi_get_i2c_resource(ares, &sb))
     78		*count = *count + 1;
     79
     80	return 1;
     81}
     82
     83/**
     84 * i2c_acpi_client_count - Count the number of I2cSerialBus resources
     85 * @adev:	ACPI device
     86 *
     87 * Returns the number of I2cSerialBus resources in the ACPI-device's
     88 * resource-list; or a negative error code.
     89 */
     90int i2c_acpi_client_count(struct acpi_device *adev)
     91{
     92	int ret, count = 0;
     93	LIST_HEAD(r);
     94
     95	ret = acpi_dev_get_resources(adev, &r, i2c_acpi_resource_count, &count);
     96	if (ret < 0)
     97		return ret;
     98
     99	acpi_dev_free_resource_list(&r);
    100	return count;
    101}
    102EXPORT_SYMBOL_GPL(i2c_acpi_client_count);
    103
    104static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data)
    105{
    106	struct i2c_acpi_lookup *lookup = data;
    107	struct i2c_board_info *info = lookup->info;
    108	struct acpi_resource_i2c_serialbus *sb;
    109	acpi_status status;
    110
    111	if (info->addr || !i2c_acpi_get_i2c_resource(ares, &sb))
    112		return 1;
    113
    114	if (lookup->index != -1 && lookup->n++ != lookup->index)
    115		return 1;
    116
    117	status = acpi_get_handle(lookup->device_handle,
    118				 sb->resource_source.string_ptr,
    119				 &lookup->adapter_handle);
    120	if (ACPI_FAILURE(status))
    121		return 1;
    122
    123	info->addr = sb->slave_address;
    124	lookup->speed = sb->connection_speed;
    125	if (sb->access_mode == ACPI_I2C_10BIT_MODE)
    126		info->flags |= I2C_CLIENT_TEN;
    127
    128	return 1;
    129}
    130
    131static const struct acpi_device_id i2c_acpi_ignored_device_ids[] = {
    132	/*
    133	 * ACPI video acpi_devices, which are handled by the acpi-video driver
    134	 * sometimes contain a SERIAL_TYPE_I2C ACPI resource, ignore these.
    135	 */
    136	{ ACPI_VIDEO_HID, 0 },
    137	{}
    138};
    139
    140static int i2c_acpi_do_lookup(struct acpi_device *adev,
    141			      struct i2c_acpi_lookup *lookup)
    142{
    143	struct i2c_board_info *info = lookup->info;
    144	struct list_head resource_list;
    145	int ret;
    146
    147	if (acpi_bus_get_status(adev))
    148		return -EINVAL;
    149
    150	if (!acpi_dev_ready_for_enumeration(adev))
    151		return -ENODEV;
    152
    153	if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
    154		return -ENODEV;
    155
    156	memset(info, 0, sizeof(*info));
    157	lookup->device_handle = acpi_device_handle(adev);
    158
    159	/* Look up for I2cSerialBus resource */
    160	INIT_LIST_HEAD(&resource_list);
    161	ret = acpi_dev_get_resources(adev, &resource_list,
    162				     i2c_acpi_fill_info, lookup);
    163	acpi_dev_free_resource_list(&resource_list);
    164
    165	if (ret < 0 || !info->addr)
    166		return -EINVAL;
    167
    168	return 0;
    169}
    170
    171static int i2c_acpi_add_resource(struct acpi_resource *ares, void *data)
    172{
    173	int *irq = data;
    174	struct resource r;
    175
    176	if (*irq <= 0 && acpi_dev_resource_interrupt(ares, 0, &r))
    177		*irq = i2c_dev_irq_from_resources(&r, 1);
    178
    179	return 1; /* No need to add resource to the list */
    180}
    181
    182/**
    183 * i2c_acpi_get_irq - get device IRQ number from ACPI
    184 * @client: Pointer to the I2C client device
    185 *
    186 * Find the IRQ number used by a specific client device.
    187 *
    188 * Return: The IRQ number or an error code.
    189 */
    190int i2c_acpi_get_irq(struct i2c_client *client)
    191{
    192	struct acpi_device *adev = ACPI_COMPANION(&client->dev);
    193	struct list_head resource_list;
    194	int irq = -ENOENT;
    195	int ret;
    196
    197	INIT_LIST_HEAD(&resource_list);
    198
    199	ret = acpi_dev_get_resources(adev, &resource_list,
    200				     i2c_acpi_add_resource, &irq);
    201	if (ret < 0)
    202		return ret;
    203
    204	acpi_dev_free_resource_list(&resource_list);
    205
    206	if (irq == -ENOENT)
    207		irq = acpi_dev_gpio_irq_get(adev, 0);
    208
    209	return irq;
    210}
    211
    212static int i2c_acpi_get_info(struct acpi_device *adev,
    213			     struct i2c_board_info *info,
    214			     struct i2c_adapter *adapter,
    215			     acpi_handle *adapter_handle)
    216{
    217	struct i2c_acpi_lookup lookup;
    218	int ret;
    219
    220	memset(&lookup, 0, sizeof(lookup));
    221	lookup.info = info;
    222	lookup.index = -1;
    223
    224	if (acpi_device_enumerated(adev))
    225		return -EINVAL;
    226
    227	ret = i2c_acpi_do_lookup(adev, &lookup);
    228	if (ret)
    229		return ret;
    230
    231	if (adapter) {
    232		/* The adapter must match the one in I2cSerialBus() connector */
    233		if (ACPI_HANDLE(&adapter->dev) != lookup.adapter_handle)
    234			return -ENODEV;
    235	} else {
    236		struct acpi_device *adapter_adev;
    237
    238		/* The adapter must be present */
    239		adapter_adev = acpi_fetch_acpi_dev(lookup.adapter_handle);
    240		if (!adapter_adev)
    241			return -ENODEV;
    242		if (acpi_bus_get_status(adapter_adev) ||
    243		    !adapter_adev->status.present)
    244			return -ENODEV;
    245	}
    246
    247	info->fwnode = acpi_fwnode_handle(adev);
    248	if (adapter_handle)
    249		*adapter_handle = lookup.adapter_handle;
    250
    251	acpi_set_modalias(adev, dev_name(&adev->dev), info->type,
    252			  sizeof(info->type));
    253
    254	return 0;
    255}
    256
    257static void i2c_acpi_register_device(struct i2c_adapter *adapter,
    258				     struct acpi_device *adev,
    259				     struct i2c_board_info *info)
    260{
    261	/*
    262	 * Skip registration on boards where the ACPI tables are
    263	 * known to contain bogus I2C devices.
    264	 */
    265	if (acpi_quirk_skip_i2c_client_enumeration(adev))
    266		return;
    267
    268	adev->power.flags.ignore_parent = true;
    269	acpi_device_set_enumerated(adev);
    270
    271	if (IS_ERR(i2c_new_client_device(adapter, info)))
    272		adev->power.flags.ignore_parent = false;
    273}
    274
    275static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
    276				       void *data, void **return_value)
    277{
    278	struct i2c_adapter *adapter = data;
    279	struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
    280	struct i2c_board_info info;
    281
    282	if (!adev || i2c_acpi_get_info(adev, &info, adapter, NULL))
    283		return AE_OK;
    284
    285	i2c_acpi_register_device(adapter, adev, &info);
    286
    287	return AE_OK;
    288}
    289
    290#define I2C_ACPI_MAX_SCAN_DEPTH 32
    291
    292/**
    293 * i2c_acpi_register_devices - enumerate I2C slave devices behind adapter
    294 * @adap: pointer to adapter
    295 *
    296 * Enumerate all I2C slave devices behind this adapter by walking the ACPI
    297 * namespace. When a device is found it will be added to the Linux device
    298 * model and bound to the corresponding ACPI handle.
    299 */
    300void i2c_acpi_register_devices(struct i2c_adapter *adap)
    301{
    302	struct acpi_device *adev;
    303	acpi_status status;
    304
    305	if (!has_acpi_companion(&adap->dev))
    306		return;
    307
    308	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
    309				     I2C_ACPI_MAX_SCAN_DEPTH,
    310				     i2c_acpi_add_device, NULL,
    311				     adap, NULL);
    312	if (ACPI_FAILURE(status))
    313		dev_warn(&adap->dev, "failed to enumerate I2C slaves\n");
    314
    315	if (!adap->dev.parent)
    316		return;
    317
    318	adev = ACPI_COMPANION(adap->dev.parent);
    319	if (!adev)
    320		return;
    321
    322	acpi_dev_clear_dependencies(adev);
    323}
    324
    325static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = {
    326	/*
    327	 * These Silead touchscreen controllers only work at 400KHz, for
    328	 * some reason they do not work at 100KHz. On some devices the ACPI
    329	 * tables list another device at their bus as only being capable
    330	 * of 100KHz, testing has shown that these other devices work fine
    331	 * at 400KHz (as can be expected of any recent i2c hw) so we force
    332	 * the speed of the bus to 400 KHz if a Silead device is present.
    333	 */
    334	{ "MSSL1680", 0 },
    335	{}
    336};
    337
    338static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
    339					   void *data, void **return_value)
    340{
    341	struct i2c_acpi_lookup *lookup = data;
    342	struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
    343
    344	if (!adev || i2c_acpi_do_lookup(adev, lookup))
    345		return AE_OK;
    346
    347	if (lookup->search_handle != lookup->adapter_handle)
    348		return AE_OK;
    349
    350	if (lookup->speed <= lookup->min_speed)
    351		lookup->min_speed = lookup->speed;
    352
    353	if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
    354		lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
    355
    356	return AE_OK;
    357}
    358
    359/**
    360 * i2c_acpi_find_bus_speed - find I2C bus speed from ACPI
    361 * @dev: The device owning the bus
    362 *
    363 * Find the I2C bus speed by walking the ACPI namespace for all I2C slaves
    364 * devices connected to this bus and use the speed of slowest device.
    365 *
    366 * Returns the speed in Hz or zero
    367 */
    368u32 i2c_acpi_find_bus_speed(struct device *dev)
    369{
    370	struct i2c_acpi_lookup lookup;
    371	struct i2c_board_info dummy;
    372	acpi_status status;
    373
    374	if (!has_acpi_companion(dev))
    375		return 0;
    376
    377	memset(&lookup, 0, sizeof(lookup));
    378	lookup.search_handle = ACPI_HANDLE(dev);
    379	lookup.min_speed = UINT_MAX;
    380	lookup.info = &dummy;
    381	lookup.index = -1;
    382
    383	status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
    384				     I2C_ACPI_MAX_SCAN_DEPTH,
    385				     i2c_acpi_lookup_speed, NULL,
    386				     &lookup, NULL);
    387
    388	if (ACPI_FAILURE(status)) {
    389		dev_warn(dev, "unable to find I2C bus speed from ACPI\n");
    390		return 0;
    391	}
    392
    393	if (lookup.force_speed) {
    394		if (lookup.force_speed != lookup.min_speed)
    395			dev_warn(dev, FW_BUG "DSDT uses known not-working I2C bus speed %d, forcing it to %d\n",
    396				 lookup.min_speed, lookup.force_speed);
    397		return lookup.force_speed;
    398	} else if (lookup.min_speed != UINT_MAX) {
    399		return lookup.min_speed;
    400	} else {
    401		return 0;
    402	}
    403}
    404EXPORT_SYMBOL_GPL(i2c_acpi_find_bus_speed);
    405
    406struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
    407{
    408	struct i2c_adapter *adapter;
    409	struct device *dev;
    410
    411	dev = bus_find_device(&i2c_bus_type, NULL, handle, device_match_acpi_handle);
    412	if (!dev)
    413		return NULL;
    414
    415	adapter = i2c_verify_adapter(dev);
    416	if (!adapter)
    417		put_device(dev);
    418
    419	return adapter;
    420}
    421EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle);
    422
    423static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev)
    424{
    425	struct device *dev;
    426	struct i2c_client *client;
    427
    428	dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
    429	if (!dev)
    430		return NULL;
    431
    432	client = i2c_verify_client(dev);
    433	if (!client)
    434		put_device(dev);
    435
    436	return client;
    437}
    438
    439static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
    440			   void *arg)
    441{
    442	struct acpi_device *adev = arg;
    443	struct i2c_board_info info;
    444	acpi_handle adapter_handle;
    445	struct i2c_adapter *adapter;
    446	struct i2c_client *client;
    447
    448	switch (value) {
    449	case ACPI_RECONFIG_DEVICE_ADD:
    450		if (i2c_acpi_get_info(adev, &info, NULL, &adapter_handle))
    451			break;
    452
    453		adapter = i2c_acpi_find_adapter_by_handle(adapter_handle);
    454		if (!adapter)
    455			break;
    456
    457		i2c_acpi_register_device(adapter, adev, &info);
    458		put_device(&adapter->dev);
    459		break;
    460	case ACPI_RECONFIG_DEVICE_REMOVE:
    461		if (!acpi_device_enumerated(adev))
    462			break;
    463
    464		client = i2c_acpi_find_client_by_adev(adev);
    465		if (!client)
    466			break;
    467
    468		i2c_unregister_device(client);
    469		put_device(&client->dev);
    470		break;
    471	}
    472
    473	return NOTIFY_OK;
    474}
    475
    476struct notifier_block i2c_acpi_notifier = {
    477	.notifier_call = i2c_acpi_notify,
    478};
    479
    480/**
    481 * i2c_acpi_new_device_by_fwnode - Create i2c-client for the Nth I2cSerialBus resource
    482 * @fwnode:  fwnode with the ACPI resources to get the client from
    483 * @index:   Index of ACPI resource to get
    484 * @info:    describes the I2C device; note this is modified (addr gets set)
    485 * Context: can sleep
    486 *
    487 * By default the i2c subsys creates an i2c-client for the first I2cSerialBus
    488 * resource of an acpi_device, but some acpi_devices have multiple I2cSerialBus
    489 * resources, in that case this function can be used to create an i2c-client
    490 * for other I2cSerialBus resources in the Current Resource Settings table.
    491 *
    492 * Also see i2c_new_client_device, which this function calls to create the
    493 * i2c-client.
    494 *
    495 * Returns a pointer to the new i2c-client, or error pointer in case of failure.
    496 * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
    497 */
    498struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
    499						 int index,
    500						 struct i2c_board_info *info)
    501{
    502	struct i2c_acpi_lookup lookup;
    503	struct i2c_adapter *adapter;
    504	struct acpi_device *adev;
    505	LIST_HEAD(resource_list);
    506	int ret;
    507
    508	adev = to_acpi_device_node(fwnode);
    509	if (!adev)
    510		return ERR_PTR(-ENODEV);
    511
    512	memset(&lookup, 0, sizeof(lookup));
    513	lookup.info = info;
    514	lookup.device_handle = acpi_device_handle(adev);
    515	lookup.index = index;
    516
    517	ret = acpi_dev_get_resources(adev, &resource_list,
    518				     i2c_acpi_fill_info, &lookup);
    519	if (ret < 0)
    520		return ERR_PTR(ret);
    521
    522	acpi_dev_free_resource_list(&resource_list);
    523
    524	if (!info->addr)
    525		return ERR_PTR(-EADDRNOTAVAIL);
    526
    527	adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle);
    528	if (!adapter)
    529		return ERR_PTR(-EPROBE_DEFER);
    530
    531	return i2c_new_client_device(adapter, info);
    532}
    533EXPORT_SYMBOL_GPL(i2c_acpi_new_device_by_fwnode);
    534
    535bool i2c_acpi_waive_d0_probe(struct device *dev)
    536{
    537	struct i2c_driver *driver = to_i2c_driver(dev->driver);
    538	struct acpi_device *adev = ACPI_COMPANION(dev);
    539
    540	return driver->flags & I2C_DRV_ACPI_WAIVE_D0_PROBE &&
    541		adev && adev->power.state_for_enumeration >= adev->power.state;
    542}
    543EXPORT_SYMBOL_GPL(i2c_acpi_waive_d0_probe);
    544
    545#ifdef CONFIG_ACPI_I2C_OPREGION
    546static int acpi_gsb_i2c_read_bytes(struct i2c_client *client,
    547		u8 cmd, u8 *data, u8 data_len)
    548{
    549
    550	struct i2c_msg msgs[2];
    551	int ret;
    552	u8 *buffer;
    553
    554	buffer = kzalloc(data_len, GFP_KERNEL);
    555	if (!buffer)
    556		return AE_NO_MEMORY;
    557
    558	msgs[0].addr = client->addr;
    559	msgs[0].flags = client->flags;
    560	msgs[0].len = 1;
    561	msgs[0].buf = &cmd;
    562
    563	msgs[1].addr = client->addr;
    564	msgs[1].flags = client->flags | I2C_M_RD;
    565	msgs[1].len = data_len;
    566	msgs[1].buf = buffer;
    567
    568	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
    569	if (ret < 0) {
    570		/* Getting a NACK is unfortunately normal with some DSTDs */
    571		if (ret == -EREMOTEIO)
    572			dev_dbg(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n",
    573				data_len, client->addr, cmd, ret);
    574		else
    575			dev_err(&client->adapter->dev, "i2c read %d bytes from client@%#x starting at reg %#x failed, error: %d\n",
    576				data_len, client->addr, cmd, ret);
    577	/* 2 transfers must have completed successfully */
    578	} else if (ret == 2) {
    579		memcpy(data, buffer, data_len);
    580		ret = 0;
    581	} else {
    582		ret = -EIO;
    583	}
    584
    585	kfree(buffer);
    586	return ret;
    587}
    588
    589static int acpi_gsb_i2c_write_bytes(struct i2c_client *client,
    590		u8 cmd, u8 *data, u8 data_len)
    591{
    592
    593	struct i2c_msg msgs[1];
    594	u8 *buffer;
    595	int ret = AE_OK;
    596
    597	buffer = kzalloc(data_len + 1, GFP_KERNEL);
    598	if (!buffer)
    599		return AE_NO_MEMORY;
    600
    601	buffer[0] = cmd;
    602	memcpy(buffer + 1, data, data_len);
    603
    604	msgs[0].addr = client->addr;
    605	msgs[0].flags = client->flags;
    606	msgs[0].len = data_len + 1;
    607	msgs[0].buf = buffer;
    608
    609	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
    610
    611	kfree(buffer);
    612
    613	if (ret < 0) {
    614		dev_err(&client->adapter->dev, "i2c write failed: %d\n", ret);
    615		return ret;
    616	}
    617
    618	/* 1 transfer must have completed successfully */
    619	return (ret == 1) ? 0 : -EIO;
    620}
    621
    622static acpi_status
    623i2c_acpi_space_handler(u32 function, acpi_physical_address command,
    624			u32 bits, u64 *value64,
    625			void *handler_context, void *region_context)
    626{
    627	struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
    628	struct i2c_acpi_handler_data *data = handler_context;
    629	struct acpi_connection_info *info = &data->info;
    630	struct acpi_resource_i2c_serialbus *sb;
    631	struct i2c_adapter *adapter = data->adapter;
    632	struct i2c_client *client;
    633	struct acpi_resource *ares;
    634	u32 accessor_type = function >> 16;
    635	u8 action = function & ACPI_IO_MASK;
    636	acpi_status ret;
    637	int status;
    638
    639	ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
    640	if (ACPI_FAILURE(ret))
    641		return ret;
    642
    643	client = kzalloc(sizeof(*client), GFP_KERNEL);
    644	if (!client) {
    645		ret = AE_NO_MEMORY;
    646		goto err;
    647	}
    648
    649	if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
    650		ret = AE_BAD_PARAMETER;
    651		goto err;
    652	}
    653
    654	client->adapter = adapter;
    655	client->addr = sb->slave_address;
    656
    657	if (sb->access_mode == ACPI_I2C_10BIT_MODE)
    658		client->flags |= I2C_CLIENT_TEN;
    659
    660	switch (accessor_type) {
    661	case ACPI_GSB_ACCESS_ATTRIB_SEND_RCV:
    662		if (action == ACPI_READ) {
    663			status = i2c_smbus_read_byte(client);
    664			if (status >= 0) {
    665				gsb->bdata = status;
    666				status = 0;
    667			}
    668		} else {
    669			status = i2c_smbus_write_byte(client, gsb->bdata);
    670		}
    671		break;
    672
    673	case ACPI_GSB_ACCESS_ATTRIB_BYTE:
    674		if (action == ACPI_READ) {
    675			status = i2c_smbus_read_byte_data(client, command);
    676			if (status >= 0) {
    677				gsb->bdata = status;
    678				status = 0;
    679			}
    680		} else {
    681			status = i2c_smbus_write_byte_data(client, command,
    682					gsb->bdata);
    683		}
    684		break;
    685
    686	case ACPI_GSB_ACCESS_ATTRIB_WORD:
    687		if (action == ACPI_READ) {
    688			status = i2c_smbus_read_word_data(client, command);
    689			if (status >= 0) {
    690				gsb->wdata = status;
    691				status = 0;
    692			}
    693		} else {
    694			status = i2c_smbus_write_word_data(client, command,
    695					gsb->wdata);
    696		}
    697		break;
    698
    699	case ACPI_GSB_ACCESS_ATTRIB_BLOCK:
    700		if (action == ACPI_READ) {
    701			status = i2c_smbus_read_block_data(client, command,
    702					gsb->data);
    703			if (status >= 0) {
    704				gsb->len = status;
    705				status = 0;
    706			}
    707		} else {
    708			status = i2c_smbus_write_block_data(client, command,
    709					gsb->len, gsb->data);
    710		}
    711		break;
    712
    713	case ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE:
    714		if (action == ACPI_READ) {
    715			status = acpi_gsb_i2c_read_bytes(client, command,
    716					gsb->data, info->access_length);
    717		} else {
    718			status = acpi_gsb_i2c_write_bytes(client, command,
    719					gsb->data, info->access_length);
    720		}
    721		break;
    722
    723	default:
    724		dev_warn(&adapter->dev, "protocol 0x%02x not supported for client 0x%02x\n",
    725			 accessor_type, client->addr);
    726		ret = AE_BAD_PARAMETER;
    727		goto err;
    728	}
    729
    730	gsb->status = status;
    731
    732 err:
    733	kfree(client);
    734	ACPI_FREE(ares);
    735	return ret;
    736}
    737
    738
    739int i2c_acpi_install_space_handler(struct i2c_adapter *adapter)
    740{
    741	acpi_handle handle;
    742	struct i2c_acpi_handler_data *data;
    743	acpi_status status;
    744
    745	if (!adapter->dev.parent)
    746		return -ENODEV;
    747
    748	handle = ACPI_HANDLE(adapter->dev.parent);
    749
    750	if (!handle)
    751		return -ENODEV;
    752
    753	data = kzalloc(sizeof(struct i2c_acpi_handler_data),
    754			    GFP_KERNEL);
    755	if (!data)
    756		return -ENOMEM;
    757
    758	data->adapter = adapter;
    759	status = acpi_bus_attach_private_data(handle, (void *)data);
    760	if (ACPI_FAILURE(status)) {
    761		kfree(data);
    762		return -ENOMEM;
    763	}
    764
    765	status = acpi_install_address_space_handler(handle,
    766				ACPI_ADR_SPACE_GSBUS,
    767				&i2c_acpi_space_handler,
    768				NULL,
    769				data);
    770	if (ACPI_FAILURE(status)) {
    771		dev_err(&adapter->dev, "Error installing i2c space handler\n");
    772		acpi_bus_detach_private_data(handle);
    773		kfree(data);
    774		return -ENOMEM;
    775	}
    776
    777	return 0;
    778}
    779
    780void i2c_acpi_remove_space_handler(struct i2c_adapter *adapter)
    781{
    782	acpi_handle handle;
    783	struct i2c_acpi_handler_data *data;
    784	acpi_status status;
    785
    786	if (!adapter->dev.parent)
    787		return;
    788
    789	handle = ACPI_HANDLE(adapter->dev.parent);
    790
    791	if (!handle)
    792		return;
    793
    794	acpi_remove_address_space_handler(handle,
    795				ACPI_ADR_SPACE_GSBUS,
    796				&i2c_acpi_space_handler);
    797
    798	status = acpi_bus_get_private_data(handle, (void **)&data);
    799	if (ACPI_SUCCESS(status))
    800		kfree(data);
    801
    802	acpi_bus_detach_private_data(handle);
    803}
    804#endif /* CONFIG_ACPI_I2C_OPREGION */