Hi Andy, > > Latest NVIDIA GPU card has USB Type-C interface. There is a > > Type-C controller which can be accessed over I2C. > > > > This driver add I2C bus driver to communicate with Type-C controller. > > I2C client driver will be part of USB Type-C UCSI driver. > > > drivers/i2c/busses/i2c-gpu.c | 493 > +++++++++++++++++++++++++++++++++++++++ > > Can we got more better name, which includes vendor and/or model of the I2C > host? Sure will change to i2c-nvidia-gpu.c > > +/* STATUS definitions */ > > +#define STATUS_SUCCESS 0 > > +#define STATUS_UNSUCCESSFUL 0x80000000UL > > +#define STATUS_TIMEOUT 0x80000001UL > > +#define STATUS_IO_DEVICE_ERROR 0x80000002UL > > +#define STATUS_IO_TIMEOUT 0x80000004UL > > +#define STATUS_IO_PREEMPTED 0x80000008UL > > Looks slightly different from my point of view, something like > > /* Bit 31 shows error condition while LSB encodes the error code */ > STATUS_TIMEOUT BIT(0) > ... > STATUS_ERROR BIT(31) Will fix. > > + dev_dbg(dev, "%s: %p (I2C_MST_HYBRID_PADCTL) <- %08x", __func__, > > + (gdev->regs + I2C_MST_HYBRID_PADCTL), val); > > Parens are redundant, __func__ is redundant. Will fix. > > + dev_dbg(dev, "%s: %p (I2C_MST_I2C0_TIMING) <- %08x", __func__, > > + gdev->regs + I2C_MST_I2C0_TIMING, val); > > Ditto. Check your debug messages, and perheps even drop some. Will fix. > > +static u32 i2c_check_status(struct gpu_i2c_dev *gdev) > > +{ > > > + while (time_is_after_jiffies(target)) { > > + } > > For functions like this better to get in a form > do { > } while(). Ok, will fix. > There is no guarantee that it runs even once in your case. > > > + dev_err(dev, "%si2c timeout", __func__); > > No space? Ok, will fix. > > > + val = readl(gdev->regs + I2C_MST_DATA); > > + switch (len) { > > + case 1: > > + data[0] = (val >> 0) & 0xff; > > + break; > > + case 2: > > + data[0] = (val >> 8) & 0xff; > > + data[1] = (val >> 0) & 0xff; > > + break; > > + case 3: > > + data[0] = (val >> 16) & 0xff; > > + data[1] = (val >> 8) & 0xff; > > + data[2] = (val >> 0) & 0xff; > > + break; > > + case 4: > > + data[0] = (val >> 24) & 0xff; > > + data[1] = (val >> 16) & 0xff; > > + data[2] = (val >> 8) & 0xff; > > + data[3] = (val >> 0) & 0xff; > > + break; > > Redundant & 0xff. > We have get_unaligned*(), put_unaligned*() and many variations of > cpu_to_Xe*() and Xe*_to_cpu(). Ok, will fix. > > > + u32 val = 0; > > Redundant assignment. Ok, will fix. > > > + val = addr << I2C_MST_ADDR_DAB; > > > + val = 0; > > Ditto. What's wrong with assign value below directly? > > > + val |= I2C_MST_CNTL_GEN_START | I2C_MST_CNTL_CMD_NONE | > > + I2C_MST_CNTL_GEN_NACK; > > > + u32 val = 0; > > Check your code for these kind of style mistakes. > > > +/* gdev i2c adapter */ > > Pointless. > > > +static int gpu_i2c_master_xfer(struct i2c_adapter *adap, > > + struct i2c_msg *msgs, int num) > > +{ > > + struct gpu_i2c_dev *gdev = i2c_get_adapdata(adap); > > + struct device *dev = &gdev->pci_dev->dev; > > + int retry1b = 10; > > + u32 status; > > + int i, j; > > > + goto exit; > > +exit_stop: > > + status = i2c_manual_stop(gdev); > > + if (status != STATUS_SUCCESS) > > + dev_err(dev, "i2c_manual_stop failed %x", status); > > +exit: > > + mutex_unlock(&gdev->mutex); > > + return i; > > +} > > Ouch! Besides many small style issues and redundancy (like __LINE__), > this function needs to be refactored to few smaller and readable ones. Ok, will fix. > > > +#define PCI_CLASS_SERIAL_UNKNOWN 0x0c80 > > > +/* pci driver */ > > Pointless. Ok, will fix. > > > +static const struct pci_device_id gpu_i2c_ids[] = { > > + { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, > > + PCI_CLASS_SERIAL_UNKNOWN << 8, 0xffffff00}, > > Are you sure?! Yes, we want to identify using vendor ID and class code. Currently there is no class code defined for UCSI device over PCI so using UNKNOWN. > > > + { }, > > Terminator line better w/o comma. Ok, will fix. > > > +}; > > +MODULE_DEVICE_TABLE(pci, gpu_i2c_ids); > > > +static int gpu_i2c_probe(struct pci_dev *dev, const struct pci_device_id > *id) > > +{ > > + struct gpu_i2c_dev *gdev; > > + int status; > > + > > > + dev_info(&dev->dev, > > + "dev %p id %08x %08x sub %08x %08x class %08x %08x\n", > > + dev, id->vendor, id->device, id->subvendor, id->subdevice, > > + id->class, id->class_mask); > > Useless. We have PCI core printed this information out several times > during the boot or, if card is hotpluggable, when it's plugged in. Ok, will fix. > > > + gdev = devm_kzalloc(&dev->dev, sizeof(struct gpu_i2c_dev), > GFP_KERNEL); > > + if (!gdev) > > + return -ENOMEM; > > > + status = pci_enable_device(dev); > > Using devm_ without pcim_ sound slightly inconsistent. Ok, will fix. > > > + status = pci_enable_msi(dev); > > This done in the other way. Check pci_alloc_irq_vectors(), IIRC. sure, will fix. > > > +i2c_init_err: > > + pci_disable_msi(dev); > > +enable_msi_err: > > + pci_iounmap(dev, gdev->regs); > > +iomap_err: > > + pci_disable_device(dev); > > At least above will gone after switching to pcim_ > > > + pci_disable_msi(dev); > > + pci_iounmap(dev, gdev->regs); > > Same. > > > + dev_dbg(dev, "%s\n", __func__); > > Pointless. We have ftrace, for example to see this. > > > + dev_dbg(dev, "%s\n", __func__); > > Ditto. > > Thanks Ajay -- nvpublic -- > -- > With Best Regards, > Andy Shevchenko