int nvkm_fanpwm_create(struct nvkm_therm *therm, struct dcb_gpio_func *func) { struct nvkm_device *device = nv_device(therm); struct nvkm_therm_priv *tpriv = (void *)therm; struct nvkm_bios *bios = nvkm_bios(therm); struct nvkm_fanpwm_priv *priv; struct nvbios_therm_fan fan; u32 divs, duty; nvbios_fan_parse(bios, &fan); if (!nvkm_boolopt(device->cfgopt, "NvFanPWM", func->param) || !therm->pwm_ctrl || fan.type == NVBIOS_THERM_FAN_TOGGLE || therm->pwm_get(therm, func->line, &divs, &duty) == -ENODEV) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); tpriv->fan = &priv->base; if (!priv) return -ENOMEM; priv->base.type = "PWM"; priv->base.get = nvkm_fanpwm_get; priv->base.set = nvkm_fanpwm_set; priv->func = *func; return 0; }
int nvkm_i2c_port_create_(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, u8 index, const struct i2c_algorithm *algo, const struct nvkm_i2c_func *func, int size, void **pobject) { struct nvkm_device *device = nv_device(parent); struct nvkm_i2c *i2c = nvkm_i2c(parent); struct nvkm_i2c_port *port; int ret; ret = nvkm_object_create_(parent, engine, oclass, 0, size, pobject); port = *pobject; if (ret) return ret; snprintf(port->adapter.name, sizeof(port->adapter.name), "nvkm-%s-%d", device->name, index); port->adapter.owner = THIS_MODULE; port->adapter.dev.parent = nv_device_base(device); port->index = index; port->aux = -1; port->func = func; mutex_init(&port->mutex); if ( algo == &nvkm_i2c_bit_algo && !nvkm_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) { struct i2c_algo_bit_data *bit; bit = kzalloc(sizeof(*bit), GFP_KERNEL); if (!bit) return -ENOMEM; bit->udelay = 10; bit->timeout = usecs_to_jiffies(2200); bit->data = port; bit->pre_xfer = nvkm_i2c_pre_xfer; bit->post_xfer = nvkm_i2c_post_xfer; bit->setsda = nvkm_i2c_setsda; bit->setscl = nvkm_i2c_setscl; bit->getsda = nvkm_i2c_getsda; bit->getscl = nvkm_i2c_getscl; port->adapter.algo_data = bit; ret = i2c_bit_add_bus(&port->adapter); } else { port->adapter.algo_data = port; port->adapter.algo = algo; ret = i2c_add_adapter(&port->adapter); } if (ret == 0) list_add_tail(&port->head, &i2c->ports); return ret; }
int nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device, int index, struct nvkm_pci **ppci) { struct nvkm_pci *pci; if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_pci_func, device, index, &pci->subdev); pci->func = func; pci->pdev = device->func->pci(device)->pdev; pci->irq = -1; pci->pcie.speed = -1; pci->pcie.width = -1; if (device->type == NVKM_DEVICE_AGP) nvkm_agp_ctor(pci); switch (pci->pdev->device & 0x0ff0) { case 0x00f0: case 0x02e0: /* BR02? NFI how these would be handled yet exactly */ break; default: switch (device->chipset) { case 0xaa: /* reported broken, nv also disable it */ break; default: pci->msi = true; break; } } #ifdef __BIG_ENDIAN pci->msi = false; #endif pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi); if (pci->msi && func->msi_rearm) { pci->msi = pci_enable_msi(pci->pdev) == 0; if (pci->msi) nvkm_debug(&pci->subdev, "MSI enabled\n"); } else { pci->msi = false; } return 0; }
int nvkm_engine_ctor(const struct nvkm_engine_func *func, struct nvkm_device *device, int index, u32 pmc_enable, bool enable, struct nvkm_engine *engine) { nvkm_subdev_ctor(&nvkm_engine_func, device, index, pmc_enable, &engine->subdev); engine->func = func; if (!nvkm_boolopt(device->cfgopt, nvkm_subdev_name[index], enable)) { nvkm_debug(&engine->subdev, "disabled\n"); return -ENODEV; } spin_lock_init(&engine->lock); return 0; }