diff --git a/drivers/pwm/pwm-tegra-tachometer.c b/drivers/pwm/pwm-tegra-tachometer.c index 46cb8b9a..f5e38c72 100644 --- a/drivers/pwm/pwm-tegra-tachometer.c +++ b/drivers/pwm/pwm-tegra-tachometer.c @@ -12,7 +12,9 @@ #include #include #include -#define DRIVER_NAME "pwm-tach" +#include +#include +#define DRIVER_NAME "pwm_tach" /* Since oscillator clock (38.4MHz) serves as a clock source for * the tach input controller, 1.0105263MHz (i.e. 38.4/38) has to be @@ -91,6 +93,37 @@ struct pwm_tegra_tach { const struct pwm_tegra_tach_soc_data *soc_data; }; +static ssize_t rpm_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct pwm_tegra_tach *ptt = dev_get_drvdata(dev); + struct pwm_device *pwm = &ptt->chip.pwms[0]; + struct pwm_capture result; + unsigned int rpm = 0; + int ret; + + ret = pwm_capture(pwm, &result, 0); + if (ret < 0) { + dev_err(ptt->dev, "Failed to capture PWM: %d\n", ret); + return ret; + } + + if (result.period) + rpm = DIV_ROUND_CLOSEST_ULL(60ULL * NSEC_PER_SEC, + result.period); + + return sprintf(buf, "%u\n", rpm); +} + +static DEVICE_ATTR_RO(rpm); + +static struct attribute *pwm_tach_attrs[] = { + &dev_attr_rpm.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(pwm_tach); + static struct pwm_tegra_tach *to_tegra_pwm_chip(struct pwm_chip *chip) { return container_of(chip, struct pwm_tegra_tach, chip); @@ -299,6 +332,7 @@ static int pwm_tegra_tach_probe(struct platform_device *pdev) { struct pwm_tegra_tach *ptt; struct pwm_device *pwm; + struct device *hwmon; struct resource *r; int ret; @@ -353,7 +387,11 @@ static int pwm_tegra_tach_probe(struct platform_device *pdev) goto clk_unprep; } - reset_control_reset(ptt->rst); + ret = reset_control_reset(ptt->rst); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to reset: %d\n", ret); + goto clk_unprep; + } if (ptt->soc_data->has_interrupt_support) { ptt->irq = platform_get_irq(pdev, 0); @@ -413,6 +451,13 @@ static int pwm_tegra_tach_probe(struct platform_device *pdev) TACH_FAN_ENABLE_INTERRUPT_SHIFT); } + + hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, DRIVER_NAME, ptt, pwm_tach_groups); + if (IS_ERR(hwmon)) { + dev_warn(&pdev->dev, "Failed to register hwmon device: %d\n", PTR_ERR_OR_ZERO(hwmon)); + dev_warn(&pdev->dev, "Tegra Tachometer got registered witout hwmon sysfs support\n"); + } + return 0; pwm_remove: @@ -472,7 +517,7 @@ static struct pwm_tegra_tach_soc_data tegra194_tach_soc_data = { }; static struct pwm_tegra_tach_soc_data tegra234_tach_soc_data = { - .has_interrupt_support = true, + .has_interrupt_support = false, }; static const struct of_device_id pwm_tegra_tach_of_match[] = {