static int omap_temp_sensor_resume(struct platform_device *pdev) { struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); omap_temp_sensor_enable(temp_sensor); return 0; }
void omap_temp_sensor_idle(int idle_state) { if (!temp_sensor_pm) return; if (idle_state) omap_temp_sensor_disable(temp_sensor_pm); else omap_temp_sensor_enable(temp_sensor_pm); }
void omap_temp_sensor_idle(int idle_state) { if (!cpu_is_omap446x() && !cpu_is_omap447x()) return; if (idle_state) omap_temp_sensor_disable(temp_sensor_pm); else omap_temp_sensor_enable(temp_sensor_pm); }
static int omap_temp_sensor_resume(struct platform_device *pdev) { struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); omap_temp_sensor_enable(temp_sensor); /* Restart Polling */ schedule_delayed_work(&temp_sensor->temp_poll_work, msecs_to_jiffies(POLL_DELAY_MS)); return 0; }
static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0; if (!pdata) { dev_err(dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "%s:no mem resource\n", __func__); dump_stack(); ret = -EINVAL; goto plat_res_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } platform_set_drvdata(pdev, temp_sensor); ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } omap_enable_continuous_mode(temp_sensor); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_read_current_temp(temp_sensor); /* Initialize Polling work queue*/ INIT_DELAYED_WORK(&temp_sensor->temp_poll_work, temp_poll_work_fn); schedule_delayed_work(&temp_sensor->temp_poll_work, msecs_to_jiffies(POLL_DELAY_MS)); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sensor_enable_err; } ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section1_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section2_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section3_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section4_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_section5_group); if (ret) dev_err(&pdev->dev, "could not create section sysfs files\n"); dev_info(dev, "%s probed", pdata->name); temp_sensor_pm = temp_sensor; return 0; sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(dev); plat_res_err: kfree(temp_sensor); return ret; }
static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0, val; if (!pdata) { dev_err(&pdev->dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mutex_init(&temp_sensor->sensor_mutex); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "%s:no mem resource\n", __func__); ret = -EINVAL; goto plat_res_err; } temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert"); if (temp_sensor->irq < 0) { dev_err(&pdev->dev, "%s:Cannot get thermal alert irq\n", __func__); ret = -EINVAL; goto get_irq_err; } ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN, "thermal_shutdown"); if (ret) { dev_err(&pdev->dev, "%s: Could not get tshut_gpio\n", __func__); goto tshut_gpio_req_err; } temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO); if (temp_sensor->tshut_irq < 0) { dev_err(&pdev->dev, "%s:Cannot get thermal shutdown irq\n", __func__); ret = -EINVAL; goto get_tshut_irq_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); kobject_uevent(&pdev->dev.kobj, KOBJ_ADD); platform_set_drvdata(pdev, temp_sensor); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(&pdev->dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } temp_sensor->therm_fw = kzalloc(sizeof(struct thermal_dev), GFP_KERNEL); if (temp_sensor->therm_fw) { temp_sensor->therm_fw->name = "omap_ondie_sensor"; temp_sensor->therm_fw->domain_name = "cpu"; temp_sensor->therm_fw->dev = temp_sensor->dev; temp_sensor->therm_fw->dev_ops = &omap_sensor_ops; thermal_sensor_dev_register(temp_sensor->therm_fw); } else { dev_err(&pdev->dev, "%s:Cannot alloc memory for thermal fw\n", __func__); ret = -ENOMEM; goto therm_fw_alloc_err; } omap_enable_continuous_mode(temp_sensor, 1); omap_configure_temp_sensor_thresholds(temp_sensor); /* 1 ms */ omap_configure_temp_sensor_counter(temp_sensor, 1); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_report_temp(temp_sensor->therm_fw); /* Set 250 milli-seconds time as default counter */ omap_configure_temp_sensor_counter(temp_sensor, temp_sensor->clk_rate * 250 / 1000); ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sysfs_create_err; } ret = request_threaded_irq(temp_sensor->irq, NULL, omap_talert_irq_handler, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "temp_sensor", (void *)temp_sensor); if (ret) { dev_err(&pdev->dev, "Request threaded irq failed.\n"); goto req_irq_err; } ret = request_threaded_irq(temp_sensor->tshut_irq, NULL, omap_tshut_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tshut", (void *)temp_sensor); if (ret) { dev_err(&pdev->dev, "Request threaded irq failed for TSHUT.\n"); goto tshut_irq_req_err; } /* unmask the T_COLD and unmask T_HOT at init */ val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); val |= OMAP4_MASK_COLD_MASK; val |= OMAP4_MASK_HOT_MASK; omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); dev_info(&pdev->dev, "%s : '%s'\n", temp_sensor->therm_fw->name, pdata->name); temp_sensor_pm = temp_sensor; return 0; tshut_irq_req_err: free_irq(temp_sensor->irq, temp_sensor); req_irq_err: kobject_uevent(&temp_sensor->dev->kobj, KOBJ_REMOVE); sysfs_remove_group(&temp_sensor->dev->kobj, &omap_temp_sensor_group); sysfs_create_err: thermal_sensor_dev_unregister(temp_sensor->therm_fw); kfree(temp_sensor->therm_fw); if (temp_sensor->clock) clk_put(temp_sensor->clock); platform_set_drvdata(pdev, NULL); therm_fw_alloc_err: omap_temp_sensor_disable(temp_sensor); sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(&pdev->dev); get_tshut_irq_err: gpio_free(OMAP_TSHUT_GPIO); tshut_gpio_req_err: get_irq_err: plat_res_err: mutex_destroy(&temp_sensor->sensor_mutex); kfree(temp_sensor); return ret; }
/* * Check if the die sensor is cooling down. If it's higher than * t_hot since the last throttle then throttle it again. * OMAP junction temperature could stay for a long time in an * unacceptable temperature range. The idea here is to check after * t_hot->throttle the system really came below t_hot else re-throttle * and keep doing till it's under t_hot temp range. */ static void throttle_delayed_work_fn(struct work_struct *work) { int curr; struct omap_temp_sensor *temp_sensor = container_of(work, struct omap_temp_sensor, throttle_work.work); curr = omap_read_current_temp(temp_sensor); #ifdef CONFIG_OMAP_TEMP_CONTROL if (curr >= temp_limit || curr < 0) { #else if (curr >= BGAP_THRESHOLD_T_HOT || curr < 0) { #endif pr_warn("%s: OMAP temp read %d exceeds the threshold\n", __func__, curr); omap_thermal_throttle(); schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); } else { schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); } } static irqreturn_t omap_tshut_irq_handler(int irq, void *data) { struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; /* Need to handle thermal mgmt in bootloader * to avoid restart again at kernel level */ if (temp_sensor->is_efuse_valid) { pr_emerg("%s: Thermal shutdown reached rebooting device\n", __func__); kernel_restart(NULL); } else { pr_err("%s:Invalid EFUSE, Non-trimmed BGAP\n", __func__); } return IRQ_HANDLED; } static irqreturn_t omap_talert_irq_handler(int irq, void *data) { struct omap_temp_sensor *temp_sensor = (struct omap_temp_sensor *)data; int t_hot, t_cold, temp_offset; t_hot = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) & OMAP4_HOT_FLAG_MASK; t_cold = omap_temp_sensor_readl(temp_sensor, BGAP_STATUS_OFFSET) & OMAP4_COLD_FLAG_MASK; temp_offset = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); if (t_hot) { omap_thermal_throttle(); schedule_delayed_work(&temp_sensor->throttle_work, msecs_to_jiffies(THROTTLE_DELAY_MS)); temp_offset &= ~(OMAP4_MASK_HOT_MASK); temp_offset |= OMAP4_MASK_COLD_MASK; } else if (t_cold) { cancel_delayed_work_sync(&temp_sensor->throttle_work); omap_thermal_unthrottle(); temp_offset &= ~(OMAP4_MASK_COLD_MASK); temp_offset |= OMAP4_MASK_HOT_MASK; } omap_temp_sensor_writel(temp_sensor, temp_offset, BGAP_CTRL_OFFSET); return IRQ_HANDLED; } static int __devinit omap_temp_sensor_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct omap_temp_sensor_pdata *pdata = pdev->dev.platform_data; struct omap_temp_sensor *temp_sensor; struct resource *mem; int ret = 0, val; if (!pdata) { dev_err(dev, "%s: platform data missing\n", __func__); return -EINVAL; } temp_sensor = kzalloc(sizeof(struct omap_temp_sensor), GFP_KERNEL); if (!temp_sensor) return -ENOMEM; spin_lock_init(&temp_sensor->lock); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(dev, "%s:no mem resource\n", __func__); ret = -EINVAL; goto plat_res_err; } temp_sensor->irq = platform_get_irq_byname(pdev, "thermal_alert"); if (temp_sensor->irq < 0) { dev_err(dev, "%s:Cannot get thermal alert irq\n", __func__); ret = -EINVAL; goto get_irq_err; } ret = gpio_request_one(OMAP_TSHUT_GPIO, GPIOF_DIR_IN, "thermal_shutdown"); if (ret) { dev_err(dev, "%s: Could not get tshut_gpio\n", __func__); goto tshut_gpio_req_err; } temp_sensor->tshut_irq = gpio_to_irq(OMAP_TSHUT_GPIO); if (temp_sensor->tshut_irq < 0) { dev_err(dev, "%s:Cannot get thermal shutdown irq\n", __func__); ret = -EINVAL; goto get_tshut_irq_err; } temp_sensor->phy_base = pdata->offset; temp_sensor->pdev = pdev; temp_sensor->dev = dev; pm_runtime_enable(dev); pm_runtime_irq_safe(dev); /* * check if the efuse has a non-zero value if not * it is an untrimmed sample and the temperatures * may not be accurate */ if (omap_readl(OMAP4_CTRL_MODULE_CORE + OMAP4_CTRL_MODULE_CORE_STD_FUSE_OPP_BGAP)) temp_sensor->is_efuse_valid = 1; temp_sensor->clock = clk_get(&temp_sensor->pdev->dev, "fck"); if (IS_ERR(temp_sensor->clock)) { ret = PTR_ERR(temp_sensor->clock); pr_err("%s:Unable to get fclk: %d\n", __func__, ret); ret = -EINVAL; goto clk_get_err; } /* Init delayed work for throttle decision */ INIT_DELAYED_WORK(&temp_sensor->throttle_work, throttle_delayed_work_fn); platform_set_drvdata(pdev, temp_sensor); ret = omap_temp_sensor_enable(temp_sensor); if (ret) { dev_err(dev, "%s:Cannot enable temp sensor\n", __func__); goto sensor_enable_err; } omap_enable_continuous_mode(temp_sensor); omap_configure_temp_sensor_thresholds(temp_sensor); /* 1 ms */ omap_configure_temp_sensor_counter(temp_sensor, 1); /* Wait till the first conversion is done wait for at least 1ms */ mdelay(2); /* Read the temperature once due to hw issue*/ omap_read_current_temp(temp_sensor); /* Set 2 seconds time as default counter */ omap_configure_temp_sensor_counter(temp_sensor, temp_sensor->clk_rate * 2); ret = request_threaded_irq(temp_sensor->irq, NULL, omap_talert_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "temp_sensor", (void *)temp_sensor); if (ret) { dev_err(dev, "Request threaded irq failed.\n"); goto req_irq_err; } ret = request_threaded_irq(temp_sensor->tshut_irq, NULL, omap_tshut_irq_handler, IRQF_TRIGGER_RISING | IRQF_ONESHOT, "tshut", (void *)temp_sensor); if (ret) { dev_err(dev, "Request threaded irq failed for TSHUT.\n"); goto tshut_irq_req_err; } ret = sysfs_create_group(&pdev->dev.kobj, &omap_temp_sensor_group); if (ret) { dev_err(&pdev->dev, "could not create sysfs files\n"); goto sysfs_create_err; } /* unmask the T_COLD and unmask T_HOT at init */ val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); val |= OMAP4_MASK_COLD_MASK; val |= OMAP4_MASK_HOT_MASK; omap_temp_sensor_writel(temp_sensor, val, BGAP_CTRL_OFFSET); dev_info(dev, "%s probed", pdata->name); temp_sensor_pm = temp_sensor; #ifdef CONFIG_OMAP_TEMP_CONTROL ctrl_sensor = temp_sensor; tempcontrol_registerlimit(temp_limit); #endif return 0; sysfs_create_err: free_irq(temp_sensor->tshut_irq, temp_sensor); cancel_delayed_work_sync(&temp_sensor->throttle_work); tshut_irq_req_err: free_irq(temp_sensor->irq, temp_sensor); req_irq_err: platform_set_drvdata(pdev, NULL); omap_temp_sensor_disable(temp_sensor); sensor_enable_err: clk_put(temp_sensor->clock); clk_get_err: pm_runtime_disable(dev); get_tshut_irq_err: gpio_free(OMAP_TSHUT_GPIO); tshut_gpio_req_err: get_irq_err: plat_res_err: kfree(temp_sensor); return ret; } static int __devexit omap_temp_sensor_remove(struct platform_device *pdev) { struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); sysfs_remove_group(&pdev->dev.kobj, &omap_temp_sensor_group); cancel_delayed_work_sync(&temp_sensor->throttle_work); omap_temp_sensor_disable(temp_sensor); clk_put(temp_sensor->clock); platform_set_drvdata(pdev, NULL); if (temp_sensor->irq) free_irq(temp_sensor->irq, temp_sensor); if (temp_sensor->tshut_irq) free_irq(temp_sensor->tshut_irq, temp_sensor); kfree(temp_sensor); return 0; } #ifdef CONFIG_PM static void omap_temp_sensor_save_ctxt(struct omap_temp_sensor *temp_sensor) { temp_sensor_context.temp_sensor_ctrl = omap_temp_sensor_readl(temp_sensor, TEMP_SENSOR_CTRL_OFFSET); temp_sensor_context.bg_ctrl = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); temp_sensor_context.bg_counter = omap_temp_sensor_readl(temp_sensor, BGAP_COUNTER_OFFSET); temp_sensor_context.bg_threshold = omap_temp_sensor_readl(temp_sensor, BGAP_THRESHOLD_OFFSET); temp_sensor_context.temp_sensor_tshut_threshold = omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET); }