int nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) { struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_device *device = nv_device(therm); static const char *name[] = { "disabled", "manual", "automatic" }; /* The default PPWR ucode on fermi interferes with fan management */ if ((mode >= ARRAY_SIZE(name)) || (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0 && !nouveau_subdev(device, NVDEV_SUBDEV_PWR))) return -EINVAL; /* do not allow automatic fan management if the thermal sensor is * not available */ if (mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0) return -EINVAL; if (priv->mode == mode) return 0; nv_info(therm, "fan management: %s\n", name[mode]); nouveau_therm_update(therm, mode); return 0; }
static irqreturn_t nouveau_mc_intr(int irq, void *arg) { struct nouveau_mc *pmc = arg; const struct nouveau_mc_intr *map = pmc->intr_map; struct nouveau_subdev *unit; u32 stat, intr; intr = stat = nv_rd32(pmc, 0x000100); while (stat && map->stat) { if (stat & map->stat) { unit = nouveau_subdev(pmc, map->unit); if (unit && unit->intr) unit->intr(unit); intr &= ~map->stat; } map++; } if (intr) { nv_error(pmc, "unknown intr 0x%08x\n", stat); } return stat ? IRQ_HANDLED : IRQ_NONE; }
static irqreturn_t nouveau_mc_intr(int irq, void *arg) #endif { struct nouveau_mc *pmc = arg; const struct nouveau_mc_oclass *oclass = (void *)nv_object(pmc)->oclass; const struct nouveau_mc_intr *map = oclass->intr; struct nouveau_subdev *unit; u32 intr; nv_wr32(pmc, 0x000140, 0x00000000); nv_rd32(pmc, 0x000140); intr = nouveau_mc_intr_mask(pmc); if (pmc->use_msi) oclass->msi_rearm(pmc); if (intr) { u32 stat = intr = nouveau_mc_intr_mask(pmc); while (map->stat) { if (intr & map->stat) { unit = nouveau_subdev(pmc, map->unit); if (unit && unit->intr) unit->intr(unit); stat &= ~map->stat; } map++; } if (stat) nv_error(pmc, "unknown intr 0x%08x\n", stat); } nv_wr32(pmc, 0x000140, 0x00000001); #ifdef __NetBSD__ return intr ? 1 : 0; #else return intr ? IRQ_HANDLED : IRQ_NONE; #endif }