^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * AMD MP2 PCIe communication driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Elie Morisse <syniurge@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "i2c-amd-mp2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/io-64-nonatomic-lo-hi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static void amd_mp2_c2p_mutex_lock(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* there is only one data mailbox for two i2c adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) mutex_lock(&privdata->c2p_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) privdata->c2p_lock_busid = i2c_common->bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static void amd_mp2_c2p_mutex_unlock(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (unlikely(privdata->c2p_lock_busid != i2c_common->bus_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) dev_warn(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) "bus %d attempting to unlock C2P locked by bus %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) i2c_common->bus_id, privdata->c2p_lock_busid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) mutex_unlock(&privdata->c2p_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int amd_mp2_cmd(struct amd_i2c_common *i2c_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) union i2c_cmd_base i2c_cmd_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) i2c_common->reqcmd = i2c_cmd_base.s.i2c_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) reg = privdata->mmio + ((i2c_cmd_base.s.bus_id == 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) AMD_C2P_MSG1 : AMD_C2P_MSG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) writel(i2c_cmd_base.ul, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int amd_mp2_bus_enable_set(struct amd_i2c_common *i2c_common, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) union i2c_cmd_base i2c_cmd_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) dev_dbg(ndev_dev(privdata), "%s id: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) i2c_common->bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) i2c_cmd_base.ul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) i2c_cmd_base.s.i2c_cmd = enable ? i2c_enable : i2c_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) i2c_cmd_base.s.bus_id = i2c_common->bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) i2c_cmd_base.s.i2c_speed = i2c_common->i2c_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) amd_mp2_c2p_mutex_lock(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return amd_mp2_cmd(i2c_common, i2c_cmd_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) EXPORT_SYMBOL_GPL(amd_mp2_bus_enable_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void amd_mp2_cmd_rw_fill(struct amd_i2c_common *i2c_common,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) union i2c_cmd_base *i2c_cmd_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) enum i2c_cmd reqcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) i2c_cmd_base->s.i2c_cmd = reqcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) i2c_cmd_base->s.bus_id = i2c_common->bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) i2c_cmd_base->s.i2c_speed = i2c_common->i2c_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) i2c_cmd_base->s.slave_addr = i2c_common->msg->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) i2c_cmd_base->s.length = i2c_common->msg->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int amd_mp2_rw(struct amd_i2c_common *i2c_common, enum i2c_cmd reqcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) union i2c_cmd_base i2c_cmd_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) amd_mp2_cmd_rw_fill(i2c_common, &i2c_cmd_base, reqcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) amd_mp2_c2p_mutex_lock(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (i2c_common->msg->len <= 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) i2c_cmd_base.s.mem_type = use_c2pmsg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (reqcmd == i2c_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) memcpy_toio(privdata->mmio + AMD_C2P_MSG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) i2c_common->msg->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) i2c_common->msg->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) i2c_cmd_base.s.mem_type = use_dram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) writeq((u64)i2c_common->dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) privdata->mmio + AMD_C2P_MSG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return amd_mp2_cmd(i2c_common, i2c_cmd_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) EXPORT_SYMBOL_GPL(amd_mp2_rw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void amd_mp2_pci_check_rw_event(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int len = i2c_common->eventval.r.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 slave_addr = i2c_common->eventval.r.slave_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bool err = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (unlikely(len != i2c_common->msg->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) "length %d in event doesn't match buffer length %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) len, i2c_common->msg->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (unlikely(slave_addr != i2c_common->msg->addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "unexpected slave address %x (expected: %x)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) slave_addr, i2c_common->msg->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) i2c_common->cmd_success = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void __amd_mp2_process_event(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) enum status_type sts = i2c_common->eventval.r.status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) enum response_type res = i2c_common->eventval.r.response;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int len = i2c_common->eventval.r.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (res != command_success) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (res != command_failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev_err(ndev_dev(privdata), "invalid response to i2c command!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) switch (i2c_common->reqcmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) case i2c_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (sts == i2c_readcomplete_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) amd_mp2_pci_check_rw_event(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (len <= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) memcpy_fromio(i2c_common->msg->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) privdata->mmio + AMD_C2P_MSG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else if (sts != i2c_readfail_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "invalid i2c status after read (%d)!\n", sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case i2c_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (sts == i2c_writecomplete_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) amd_mp2_pci_check_rw_event(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) else if (sts != i2c_writefail_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "invalid i2c status after write (%d)!\n", sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) case i2c_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (sts == i2c_busenable_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) i2c_common->cmd_success = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) else if (sts != i2c_busenable_failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "invalid i2c status after bus enable (%d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) case i2c_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (sts == i2c_busdisable_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) i2c_common->cmd_success = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) else if (sts != i2c_busdisable_failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "invalid i2c status after bus disable (%d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) sts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) void amd_mp2_process_event(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (unlikely(i2c_common->reqcmd == i2c_none)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dev_warn(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) "received msg but no cmd was sent (bus = %d)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) i2c_common->bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __amd_mp2_process_event(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) i2c_common->reqcmd = i2c_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) amd_mp2_c2p_mutex_unlock(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) EXPORT_SYMBOL_GPL(amd_mp2_process_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static irqreturn_t amd_mp2_irq_isr(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct amd_mp2_dev *privdata = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct amd_i2c_common *i2c_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) unsigned int bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) enum irqreturn ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) for (bus_id = 0; bus_id < 2; bus_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) i2c_common = privdata->busses[bus_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) reg = privdata->mmio + ((bus_id == 0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) AMD_P2C_MSG1 : AMD_P2C_MSG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) val = readl(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) writel(0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) writel(0, privdata->mmio + AMD_P2C_MSG_INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) i2c_common->eventval.ul = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) i2c_common->cmd_completion(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (ret != IRQ_HANDLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) val = readl(privdata->mmio + AMD_P2C_MSG_INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) writel(0, privdata->mmio + AMD_P2C_MSG_INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev_warn(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) "received irq without message\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) void amd_mp2_rw_timeout(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) i2c_common->reqcmd = i2c_none;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) amd_mp2_c2p_mutex_unlock(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) EXPORT_SYMBOL_GPL(amd_mp2_rw_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int amd_mp2_register_cb(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (i2c_common->bus_id > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (privdata->busses[i2c_common->bus_id]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) "Bus %d already taken!\n", i2c_common->bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) privdata->busses[i2c_common->bus_id] = i2c_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) EXPORT_SYMBOL_GPL(amd_mp2_register_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int amd_mp2_unregister_cb(struct amd_i2c_common *i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct amd_mp2_dev *privdata = i2c_common->mp2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) privdata->busses[i2c_common->bus_id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) EXPORT_SYMBOL_GPL(amd_mp2_unregister_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void amd_mp2_clear_reg(struct amd_mp2_dev *privdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) for (reg = AMD_C2P_MSG0; reg <= AMD_C2P_MSG9; reg += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) writel(0, privdata->mmio + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) for (reg = AMD_P2C_MSG1; reg <= AMD_P2C_MSG2; reg += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) writel(0, privdata->mmio + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static int amd_mp2_pci_init(struct amd_mp2_dev *privdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct pci_dev *pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pci_set_drvdata(pci_dev, privdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) rc = pcim_enable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_err(ndev_dev(privdata), "Failed to enable MP2 PCI device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) goto err_pci_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) rc = pcim_iomap_regions(pci_dev, 1 << 2, pci_name(pci_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) dev_err(ndev_dev(privdata), "I/O memory remapping failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto err_pci_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) privdata->mmio = pcim_iomap_table(pci_dev)[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pci_set_master(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) rc = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) rc = pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) goto err_dma_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Set up intx irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) writel(0, privdata->mmio + AMD_P2C_MSG_INTEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pci_intx(pci_dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) rc = devm_request_irq(&pci_dev->dev, pci_dev->irq, amd_mp2_irq_isr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) IRQF_SHARED, dev_name(&pci_dev->dev), privdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_err(&pci_dev->dev, "Failure requesting irq %i: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pci_dev->irq, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) err_dma_mask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) pci_clear_master(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) err_pci_enable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pci_set_drvdata(pci_dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int amd_mp2_pci_probe(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct amd_mp2_dev *privdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) privdata = devm_kzalloc(&pci_dev->dev, sizeof(*privdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!privdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) privdata->pci_dev = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) rc = amd_mp2_pci_init(privdata, pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) mutex_init(&privdata->c2p_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pm_runtime_use_autosuspend(&pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) pm_runtime_put_autosuspend(&pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) pm_runtime_allow(&pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) privdata->probed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dev_info(&pci_dev->dev, "MP2 device registered.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void amd_mp2_pci_remove(struct pci_dev *pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct amd_mp2_dev *privdata = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pm_runtime_forbid(&pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) pm_runtime_get_noresume(&pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pci_intx(pci_dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pci_clear_master(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) amd_mp2_clear_reg(privdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int amd_mp2_pci_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct amd_mp2_dev *privdata = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct amd_i2c_common *i2c_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned int bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) for (bus_id = 0; bus_id < 2; bus_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) i2c_common = privdata->busses[bus_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (i2c_common)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) i2c_common->suspend(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ret = pci_save_state(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) "pci_save_state failed = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) static int amd_mp2_pci_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct pci_dev *pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct amd_mp2_dev *privdata = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct amd_i2c_common *i2c_common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned int bus_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pci_restore_state(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = pci_enable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dev_err(ndev_dev(privdata),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) "pci_enable_device failed = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) for (bus_id = 0; bus_id < 2; bus_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) i2c_common = privdata->busses[bus_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (i2c_common) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = i2c_common->resume(i2c_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static UNIVERSAL_DEV_PM_OPS(amd_mp2_pci_pm_ops, amd_mp2_pci_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) amd_mp2_pci_resume, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static const struct pci_device_id amd_mp2_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) MODULE_DEVICE_TABLE(pci, amd_mp2_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) static struct pci_driver amd_mp2_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .name = "i2c_amd_mp2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .id_table = amd_mp2_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .probe = amd_mp2_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .remove = amd_mp2_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .pm = &amd_mp2_pci_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) module_pci_driver(amd_mp2_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct amd_mp2_dev *amd_mp2_find_device(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) dev = driver_find_next_device(&amd_mp2_pci_driver.driver, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pci_dev = to_pci_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return (struct amd_mp2_dev *)pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) EXPORT_SYMBOL_GPL(amd_mp2_find_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MODULE_DESCRIPTION("AMD(R) PCI-E MP2 I2C Controller Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) MODULE_AUTHOR("Shyam Sundar S K <Shyam-sundar.S-k@amd.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) MODULE_AUTHOR("Elie Morisse <syniurge@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) MODULE_LICENSE("Dual BSD/GPL");