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-amd-mp2-plat.c (9797B)


      1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
      2/*
      3 * AMD MP2 platform driver
      4 *
      5 * Setup the I2C adapters enumerated in the ACPI namespace.
      6 * MP2 controllers have 2 separate busses, up to 2 I2C adapters may be listed.
      7 *
      8 * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com>
      9 *          Elie Morisse <syniurge@gmail.com>
     10 */
     11
     12#include <linux/acpi.h>
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15#include <linux/platform_device.h>
     16#include <linux/slab.h>
     17#include <linux/types.h>
     18
     19#include "i2c-amd-mp2.h"
     20
     21#define AMD_MP2_I2C_MAX_RW_LENGTH ((1 << 12) - 1)
     22#define AMD_I2C_TIMEOUT (msecs_to_jiffies(250))
     23
     24/**
     25 * struct amd_i2c_dev - MP2 bus/i2c adapter context
     26 * @common: shared context with the MP2 PCI driver
     27 * @pdev: platform driver node
     28 * @adap: i2c adapter
     29 * @cmd_complete: xfer completion object
     30 */
     31struct amd_i2c_dev {
     32	struct amd_i2c_common common;
     33	struct platform_device *pdev;
     34	struct i2c_adapter adap;
     35	struct completion cmd_complete;
     36};
     37
     38#define amd_i2c_dev_common(__common) \
     39	container_of(__common, struct amd_i2c_dev, common)
     40
     41static int i2c_amd_dma_map(struct amd_i2c_common *i2c_common)
     42{
     43	struct device *dev_pci = &i2c_common->mp2_dev->pci_dev->dev;
     44	struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common);
     45	enum dma_data_direction dma_direction =
     46			i2c_common->msg->flags & I2C_M_RD ?
     47			DMA_FROM_DEVICE : DMA_TO_DEVICE;
     48
     49	i2c_common->dma_buf = i2c_get_dma_safe_msg_buf(i2c_common->msg, 0);
     50	i2c_common->dma_addr = dma_map_single(dev_pci, i2c_common->dma_buf,
     51					      i2c_common->msg->len,
     52					      dma_direction);
     53
     54	if (unlikely(dma_mapping_error(dev_pci, i2c_common->dma_addr))) {
     55		dev_err(&i2c_dev->pdev->dev,
     56			"Error while mapping dma buffer %p\n",
     57			i2c_common->dma_buf);
     58		return -EIO;
     59	}
     60
     61	return 0;
     62}
     63
     64static void i2c_amd_dma_unmap(struct amd_i2c_common *i2c_common)
     65{
     66	struct device *dev_pci = &i2c_common->mp2_dev->pci_dev->dev;
     67	enum dma_data_direction dma_direction =
     68			i2c_common->msg->flags & I2C_M_RD ?
     69			DMA_FROM_DEVICE : DMA_TO_DEVICE;
     70
     71	dma_unmap_single(dev_pci, i2c_common->dma_addr,
     72			 i2c_common->msg->len, dma_direction);
     73
     74	i2c_put_dma_safe_msg_buf(i2c_common->dma_buf, i2c_common->msg, true);
     75}
     76
     77static void i2c_amd_start_cmd(struct amd_i2c_dev *i2c_dev)
     78{
     79	struct amd_i2c_common *i2c_common = &i2c_dev->common;
     80
     81	reinit_completion(&i2c_dev->cmd_complete);
     82	i2c_common->cmd_success = false;
     83}
     84
     85static void i2c_amd_cmd_completion(struct amd_i2c_common *i2c_common)
     86{
     87	struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common);
     88	union i2c_event *event = &i2c_common->eventval;
     89
     90	if (event->r.status == i2c_readcomplete_event)
     91		dev_dbg(&i2c_dev->pdev->dev, "readdata:%*ph\n", event->r.length,
     92			i2c_common->msg->buf);
     93
     94	complete(&i2c_dev->cmd_complete);
     95}
     96
     97static int i2c_amd_check_cmd_completion(struct amd_i2c_dev *i2c_dev)
     98{
     99	struct amd_i2c_common *i2c_common = &i2c_dev->common;
    100	unsigned long timeout;
    101
    102	timeout = wait_for_completion_timeout(&i2c_dev->cmd_complete,
    103					      i2c_dev->adap.timeout);
    104
    105	if ((i2c_common->reqcmd == i2c_read ||
    106	     i2c_common->reqcmd == i2c_write) &&
    107	    i2c_common->msg->len > 32)
    108		i2c_amd_dma_unmap(i2c_common);
    109
    110	if (timeout == 0) {
    111		amd_mp2_rw_timeout(i2c_common);
    112		return -ETIMEDOUT;
    113	}
    114
    115	amd_mp2_process_event(i2c_common);
    116
    117	if (!i2c_common->cmd_success)
    118		return -EIO;
    119
    120	return 0;
    121}
    122
    123static int i2c_amd_enable_set(struct amd_i2c_dev *i2c_dev, bool enable)
    124{
    125	struct amd_i2c_common *i2c_common = &i2c_dev->common;
    126
    127	i2c_amd_start_cmd(i2c_dev);
    128	amd_mp2_bus_enable_set(i2c_common, enable);
    129
    130	return i2c_amd_check_cmd_completion(i2c_dev);
    131}
    132
    133static int i2c_amd_xfer_msg(struct amd_i2c_dev *i2c_dev, struct i2c_msg *pmsg)
    134{
    135	struct amd_i2c_common *i2c_common = &i2c_dev->common;
    136
    137	i2c_amd_start_cmd(i2c_dev);
    138	i2c_common->msg = pmsg;
    139
    140	if (pmsg->len > 32)
    141		if (i2c_amd_dma_map(i2c_common))
    142			return -EIO;
    143
    144	if (pmsg->flags & I2C_M_RD)
    145		amd_mp2_rw(i2c_common, i2c_read);
    146	else
    147		amd_mp2_rw(i2c_common, i2c_write);
    148
    149	return i2c_amd_check_cmd_completion(i2c_dev);
    150}
    151
    152static int i2c_amd_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
    153{
    154	struct amd_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
    155	int i;
    156	struct i2c_msg *pmsg;
    157	int err = 0;
    158
    159	/* the adapter might have been deleted while waiting for the bus lock */
    160	if (unlikely(!i2c_dev->common.mp2_dev))
    161		return -EINVAL;
    162
    163	amd_mp2_pm_runtime_get(i2c_dev->common.mp2_dev);
    164
    165	for (i = 0; i < num; i++) {
    166		pmsg = &msgs[i];
    167		err = i2c_amd_xfer_msg(i2c_dev, pmsg);
    168		if (err)
    169			break;
    170	}
    171
    172	amd_mp2_pm_runtime_put(i2c_dev->common.mp2_dev);
    173	return err ? err : num;
    174}
    175
    176static u32 i2c_amd_func(struct i2c_adapter *a)
    177{
    178	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
    179}
    180
    181static const struct i2c_algorithm i2c_amd_algorithm = {
    182	.master_xfer = i2c_amd_xfer,
    183	.functionality = i2c_amd_func,
    184};
    185
    186#ifdef CONFIG_PM
    187static int i2c_amd_suspend(struct amd_i2c_common *i2c_common)
    188{
    189	struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common);
    190
    191	i2c_amd_enable_set(i2c_dev, false);
    192	return 0;
    193}
    194
    195static int i2c_amd_resume(struct amd_i2c_common *i2c_common)
    196{
    197	struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common);
    198
    199	return i2c_amd_enable_set(i2c_dev, true);
    200}
    201#endif
    202
    203static const u32 supported_speeds[] = {
    204	I2C_MAX_HIGH_SPEED_MODE_FREQ,
    205	I2C_MAX_TURBO_MODE_FREQ,
    206	I2C_MAX_FAST_MODE_PLUS_FREQ,
    207	I2C_MAX_FAST_MODE_FREQ,
    208	I2C_MAX_STANDARD_MODE_FREQ,
    209};
    210
    211static enum speed_enum i2c_amd_get_bus_speed(struct platform_device *pdev)
    212{
    213	u32 acpi_speed;
    214	int i;
    215
    216	acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
    217	/* round down to the lowest standard speed */
    218	for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) {
    219		if (acpi_speed >= supported_speeds[i])
    220			break;
    221	}
    222	acpi_speed = i < ARRAY_SIZE(supported_speeds) ? supported_speeds[i] : 0;
    223
    224	switch (acpi_speed) {
    225	case I2C_MAX_STANDARD_MODE_FREQ:
    226		return speed100k;
    227	case I2C_MAX_FAST_MODE_FREQ:
    228		return speed400k;
    229	case I2C_MAX_FAST_MODE_PLUS_FREQ:
    230		return speed1000k;
    231	case I2C_MAX_TURBO_MODE_FREQ:
    232		return speed1400k;
    233	case I2C_MAX_HIGH_SPEED_MODE_FREQ:
    234		return speed3400k;
    235	default:
    236		return speed400k;
    237	}
    238}
    239
    240static const struct i2c_adapter_quirks amd_i2c_dev_quirks = {
    241	.max_read_len = AMD_MP2_I2C_MAX_RW_LENGTH,
    242	.max_write_len = AMD_MP2_I2C_MAX_RW_LENGTH,
    243};
    244
    245static int i2c_amd_probe(struct platform_device *pdev)
    246{
    247	int ret;
    248	struct amd_i2c_dev *i2c_dev;
    249	struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
    250	struct amd_mp2_dev *mp2_dev;
    251	const char *uid;
    252
    253	if (!adev)
    254		return -ENODEV;
    255
    256	/* The ACPI namespace doesn't contain information about which MP2 PCI
    257	 * device an AMDI0011 ACPI device is related to, so assume that there's
    258	 * only one MP2 PCI device per system.
    259	 */
    260	mp2_dev = amd_mp2_find_device();
    261	if (!mp2_dev || !mp2_dev->probed)
    262		/* The MP2 PCI device should get probed later */
    263		return -EPROBE_DEFER;
    264
    265	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
    266	if (!i2c_dev)
    267		return -ENOMEM;
    268
    269	i2c_dev->common.mp2_dev = mp2_dev;
    270	i2c_dev->pdev = pdev;
    271	platform_set_drvdata(pdev, i2c_dev);
    272
    273	i2c_dev->common.cmd_completion = &i2c_amd_cmd_completion;
    274#ifdef CONFIG_PM
    275	i2c_dev->common.suspend = &i2c_amd_suspend;
    276	i2c_dev->common.resume = &i2c_amd_resume;
    277#endif
    278
    279	uid = adev->pnp.unique_id;
    280	if (!uid) {
    281		dev_err(&pdev->dev, "missing UID/bus id!\n");
    282		return -EINVAL;
    283	} else if (strcmp(uid, "0") == 0) {
    284		i2c_dev->common.bus_id = 0;
    285	} else if (strcmp(uid, "1") == 0) {
    286		i2c_dev->common.bus_id = 1;
    287	} else {
    288		dev_err(&pdev->dev, "incorrect UID/bus id \"%s\"!\n", uid);
    289		return -EINVAL;
    290	}
    291	dev_dbg(&pdev->dev, "bus id is %u\n", i2c_dev->common.bus_id);
    292
    293	/* Register the adapter */
    294	amd_mp2_pm_runtime_get(mp2_dev);
    295
    296	i2c_dev->common.reqcmd = i2c_none;
    297	if (amd_mp2_register_cb(&i2c_dev->common))
    298		return -EINVAL;
    299	device_link_add(&i2c_dev->pdev->dev, &mp2_dev->pci_dev->dev,
    300			DL_FLAG_AUTOREMOVE_CONSUMER);
    301
    302	i2c_dev->common.i2c_speed = i2c_amd_get_bus_speed(pdev);
    303
    304	/* Setup i2c adapter description */
    305	i2c_dev->adap.owner = THIS_MODULE;
    306	i2c_dev->adap.algo = &i2c_amd_algorithm;
    307	i2c_dev->adap.quirks = &amd_i2c_dev_quirks;
    308	i2c_dev->adap.dev.parent = &pdev->dev;
    309	i2c_dev->adap.algo_data = i2c_dev;
    310	i2c_dev->adap.timeout = AMD_I2C_TIMEOUT;
    311	ACPI_COMPANION_SET(&i2c_dev->adap.dev, ACPI_COMPANION(&pdev->dev));
    312	i2c_dev->adap.dev.of_node = pdev->dev.of_node;
    313	snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name),
    314		 "AMD MP2 i2c bus %u", i2c_dev->common.bus_id);
    315	i2c_set_adapdata(&i2c_dev->adap, i2c_dev);
    316
    317	init_completion(&i2c_dev->cmd_complete);
    318
    319	/* Enable the bus */
    320	if (i2c_amd_enable_set(i2c_dev, true))
    321		dev_err(&pdev->dev, "initial bus enable failed\n");
    322
    323	/* Attach to the i2c layer */
    324	ret = i2c_add_adapter(&i2c_dev->adap);
    325
    326	amd_mp2_pm_runtime_put(mp2_dev);
    327
    328	if (ret < 0)
    329		dev_err(&pdev->dev, "i2c add adapter failed = %d\n", ret);
    330
    331	return ret;
    332}
    333
    334static int i2c_amd_remove(struct platform_device *pdev)
    335{
    336	struct amd_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
    337	struct amd_i2c_common *i2c_common = &i2c_dev->common;
    338
    339	i2c_lock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
    340
    341	i2c_amd_enable_set(i2c_dev, false);
    342	amd_mp2_unregister_cb(i2c_common);
    343	i2c_common->mp2_dev = NULL;
    344
    345	i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER);
    346
    347	i2c_del_adapter(&i2c_dev->adap);
    348	return 0;
    349}
    350
    351static const struct acpi_device_id i2c_amd_acpi_match[] = {
    352	{ "AMDI0011" },
    353	{ },
    354};
    355MODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match);
    356
    357static struct platform_driver i2c_amd_plat_driver = {
    358	.probe = i2c_amd_probe,
    359	.remove = i2c_amd_remove,
    360	.driver = {
    361		.name = "i2c_amd_mp2",
    362		.acpi_match_table = ACPI_PTR(i2c_amd_acpi_match),
    363	},
    364};
    365module_platform_driver(i2c_amd_plat_driver);
    366
    367MODULE_DESCRIPTION("AMD(R) MP2 I2C Platform Driver");
    368MODULE_AUTHOR("Nehal Shah <nehal-bakulchandra.shah@amd.com>");
    369MODULE_AUTHOR("Elie Morisse <syniurge@gmail.com>");
    370MODULE_LICENSE("Dual BSD/GPL");