static int hisi_thermal_register_sensor(struct platform_device *pdev, struct hisi_thermal_data *data, struct hisi_thermal_sensor *sensor, int index) { int ret, i; const struct thermal_trip *trip; sensor->id = index; sensor->thermal = data; sensor->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev, sensor->id, sensor, &hisi_of_thermal_ops); if (IS_ERR(sensor->tzd)) { ret = PTR_ERR(sensor->tzd); sensor->tzd = NULL; dev_err(&pdev->dev, "failed to register sensor id %d: %d\n", sensor->id, ret); return ret; } trip = of_thermal_get_trip_points(sensor->tzd); for (i = 0; i < of_thermal_get_ntrips(sensor->tzd); i++) { if (trip[i].type == THERMAL_TRIP_PASSIVE) { sensor->thres_temp = trip[i].temperature; break; } } return 0; }
static int uniphier_tm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct regmap *regmap; struct device_node *parent; struct uniphier_tm_dev *tdev; const struct thermal_trip *trips; int i, ret, irq, ntrips, crit_temp = INT_MAX; tdev = devm_kzalloc(dev, sizeof(*tdev), GFP_KERNEL); if (!tdev) return -ENOMEM; tdev->dev = dev; tdev->data = of_device_get_match_data(dev); if (WARN_ON(!tdev->data)) return -EINVAL; irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; /* get regmap from syscon node */ parent = of_get_parent(dev->of_node); /* parent should be syscon node */ regmap = syscon_node_to_regmap(parent); of_node_put(parent); if (IS_ERR(regmap)) { dev_err(dev, "failed to get regmap (error %ld)\n", PTR_ERR(regmap)); return PTR_ERR(regmap); } tdev->regmap = regmap; ret = uniphier_tm_initialize_sensor(tdev); if (ret) { dev_err(dev, "failed to initialize sensor\n"); return ret; } ret = devm_request_threaded_irq(dev, irq, uniphier_tm_alarm_irq, uniphier_tm_alarm_irq_thread, 0, "thermal", tdev); if (ret) return ret; platform_set_drvdata(pdev, tdev); tdev->tz_dev = devm_thermal_zone_of_sensor_register(dev, 0, tdev, &uniphier_of_thermal_ops); if (IS_ERR(tdev->tz_dev)) { dev_err(dev, "failed to register sensor device\n"); return PTR_ERR(tdev->tz_dev); } /* get trip points */ trips = of_thermal_get_trip_points(tdev->tz_dev); ntrips = of_thermal_get_ntrips(tdev->tz_dev); if (ntrips > ALERT_CH_NUM) { dev_err(dev, "thermal zone has too many trips\n"); return -E2BIG; } /* set alert temperatures */ for (i = 0; i < ntrips; i++) { if (trips[i].type == THERMAL_TRIP_CRITICAL && trips[i].temperature < crit_temp) crit_temp = trips[i].temperature; uniphier_tm_set_alert(tdev, i, trips[i].temperature); tdev->alert_en[i] = true; } if (crit_temp > CRITICAL_TEMP_LIMIT) { dev_err(dev, "critical trip is over limit(>%d), or not set\n", CRITICAL_TEMP_LIMIT); return -EINVAL; } uniphier_tm_enable_sensor(tdev); return 0; }
static int rcar_gen3_thermal_probe(struct platform_device *pdev) { struct rcar_gen3_thermal_priv *priv; struct device *dev = &pdev->dev; struct resource *res; struct thermal_zone_device *zone; int ret, irq, i; char *irqname; /* default values if FUSEs are missing */ /* TODO: Read values from hardware on supported platforms */ int ptat[3] = { 2631, 1509, 435 }; int thcode[TSC_MAX_NUM][3] = { { 3397, 2800, 2221 }, { 3393, 2795, 2216 }, { 3389, 2805, 2237 }, }; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->thermal_init = rcar_gen3_thermal_init; if (soc_device_match(r8a7795es1)) priv->thermal_init = rcar_gen3_thermal_init_r8a7795es1; spin_lock_init(&priv->lock); platform_set_drvdata(pdev, priv); /* * Request 2 (of the 3 possible) IRQs, the driver only needs to * to trigger on the low and high trip points of the current * temp window at this point. */ for (i = 0; i < 2; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) return irq; irqname = devm_kasprintf(dev, GFP_KERNEL, "%s:ch%d", dev_name(dev), i); if (!irqname) return -ENOMEM; ret = devm_request_threaded_irq(dev, irq, rcar_gen3_thermal_irq, rcar_gen3_thermal_irq_thread, IRQF_SHARED, irqname, priv); if (ret) return ret; } pm_runtime_enable(dev); pm_runtime_get_sync(dev); for (i = 0; i < TSC_MAX_NUM; i++) { struct rcar_gen3_thermal_tsc *tsc; res = platform_get_resource(pdev, IORESOURCE_MEM, i); if (!res) break; tsc = devm_kzalloc(dev, sizeof(*tsc), GFP_KERNEL); if (!tsc) { ret = -ENOMEM; goto error_unregister; } tsc->base = devm_ioremap_resource(dev, res); if (IS_ERR(tsc->base)) { ret = PTR_ERR(tsc->base); goto error_unregister; } priv->tscs[i] = tsc; priv->thermal_init(tsc); rcar_gen3_thermal_calc_coefs(&tsc->coef, ptat, thcode[i]); zone = devm_thermal_zone_of_sensor_register(dev, i, tsc, &rcar_gen3_tz_of_ops); if (IS_ERR(zone)) { dev_err(dev, "Can't register thermal zone\n"); ret = PTR_ERR(zone); goto error_unregister; } tsc->zone = zone; ret = of_thermal_get_ntrips(tsc->zone); if (ret < 0) goto error_unregister; dev_info(dev, "TSC%d: Loaded %d trip points\n", i, ret); } priv->num_tscs = i; if (!priv->num_tscs) { ret = -ENODEV; goto error_unregister; } rcar_thermal_irq_set(priv, true); return 0; error_unregister: rcar_gen3_thermal_remove(pdev); return ret; }