1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Nvidia GPU I2C controller Driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2018 NVIDIA Corporation. All rights reserved.
6*4882a593Smuzhiyun * Author: Ajay Gupta <ajayg@nvidia.com>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun #include <linux/delay.h>
9*4882a593Smuzhiyun #include <linux/i2c.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <linux/iopoll.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/pci.h>
14*4882a593Smuzhiyun #include <linux/platform_device.h>
15*4882a593Smuzhiyun #include <linux/pm.h>
16*4882a593Smuzhiyun #include <linux/pm_runtime.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <asm/unaligned.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* I2C definitions */
21*4882a593Smuzhiyun #define I2C_MST_CNTL 0x00
22*4882a593Smuzhiyun #define I2C_MST_CNTL_GEN_START BIT(0)
23*4882a593Smuzhiyun #define I2C_MST_CNTL_GEN_STOP BIT(1)
24*4882a593Smuzhiyun #define I2C_MST_CNTL_CMD_READ (1 << 2)
25*4882a593Smuzhiyun #define I2C_MST_CNTL_CMD_WRITE (2 << 2)
26*4882a593Smuzhiyun #define I2C_MST_CNTL_BURST_SIZE_SHIFT 6
27*4882a593Smuzhiyun #define I2C_MST_CNTL_GEN_NACK BIT(28)
28*4882a593Smuzhiyun #define I2C_MST_CNTL_STATUS GENMASK(30, 29)
29*4882a593Smuzhiyun #define I2C_MST_CNTL_STATUS_OKAY (0 << 29)
30*4882a593Smuzhiyun #define I2C_MST_CNTL_STATUS_NO_ACK (1 << 29)
31*4882a593Smuzhiyun #define I2C_MST_CNTL_STATUS_TIMEOUT (2 << 29)
32*4882a593Smuzhiyun #define I2C_MST_CNTL_STATUS_BUS_BUSY (3 << 29)
33*4882a593Smuzhiyun #define I2C_MST_CNTL_CYCLE_TRIGGER BIT(31)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define I2C_MST_ADDR 0x04
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define I2C_MST_I2C0_TIMING 0x08
38*4882a593Smuzhiyun #define I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ 0x10e
39*4882a593Smuzhiyun #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT 16
40*4882a593Smuzhiyun #define I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX 255
41*4882a593Smuzhiyun #define I2C_MST_I2C0_TIMING_TIMEOUT_CHECK BIT(24)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define I2C_MST_DATA 0x0c
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define I2C_MST_HYBRID_PADCTL 0x20
46*4882a593Smuzhiyun #define I2C_MST_HYBRID_PADCTL_MODE_I2C BIT(0)
47*4882a593Smuzhiyun #define I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV BIT(14)
48*4882a593Smuzhiyun #define I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV BIT(15)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun struct gpu_i2c_dev {
51*4882a593Smuzhiyun struct device *dev;
52*4882a593Smuzhiyun void __iomem *regs;
53*4882a593Smuzhiyun struct i2c_adapter adapter;
54*4882a593Smuzhiyun struct i2c_board_info *gpu_ccgx_ucsi;
55*4882a593Smuzhiyun struct i2c_client *ccgx_client;
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
gpu_enable_i2c_bus(struct gpu_i2c_dev * i2cd)58*4882a593Smuzhiyun static void gpu_enable_i2c_bus(struct gpu_i2c_dev *i2cd)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun u32 val;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* enable I2C */
63*4882a593Smuzhiyun val = readl(i2cd->regs + I2C_MST_HYBRID_PADCTL);
64*4882a593Smuzhiyun val |= I2C_MST_HYBRID_PADCTL_MODE_I2C |
65*4882a593Smuzhiyun I2C_MST_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
66*4882a593Smuzhiyun I2C_MST_HYBRID_PADCTL_I2C_SDA_INPUT_RCV;
67*4882a593Smuzhiyun writel(val, i2cd->regs + I2C_MST_HYBRID_PADCTL);
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun /* enable 100KHZ mode */
70*4882a593Smuzhiyun val = I2C_MST_I2C0_TIMING_SCL_PERIOD_100KHZ;
71*4882a593Smuzhiyun val |= (I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT_MAX
72*4882a593Smuzhiyun << I2C_MST_I2C0_TIMING_TIMEOUT_CLK_CNT);
73*4882a593Smuzhiyun val |= I2C_MST_I2C0_TIMING_TIMEOUT_CHECK;
74*4882a593Smuzhiyun writel(val, i2cd->regs + I2C_MST_I2C0_TIMING);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
gpu_i2c_check_status(struct gpu_i2c_dev * i2cd)77*4882a593Smuzhiyun static int gpu_i2c_check_status(struct gpu_i2c_dev *i2cd)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun u32 val;
80*4882a593Smuzhiyun int ret;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun ret = readl_poll_timeout(i2cd->regs + I2C_MST_CNTL, val,
83*4882a593Smuzhiyun !(val & I2C_MST_CNTL_CYCLE_TRIGGER) ||
84*4882a593Smuzhiyun (val & I2C_MST_CNTL_STATUS) != I2C_MST_CNTL_STATUS_BUS_BUSY,
85*4882a593Smuzhiyun 500, 1000 * USEC_PER_MSEC);
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun if (ret) {
88*4882a593Smuzhiyun dev_err(i2cd->dev, "i2c timeout error %x\n", val);
89*4882a593Smuzhiyun return -ETIMEDOUT;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun val = readl(i2cd->regs + I2C_MST_CNTL);
93*4882a593Smuzhiyun switch (val & I2C_MST_CNTL_STATUS) {
94*4882a593Smuzhiyun case I2C_MST_CNTL_STATUS_OKAY:
95*4882a593Smuzhiyun return 0;
96*4882a593Smuzhiyun case I2C_MST_CNTL_STATUS_NO_ACK:
97*4882a593Smuzhiyun return -ENXIO;
98*4882a593Smuzhiyun case I2C_MST_CNTL_STATUS_TIMEOUT:
99*4882a593Smuzhiyun return -ETIMEDOUT;
100*4882a593Smuzhiyun default:
101*4882a593Smuzhiyun return 0;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
gpu_i2c_read(struct gpu_i2c_dev * i2cd,u8 * data,u16 len)105*4882a593Smuzhiyun static int gpu_i2c_read(struct gpu_i2c_dev *i2cd, u8 *data, u16 len)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun int status;
108*4882a593Smuzhiyun u32 val;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun val = I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_READ |
111*4882a593Smuzhiyun (len << I2C_MST_CNTL_BURST_SIZE_SHIFT) |
112*4882a593Smuzhiyun I2C_MST_CNTL_CYCLE_TRIGGER | I2C_MST_CNTL_GEN_NACK;
113*4882a593Smuzhiyun writel(val, i2cd->regs + I2C_MST_CNTL);
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun status = gpu_i2c_check_status(i2cd);
116*4882a593Smuzhiyun if (status < 0)
117*4882a593Smuzhiyun return status;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun val = readl(i2cd->regs + I2C_MST_DATA);
120*4882a593Smuzhiyun switch (len) {
121*4882a593Smuzhiyun case 1:
122*4882a593Smuzhiyun data[0] = val;
123*4882a593Smuzhiyun break;
124*4882a593Smuzhiyun case 2:
125*4882a593Smuzhiyun put_unaligned_be16(val, data);
126*4882a593Smuzhiyun break;
127*4882a593Smuzhiyun case 3:
128*4882a593Smuzhiyun put_unaligned_be24(val, data);
129*4882a593Smuzhiyun break;
130*4882a593Smuzhiyun case 4:
131*4882a593Smuzhiyun put_unaligned_be32(val, data);
132*4882a593Smuzhiyun break;
133*4882a593Smuzhiyun default:
134*4882a593Smuzhiyun break;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun return status;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun
gpu_i2c_start(struct gpu_i2c_dev * i2cd)139*4882a593Smuzhiyun static int gpu_i2c_start(struct gpu_i2c_dev *i2cd)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun writel(I2C_MST_CNTL_GEN_START, i2cd->regs + I2C_MST_CNTL);
142*4882a593Smuzhiyun return gpu_i2c_check_status(i2cd);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
gpu_i2c_stop(struct gpu_i2c_dev * i2cd)145*4882a593Smuzhiyun static int gpu_i2c_stop(struct gpu_i2c_dev *i2cd)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun writel(I2C_MST_CNTL_GEN_STOP, i2cd->regs + I2C_MST_CNTL);
148*4882a593Smuzhiyun return gpu_i2c_check_status(i2cd);
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
gpu_i2c_write(struct gpu_i2c_dev * i2cd,u8 data)151*4882a593Smuzhiyun static int gpu_i2c_write(struct gpu_i2c_dev *i2cd, u8 data)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun u32 val;
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun writel(data, i2cd->regs + I2C_MST_DATA);
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun val = I2C_MST_CNTL_CMD_WRITE | (1 << I2C_MST_CNTL_BURST_SIZE_SHIFT);
158*4882a593Smuzhiyun writel(val, i2cd->regs + I2C_MST_CNTL);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun return gpu_i2c_check_status(i2cd);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
gpu_i2c_master_xfer(struct i2c_adapter * adap,struct i2c_msg * msgs,int num)163*4882a593Smuzhiyun static int gpu_i2c_master_xfer(struct i2c_adapter *adap,
164*4882a593Smuzhiyun struct i2c_msg *msgs, int num)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun struct gpu_i2c_dev *i2cd = i2c_get_adapdata(adap);
167*4882a593Smuzhiyun int status, status2;
168*4882a593Smuzhiyun bool send_stop = true;
169*4882a593Smuzhiyun int i, j;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /*
172*4882a593Smuzhiyun * The controller supports maximum 4 byte read due to known
173*4882a593Smuzhiyun * limitation of sending STOP after every read.
174*4882a593Smuzhiyun */
175*4882a593Smuzhiyun pm_runtime_get_sync(i2cd->dev);
176*4882a593Smuzhiyun for (i = 0; i < num; i++) {
177*4882a593Smuzhiyun if (msgs[i].flags & I2C_M_RD) {
178*4882a593Smuzhiyun /* program client address before starting read */
179*4882a593Smuzhiyun writel(msgs[i].addr, i2cd->regs + I2C_MST_ADDR);
180*4882a593Smuzhiyun /* gpu_i2c_read has implicit start */
181*4882a593Smuzhiyun status = gpu_i2c_read(i2cd, msgs[i].buf, msgs[i].len);
182*4882a593Smuzhiyun if (status < 0)
183*4882a593Smuzhiyun goto exit;
184*4882a593Smuzhiyun } else {
185*4882a593Smuzhiyun u8 addr = i2c_8bit_addr_from_msg(msgs + i);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun status = gpu_i2c_start(i2cd);
188*4882a593Smuzhiyun if (status < 0) {
189*4882a593Smuzhiyun if (i == 0)
190*4882a593Smuzhiyun send_stop = false;
191*4882a593Smuzhiyun goto exit;
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun status = gpu_i2c_write(i2cd, addr);
195*4882a593Smuzhiyun if (status < 0)
196*4882a593Smuzhiyun goto exit;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun for (j = 0; j < msgs[i].len; j++) {
199*4882a593Smuzhiyun status = gpu_i2c_write(i2cd, msgs[i].buf[j]);
200*4882a593Smuzhiyun if (status < 0)
201*4882a593Smuzhiyun goto exit;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun send_stop = false;
206*4882a593Smuzhiyun status = gpu_i2c_stop(i2cd);
207*4882a593Smuzhiyun if (status < 0)
208*4882a593Smuzhiyun goto exit;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun status = i;
211*4882a593Smuzhiyun exit:
212*4882a593Smuzhiyun if (send_stop) {
213*4882a593Smuzhiyun status2 = gpu_i2c_stop(i2cd);
214*4882a593Smuzhiyun if (status2 < 0)
215*4882a593Smuzhiyun dev_err(i2cd->dev, "i2c stop failed %d\n", status2);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun pm_runtime_mark_last_busy(i2cd->dev);
218*4882a593Smuzhiyun pm_runtime_put_autosuspend(i2cd->dev);
219*4882a593Smuzhiyun return status;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun static const struct i2c_adapter_quirks gpu_i2c_quirks = {
223*4882a593Smuzhiyun .max_read_len = 4,
224*4882a593Smuzhiyun .max_comb_2nd_msg_len = 4,
225*4882a593Smuzhiyun .flags = I2C_AQ_COMB_WRITE_THEN_READ,
226*4882a593Smuzhiyun };
227*4882a593Smuzhiyun
gpu_i2c_functionality(struct i2c_adapter * adap)228*4882a593Smuzhiyun static u32 gpu_i2c_functionality(struct i2c_adapter *adap)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun static const struct i2c_algorithm gpu_i2c_algorithm = {
234*4882a593Smuzhiyun .master_xfer = gpu_i2c_master_xfer,
235*4882a593Smuzhiyun .functionality = gpu_i2c_functionality,
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /*
239*4882a593Smuzhiyun * This driver is for Nvidia GPU cards with USB Type-C interface.
240*4882a593Smuzhiyun * We want to identify the cards using vendor ID and class code only
241*4882a593Smuzhiyun * to avoid dependency of adding product id for any new card which
242*4882a593Smuzhiyun * requires this driver.
243*4882a593Smuzhiyun * Currently there is no class code defined for UCSI device over PCI
244*4882a593Smuzhiyun * so using UNKNOWN class for now and it will be updated when UCSI
245*4882a593Smuzhiyun * over PCI gets a class code.
246*4882a593Smuzhiyun * There is no other NVIDIA cards with UNKNOWN class code. Even if the
247*4882a593Smuzhiyun * driver gets loaded for an undesired card then eventually i2c_read()
248*4882a593Smuzhiyun * (initiated from UCSI i2c_client) will timeout or UCSI commands will
249*4882a593Smuzhiyun * timeout.
250*4882a593Smuzhiyun */
251*4882a593Smuzhiyun #define PCI_CLASS_SERIAL_UNKNOWN 0x0c80
252*4882a593Smuzhiyun static const struct pci_device_id gpu_i2c_ids[] = {
253*4882a593Smuzhiyun { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
254*4882a593Smuzhiyun PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00},
255*4882a593Smuzhiyun { }
256*4882a593Smuzhiyun };
257*4882a593Smuzhiyun MODULE_DEVICE_TABLE(pci, gpu_i2c_ids);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun static const struct property_entry ccgx_props[] = {
260*4882a593Smuzhiyun /* Use FW built for NVIDIA (nv) only */
261*4882a593Smuzhiyun PROPERTY_ENTRY_U16("ccgx,firmware-build", ('n' << 8) | 'v'),
262*4882a593Smuzhiyun { }
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun
gpu_populate_client(struct gpu_i2c_dev * i2cd,int irq)265*4882a593Smuzhiyun static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun i2cd->gpu_ccgx_ucsi = devm_kzalloc(i2cd->dev,
268*4882a593Smuzhiyun sizeof(*i2cd->gpu_ccgx_ucsi),
269*4882a593Smuzhiyun GFP_KERNEL);
270*4882a593Smuzhiyun if (!i2cd->gpu_ccgx_ucsi)
271*4882a593Smuzhiyun return -ENOMEM;
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun strlcpy(i2cd->gpu_ccgx_ucsi->type, "ccgx-ucsi",
274*4882a593Smuzhiyun sizeof(i2cd->gpu_ccgx_ucsi->type));
275*4882a593Smuzhiyun i2cd->gpu_ccgx_ucsi->addr = 0x8;
276*4882a593Smuzhiyun i2cd->gpu_ccgx_ucsi->irq = irq;
277*4882a593Smuzhiyun i2cd->gpu_ccgx_ucsi->properties = ccgx_props;
278*4882a593Smuzhiyun i2cd->ccgx_client = i2c_new_client_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi);
279*4882a593Smuzhiyun return PTR_ERR_OR_ZERO(i2cd->ccgx_client);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
gpu_i2c_probe(struct pci_dev * pdev,const struct pci_device_id * id)282*4882a593Smuzhiyun static int gpu_i2c_probe(struct pci_dev *pdev, const struct pci_device_id *id)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun struct gpu_i2c_dev *i2cd;
285*4882a593Smuzhiyun int status;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun i2cd = devm_kzalloc(&pdev->dev, sizeof(*i2cd), GFP_KERNEL);
288*4882a593Smuzhiyun if (!i2cd)
289*4882a593Smuzhiyun return -ENOMEM;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun i2cd->dev = &pdev->dev;
292*4882a593Smuzhiyun dev_set_drvdata(&pdev->dev, i2cd);
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun status = pcim_enable_device(pdev);
295*4882a593Smuzhiyun if (status < 0) {
296*4882a593Smuzhiyun dev_err(&pdev->dev, "pcim_enable_device failed %d\n", status);
297*4882a593Smuzhiyun return status;
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun pci_set_master(pdev);
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun i2cd->regs = pcim_iomap(pdev, 0, 0);
303*4882a593Smuzhiyun if (!i2cd->regs) {
304*4882a593Smuzhiyun dev_err(&pdev->dev, "pcim_iomap failed\n");
305*4882a593Smuzhiyun return -ENOMEM;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun status = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
309*4882a593Smuzhiyun if (status < 0) {
310*4882a593Smuzhiyun dev_err(&pdev->dev, "pci_alloc_irq_vectors err %d\n", status);
311*4882a593Smuzhiyun return status;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun
314*4882a593Smuzhiyun gpu_enable_i2c_bus(i2cd);
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun i2c_set_adapdata(&i2cd->adapter, i2cd);
317*4882a593Smuzhiyun i2cd->adapter.owner = THIS_MODULE;
318*4882a593Smuzhiyun strlcpy(i2cd->adapter.name, "NVIDIA GPU I2C adapter",
319*4882a593Smuzhiyun sizeof(i2cd->adapter.name));
320*4882a593Smuzhiyun i2cd->adapter.algo = &gpu_i2c_algorithm;
321*4882a593Smuzhiyun i2cd->adapter.quirks = &gpu_i2c_quirks;
322*4882a593Smuzhiyun i2cd->adapter.dev.parent = &pdev->dev;
323*4882a593Smuzhiyun status = i2c_add_adapter(&i2cd->adapter);
324*4882a593Smuzhiyun if (status < 0)
325*4882a593Smuzhiyun goto free_irq_vectors;
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun status = gpu_populate_client(i2cd, pdev->irq);
328*4882a593Smuzhiyun if (status < 0) {
329*4882a593Smuzhiyun dev_err(&pdev->dev, "gpu_populate_client failed %d\n", status);
330*4882a593Smuzhiyun goto del_adapter;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun pm_runtime_set_autosuspend_delay(&pdev->dev, 3000);
334*4882a593Smuzhiyun pm_runtime_use_autosuspend(&pdev->dev);
335*4882a593Smuzhiyun pm_runtime_put_autosuspend(&pdev->dev);
336*4882a593Smuzhiyun pm_runtime_allow(&pdev->dev);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun return 0;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun del_adapter:
341*4882a593Smuzhiyun i2c_del_adapter(&i2cd->adapter);
342*4882a593Smuzhiyun free_irq_vectors:
343*4882a593Smuzhiyun pci_free_irq_vectors(pdev);
344*4882a593Smuzhiyun return status;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun
gpu_i2c_remove(struct pci_dev * pdev)347*4882a593Smuzhiyun static void gpu_i2c_remove(struct pci_dev *pdev)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun struct gpu_i2c_dev *i2cd = dev_get_drvdata(&pdev->dev);
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun pm_runtime_get_noresume(i2cd->dev);
352*4882a593Smuzhiyun i2c_del_adapter(&i2cd->adapter);
353*4882a593Smuzhiyun pci_free_irq_vectors(pdev);
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /*
357*4882a593Smuzhiyun * We need gpu_i2c_suspend() even if it is stub, for runtime pm to work
358*4882a593Smuzhiyun * correctly. Without it, lspci shows runtime pm status as "D0" for the card.
359*4882a593Smuzhiyun * Documentation/power/pci.rst also insists for driver to provide this.
360*4882a593Smuzhiyun */
gpu_i2c_suspend(struct device * dev)361*4882a593Smuzhiyun static __maybe_unused int gpu_i2c_suspend(struct device *dev)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun return 0;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
gpu_i2c_resume(struct device * dev)366*4882a593Smuzhiyun static __maybe_unused int gpu_i2c_resume(struct device *dev)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun struct gpu_i2c_dev *i2cd = dev_get_drvdata(dev);
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun gpu_enable_i2c_bus(i2cd);
371*4882a593Smuzhiyun /*
372*4882a593Smuzhiyun * Runtime resume ccgx client so that it can see for any
373*4882a593Smuzhiyun * connector change event. Old ccg firmware has known
374*4882a593Smuzhiyun * issue of not triggering interrupt when a device is
375*4882a593Smuzhiyun * connected to runtime resume the controller.
376*4882a593Smuzhiyun */
377*4882a593Smuzhiyun pm_request_resume(&i2cd->ccgx_client->dev);
378*4882a593Smuzhiyun return 0;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun static UNIVERSAL_DEV_PM_OPS(gpu_i2c_driver_pm, gpu_i2c_suspend, gpu_i2c_resume,
382*4882a593Smuzhiyun NULL);
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun static struct pci_driver gpu_i2c_driver = {
385*4882a593Smuzhiyun .name = "nvidia-gpu",
386*4882a593Smuzhiyun .id_table = gpu_i2c_ids,
387*4882a593Smuzhiyun .probe = gpu_i2c_probe,
388*4882a593Smuzhiyun .remove = gpu_i2c_remove,
389*4882a593Smuzhiyun .driver = {
390*4882a593Smuzhiyun .pm = &gpu_i2c_driver_pm,
391*4882a593Smuzhiyun },
392*4882a593Smuzhiyun };
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun module_pci_driver(gpu_i2c_driver);
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun MODULE_AUTHOR("Ajay Gupta <ajayg@nvidia.com>");
397*4882a593Smuzhiyun MODULE_DESCRIPTION("Nvidia GPU I2C controller Driver");
398*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
399