Re: [PATCH v1 1/2] video: fbdev: acornfb: remove free_unused_pages()

2021-01-28 Thread Oscar Salvador
On Tue, Jan 26, 2021 at 07:21:12PM +0100, David Hildenbrand wrote:
> This function is never used and it is one of the last remaining user of
> __free_reserved_page(). Let's just drop it.
> 
> Cc: Andrew Morton 
> Cc: Thomas Gleixner 
> Cc: "Peter Zijlstra (Intel)" 
> Cc: Mike Rapoport 
> Cc: Oscar Salvador 
> Cc: Michal Hocko 
> Cc: Wei Yang 
> Cc: "Gustavo A. R. Silva" 
> Cc: Sam Ravnborg 
> Signed-off-by: David Hildenbrand 

Reviewed-by: Oscar Salvador 

> ---
>  drivers/video/fbdev/acornfb.c | 34 --
>  1 file changed, 34 deletions(-)
> 
> diff --git a/drivers/video/fbdev/acornfb.c b/drivers/video/fbdev/acornfb.c
> index bcc92aecf666..1b72edc01cfb 100644
> --- a/drivers/video/fbdev/acornfb.c
> +++ b/drivers/video/fbdev/acornfb.c
> @@ -921,40 +921,6 @@ static int acornfb_detect_monitortype(void)
>   return 4;
>  }
>  
> -/*
> - * This enables the unused memory to be freed on older Acorn machines.
> - * We are freeing memory on behalf of the architecture initialisation
> - * code here.
> - */
> -static inline void
> -free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
> -{
> - int mb_freed = 0;
> -
> - /*
> -  * Align addresses
> -  */
> - virtual_start = PAGE_ALIGN(virtual_start);
> - virtual_end = PAGE_ALIGN(virtual_end);
> -
> - while (virtual_start < virtual_end) {
> - struct page *page;
> -
> - /*
> -  * Clear page reserved bit,
> -  * set count to 1, and free
> -  * the page.
> -  */
> - page = virt_to_page(virtual_start);
> - __free_reserved_page(page);
> -
> - virtual_start += PAGE_SIZE;
> - mb_freed += PAGE_SIZE / 1024;
> -     }
> -
> - printk("acornfb: freed %dK memory\n", mb_freed);
> -}
> -
>  static int acornfb_probe(struct platform_device *dev)
>  {
>   unsigned long size;
> -- 
> 2.29.2
> 

-- 
Oscar Salvador
SUSE L3
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v1 2/2] mm: simplify free_highmem_page() and free_reserved_page()

2021-01-28 Thread Oscar Salvador
On Tue, Jan 26, 2021 at 07:21:13PM +0100, David Hildenbrand wrote:
> adjust_managed_page_count() as called by free_reserved_page() properly
> handles pages in a highmem zone, so we can reuse it for
> free_highmem_page().
> 
> We can now get rid of totalhigh_pages_inc() and simplify
> free_reserved_page().
> 
> Cc: Andrew Morton 
> Cc: Thomas Gleixner 
> Cc: "Peter Zijlstra (Intel)" 
> Cc: Mike Rapoport 
> Cc: Oscar Salvador 
> Cc: Michal Hocko 
> Cc: Wei Yang 
> Signed-off-by: David Hildenbrand 

Reviewed-by: Oscar Salvador 

> +#define free_highmem_page(page) free_reserved_page(page)

Should we place that under #ifdef CONFIG_HIGHMEM to make clear
that it is only used on that config?
Maybe the #ifdefery ugliness does not pay off.

-- 
Oscar Salvador
SUSE L3
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 3/5] nouveau/hwmon: Remove old code, add .write/.read operations

2017-05-18 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 844 ++--
 1 file changed, 261 insertions(+), 583 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 734fc18..7d41471 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,6 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   int temp = nvkm_therm_temp_get(therm);
-
-   if (temp < 0)
-   return temp;
-
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
-}
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -130,234 +115,7 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
 static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
-}
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
-
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
-}
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-   const char *buf,
-   size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   ther

[PATCH v8 5/5] nouveau/hwmon: Change permissions to numeric

2017-05-18 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index a30cf94..1150081 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -45,7 +45,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -77,7 +77,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -110,7 +110,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -165,7 +165,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -188,7 +188,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 4/5] nouveau/hwmon: expose the auto_point and pwm_min/max attrs

2017-05-18 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info
We also do the same for pwm_min/max attrs.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 34 -
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 7d41471..a30cf94 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -192,6 +192,27 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+static const struct attribute_group pwm_fan_sensor_group = {
+   .attrs = pwm_fan_sensor_attrs,
+};
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+static const struct attribute_group temp1_auto_point_sensor_group = {
+   .attrs = temp1_auto_point_sensor_attrs,
+};
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -687,17 +708,28 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, 
NULL);
+   _chip_info,
+   special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 2/5] nouveau/hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-05-18 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 163 
 1 file changed, 163 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..734fc18 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,169 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense || !iccsense->data_valid || list_empty(>rails))
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   return 0444;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_is_visible(data, attr, channel);
+   default:
+   return 0;
+   }
+}
+
+static const char input_labe

[PATCH v8 1/5] nouveau/hwmon: Add config for all sensors and their settings

2017-05-18 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v8 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-05-18 Thread Oscar Salvador
This v8 fixes removes dummy functions which only had a return and moves the code
into the switch statements.

Versions:

v1 -> v2:
* Keep temp attrs as read only
v2 -> v3:
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough
* Add Signed-off-by to all commits
v3 -> v4:
* Rever const to struct attribute. Kbuild complains.
v4 -> v5:
* Drops a check for attr_set in "nouveau_temp_is_visible".
v5 -> v6:
* Change to nouveau/hwmon all commit titles
* Drop author change
* Coding-Style
* Move the check before the switch in nouveau_power_is_visible function
* Expose temperature attrs as RW again
* Get rid of nouveau_hwmon_set_pwm1/_enable and implement the code 
inside
nouveau_pwm_write
* Get rid of nouveau_hwmon_set_temp_* and implement the code inside
nouveau_temp_write
v6 -> v7:
* Got rid of all dummy functions that only had a return, and moved
code into the switch statements.
v7 -> v8:
* Fix warnings

This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Oscar Salvador (5):
  nouveau/hwmon: Add config for all sensors and their settings
  nouveau/hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau/hwmon: Remove old code, add .write/.read operations
  nouveau/hwmon: expose the auto_point and pwm_min/max attrs
  nouveau/hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 983 +++-
 1 file changed, 464 insertions(+), 519 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v7 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-05-17 Thread Oscar Salvador
Hi Ben,

I'll fix the warnings.

Thanks for the time

Regards
Oscar Salvador

On 17 May 2017 at 01:06, Ben Skeggs <skeg...@gmail.com> wrote:
> On 05/17/2017 07:18 AM, Oscar Salvador wrote:
>>
>> This v7 fixes removes dummy functions which only had a return and moves
>> the code
>> into the switch statements.
>
> Hey Oscar,
>
> I see new warnings with this series:
>
> /home/skeggsb/git/nouveau/drm/nouveau/nouveau_hwmon.c:645:8: warning:
> assignment discards ‘const’ qualifier from pointer target type
> [-Wdiscarded-qualifiers]
>*buf = input_label;
>
> and
>
> /home/skeggsb/git/nouveau/drm/nouveau/nouveau_hwmon.c:200:18: warning:
> ‘pwm_fan_sensor_groups’ defined but not used [-Wunused-variable]
>
> The second one also warns for temp1_auto_point_sensor_groups too.
>
> Thanks,
> Ben.
>
>
>>
>> Versions:
>>
>> v1 -> v2:
>>  * Keep temp attrs as read only
>> v2 -> v3:
>>  * Code fix-ups: struct and string as const and add return within
>> switch
>>  due to fallthrough
>>  * Add Signed-off-by to all commits
>> v3 -> v4:
>>  * Rever const to struct attribute. Kbuild complains.
>> v4 -> v5:
>>  * Drops a check for attr_set in "nouveau_temp_is_visible".
>> v5 -> v6:
>> * Change to nouveau/hwmon all commit titles
>> * Drop author change
>> * Coding-Style
>> * Move the check before the switch in nouveau_power_is_visible
>> function
>> * Expose temperature attrs as RW again
>> * Get rid of nouveau_hwmon_set_pwm1/_enable and implement the code
>> inside
>> nouveau_pwm_write
>> * Get rid of nouveau_hwmon_set_temp_* and implement the code
>> inside
>> nouveau_temp_write
>> v6 -> v7:
>> * Got rid of all dummy functions that only had a return, and moved
>> code into the switch statements.
>>
>>
>> This patchseries replaces the deprecated hwmon_device_register function
>> with the
>> new one hwmon_device_register_with_info.
>> It also does some cleanup.
>>
>> Oscar Salvador (5):
>>nouveau/hwmon: Add config for all sensors and their settings
>>nouveau/hwmon: Add nouveau_hwmon_ops structure with
>>  .is_visible/.read_string
>>nouveau/hwmon: Remove old code, add .write/.read operations
>>nouveau/hwmon: expose the auto_point and pwm_min/max attrs
>>nouveau/hwmon: Change permissions to numeric
>>
>>   drivers/gpu/drm/nouveau/nouveau_hwmon.c | 979
>> +++-
>>   1 file changed, 460 insertions(+), 519 deletions(-)
>>
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 1/5] nouveau/hwmon: Add config for all sensors and their settings

2017-05-16 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 5/5] nouveau/hwmon: Change permissions to numeric

2017-05-16 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 53ad696..51a9fb8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -45,7 +45,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -77,7 +77,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -110,7 +110,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -165,7 +165,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -188,7 +188,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-05-16 Thread Oscar Salvador
This v7 fixes removes dummy functions which only had a return and moves the code
into the switch statements.

Versions:

v1 -> v2:
* Keep temp attrs as read only
v2 -> v3:
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough
* Add Signed-off-by to all commits
v3 -> v4:
* Rever const to struct attribute. Kbuild complains.
v4 -> v5:
* Drops a check for attr_set in "nouveau_temp_is_visible".
v5 -> v6:
* Change to nouveau/hwmon all commit titles
* Drop author change
* Coding-Style
* Move the check before the switch in nouveau_power_is_visible function
* Expose temperature attrs as RW again
* Get rid of nouveau_hwmon_set_pwm1/_enable and implement the code 
inside
nouveau_pwm_write
* Get rid of nouveau_hwmon_set_temp_* and implement the code inside
nouveau_temp_write
v6 -> v7:
* Got rid of all dummy functions that only had a return, and moved
code into the switch statements.


This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Oscar Salvador (5):
  nouveau/hwmon: Add config for all sensors and their settings
  nouveau/hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau/hwmon: Remove old code, add .write/.read operations
  nouveau/hwmon: expose the auto_point and pwm_min/max attrs
  nouveau/hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 979 +++-
 1 file changed, 460 insertions(+), 519 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 3/5] nouveau/hwmon: Remove old code, add .write/.read operations

2017-05-16 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 844 ++--
 1 file changed, 261 insertions(+), 583 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index e9908fa..bd14d3b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,6 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   int temp = nvkm_therm_temp_get(therm);
-
-   if (temp < 0)
-   return temp;
-
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
-}
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -130,234 +115,7 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
 static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
-}
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
-
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
-}
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-   const char *buf,
-   size_t count)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   ther

[PATCH v7 4/5] nouveau/hwmon: expose the auto_point and pwm_min/max attrs

2017-05-16 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info
We also do the same for pwm_min/max attrs.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index bd14d3b..53ad696 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -192,6 +192,23 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -687,17 +704,28 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, 
NULL);
+   _chip_info,
+   special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v7 2/5] nouveau/hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-05-16 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 163 
 1 file changed, 163 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..e9908fa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,169 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense || !iccsense->data_valid || list_empty(>rails))
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   return 0444;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_is_visible(data, attr, channel);
+   default:
+   return 0;
+   }
+}
+
+static const char input_labe

[PATCH v6 5/5] nouveau/hwmon: Change permissions to numeric

2017-05-08 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index dac589f..9c37207 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -254,7 +254,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -277,7 +277,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 1/5] nouveau/hwmon: Add config for all sensors and their settings

2017-05-08 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 3/5] nouveau/hwmon: Remove old code, add .write/.read operations

2017-05-08 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 777 
 1 file changed, 288 insertions(+), 489 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index e9908fa..01e7440 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,282 +125,94 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
 
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
 
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 
1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, s

[PATCH v6 2/5] nouveau/hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-05-08 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 163 
 1 file changed, 163 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..e9908fa 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,169 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense || !iccsense->data_valid || list_empty(>rails))
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   return 0444;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_is_visible(data, attr, channel);
+   default:
+   return 0;
+   }
+}
+
+static const char input_labe

[PATCH v6 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-05-08 Thread Oscar Salvador
This v6 fixes some comments pointed out by Martin Peres.

Versions:

v1 -> v2:
* Keep temp attrs as read only
v2 -> v3:
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough
* Add Signed-off-by to all commits
v3 -> v4:
* Rever const to struct attribute. Kbuild complains.
v4 -> v5:
* Drops a check for attr_set in "nouveau_temp_is_visible".
v5 -> v6:
* Change to nouveau/hwmon all commit titles
* Drop author change
* Coding-Style
* Move the check before the switch in nouveau_power_is_visible function
* Expose temperature attrs as RW again
* Get rid of nouveau_hwmon_set_pwm1/_enable and implement the code 
inside
nouveau_pwm_write
* Get rid of nouveau_hwmon_set_temp_* and implement the code inside
nouveau_temp_write


This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Oscar Salvador (5):
  nouveau/hwmon: Add config for all sensors and their settings
  nouveau/hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau/hwmon: Remove old code, add .write/.read operations
  nouveau/hwmon: expose the auto_point and pwm_min/max attrs
  nouveau/hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 996 +---
 1 file changed, 529 insertions(+), 467 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v6 4/5] nouveau/hwmon: expose the auto_point and pwm_min/max attrs

2017-05-08 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info
We also do the same for pwm_min/max attrs.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
Reviewed-by: Martin Peres <martin.pe...@free.fr>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 01e7440..dac589f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -340,6 +340,23 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
return iccsense->power_w_crit;
 }
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -808,17 +825,28 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, 
NULL);
+   _chip_info,
+   special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 3/5] nouveau_hwmon: Remove old code, add .write/.read operations

2017-04-26 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 722 +++-
 1 file changed, 249 insertions(+), 473 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index e8ea8d0..4db65fb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,312 +125,100 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
 
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
 
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 
1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-  

[PATCH v5 4/5] nouveau_hwmon: Add support for auto_point attributes

2017-04-26 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 4db65fb..9142779 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -358,6 +358,23 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
return iccsense->power_w_crit;
 }
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -792,17 +809,27 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, NULL);
+   _chip_info, special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 5/5] nouveau_hwmon: Change permissions to numeric

2017-04-26 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones,
and adds me to the authors too.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 9142779..45b5c85 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -255,7 +255,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -295,7 +295,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-26 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 170 
 1 file changed, 170 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..e8ea8d0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,176 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense)
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   if (iccsense->data_valid &&
+   !list_empty(>rails))
+   return 0444;
+   return 0;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_i

[PATCH v5 1/5] nouveau_hwmon: Add config for all sensors and their settings

2017-04-26 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-04-26 Thread Oscar Salvador
This v5 drops a check for attr_set.

Versions:

v1 -> v2:
* Keep temp attrs as read only
v2 -> v3:
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough
* Add Signed-off-by to all commits
v3 -> v4:
* Rever const to struct attribute. Kbuild complains.
v4 -> v5:
* Drops a check for attr_set in "nouveau_temp_is_visible".

This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Oscar Salvador (5):
  nouveau_hwmon: Add config for all sensors and their settings
  nouveau_hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau_hwmon: Remove old code, add .write/.read operations
  nouveau_hwmon: Add support for auto_point attributes
  nouveau_hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 953 +---
 1 file changed, 499 insertions(+), 454 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 5/5] nouveau_hwmon: Change permissions to numeric

2017-04-22 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones,
and adds me to the authors too.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index d6b34f4..d129408 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -255,7 +255,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -295,7 +295,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 3/5] nouveau_hwmon: Remove old code, add .write/.read operations

2017-04-22 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 722 +++-
 1 file changed, 249 insertions(+), 473 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 6e9bcfe..57296cb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,312 +125,100 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
 
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
 
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 
1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-  

[PATCH v4 4/5] nouveau_hwmon: Add support for auto_point attributes

2017-04-22 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 57296cb..d6b34f4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -358,6 +358,23 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
return iccsense->power_w_crit;
 }
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -793,17 +810,27 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, NULL);
+   _chip_info, special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 1/5] nouveau_hwmon: Add config for all sensors and their settings

2017-04-22 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-22 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 171 
 1 file changed, 171 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..6e9bcfe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,177 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense)
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   if (iccsense->data_valid &&
+   !list_empty(>rails))
+   return 0444;
+   return 0;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->attr_set &&
+   nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon

[PATCH v4 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-04-22 Thread Oscar Salvador
Kbuild sent me an e-mail due to a fixup I introduced in v3.
It complains due to an incompatible pointer type and it doesn't build.
This version reverts it.

Versions:

v1 -> v2:
* Keep temp attrs as read only
v2 -> v3:
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough
* Add Signed-off-by to all commits
v3 -> v4:
* Rever const to struct attribute. Kbuild complains.

This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Oscar Salvador (5):
  nouveau_hwmon: Add config for all sensors and their settings
  nouveau_hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau_hwmon: Remove old code, add .write/.read operations
  nouveau_hwmon: Add support for auto_point attributes
  nouveau_hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 954 +---
 1 file changed, 500 insertions(+), 454 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 4/5] nouveau_hwmon: Add support for auto_point attributes

2017-04-21 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 57296cb..b9efc29 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -358,6 +358,24 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
return iccsense->power_w_crit;
 }
 
+static const struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static const struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -793,17 +811,27 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, NULL);
+   _chip_info, special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-04-21 Thread Oscar Salvador
Hi, this is version v3 with some fix-ups:

Versions:

v1 -> v2: 
* Keep temp attrs as read only
v2 -> v3: 
* Code fix-ups: struct and string as const and add return within switch
due to fallthrough 
* Add Signed-off-by to all commits

This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Here is the list of patches and what they do:

1/ Adds config structures for all sensors and their possible settings. This 
patch
   and the next one are just preparing the code for what it comes.

2/ Now everything goes through nouveua_hwmon_ops. There we set up wich 
functions will
   be called for read/write and for checking if an attribute should be created 
or not.
   In this patch we just add .is_visible/.read_string operations.
   Here we sill don't interactuate with the old code.

3/ Most of the work is being done here. We remove the old code and replace it 
with
   the new one related to the new api.
   Here we introduce the .write and .read operations, and create all functions
   regarding these operations.

4/ We add support for special attributes like *_auto_point*.

5/ Cleanup: Change permissions to numeric and add me to the author

Oscar Salvador (5):
  nouveau_hwmon: Add config for all sensors and their settings
  nouveau_hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau_hwmon: Remove old code, add .write/.read operations
  nouveau_hwmon: Add support for auto_point attributes
  nouveau_hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 955 +---
 1 file changed, 501 insertions(+), 454 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 3/5] nouveau_hwmon: Remove old code, add .write/.read operations

2017-04-21 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 722 +++-
 1 file changed, 249 insertions(+), 473 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 6e9bcfe..57296cb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,312 +125,100 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
 
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
 
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 
1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
-
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-  

[PATCH v3 5/5] nouveau_hwmon: Change permissions to numeric

2017-04-21 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones,
and adds me to the authors too.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index b9efc29..2d465c0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -255,7 +255,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -295,7 +295,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-21 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 171 
 1 file changed, 171 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..6e9bcfe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,177 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   if (!iccsense)
+   return 0;
+
+   switch (attr) {
+   case hwmon_power_input:
+   if (iccsense->data_valid &&
+   !list_empty(>rails))
+   return 0444;
+   return 0;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   return 0;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   return 0;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->attr_set &&
+   nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon

[PATCH v3 1/5] nouveau_hwmon: Add config for all sensors and their settings

2017-04-21 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.

Signed-off-by: Oscar Salvador <osalvador.vilard...@gmail.com>
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Nouveau] [PATCH v2 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-20 Thread Oscar Salvador
I got what you meant. I"ll fix it

El dia 20/04/2017 08:47, "Oscar Salvador" <osalvador.vilard...@gmail.com>
va escriure:

> Hi Karol,
>
> I don't get what you mean with return due to fallthrough. I mean, I
> know what is it, but I don't see how I can do it there.
> Moving the check before the switch looks like that:
>
> if (!iccsense)
> return 0;
>
> switch (attr) {
> case hwmon_power_input:
> if (iccsense->data_valid &&
> !list_empty(>rails))
> return 0444;
> case hwmon_power_max:
> if (iccsense->power_w_max)
> return 0444;
> case hwmon_power_crit:
> if (iccsense->power_w_crit)
> return 0444;
> default:
> return 0;
> }
>
> Could you drop me a hint?
>
>
> On 18 April 2017 at 09:56, Karol Herbst <karolher...@gmail.com> wrote:
> > 2017-04-17 9:47 GMT+02:00 Oscar Salvador <osalvador.vilard...@gmail.com
> >:
> >> This patch introduces the nouveau_hwmon_ops structure, sets up
> >> .is_visible and .read_string operations and adds all the functions
> >> for these operations.
> >> This is also a preparation for the next patches, where most of the
> >> work is being done.
> >> This code doesn't interacture with the old one.
> >> It's just to make easier the review of all patches.
> >> ---
> >>  drivers/gpu/drm/nouveau/nouveau_hwmon.c | 166
> 
> >>  1 file changed, 166 insertions(+)
> >>
> >> diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> >> index 24b40c5..9b6423c 100644
> >> --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> >> +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
> >> @@ -764,6 +764,172 @@ static const struct hwmon_channel_info
> *nouveau_info[] = {
> >> _power,
> >> NULL
> >>  };
> >> +
> >> +static umode_t
> >> +nouveau_chip_is_visible(const void *data, u32 attr, int channel)
> >> +{
> >> +   switch (attr) {
> >> +   case hwmon_chip_update_interval:
> >> +   return 0444;
> >> +   default:
> >> +   return 0;
> >> +   }
> >> +}
> >> +
> >> +static umode_t
> >> +nouveau_power_is_visible(const void *data, u32 attr, int channel)
> >> +{
> >> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device
> *)data);
> >> +   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.
> device);
> >> +
> >> +   switch (attr) {
> >> +   case hwmon_power_input:
> >> +   if (iccsense &&
> >
> > move the pointer check before the switch, because you need to check it
> > in every case (or move it to every case, but doing it once is
> > simplier/cleaner)
> >
> >> +   iccsense->data_valid &&
> >> +   !list_empty(>rails))
> >> +   return 0444;
> >
> > add return due to fallthrough
> >
> >> +   case hwmon_power_max:
> >> +   if (iccsense->power_w_max)
> >> +   return 0444;
> >
> > add return due to fallthrough
> >
> >> +   case hwmon_power_crit:
> >> +   if (iccsense->power_w_crit)
> >> +   return 0444;
> >
> > add return due to fallthrough
> >
> >> +   default:
> >> +   return 0;
> >> +   }
> >> +}
> >> +
> >> +static umode_t
> >> +nouveau_temp_is_visible(const void *data, u32 attr, int channel)
> >> +{
> >> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device
> *)data);
> >> +   struct nvkm_therm *therm = nvxx_therm(>client.device);
> >> +
> >> +   if (therm &&
> >> +   therm->attr_get &&
> >> +   therm->attr_set &&
> >> +   nvkm_therm_temp_get(therm) < 0)
> >> +   return 0;
> >> +
> >> +   switch (attr) {
> >> +   case hwmon_temp_input:
> >> +   case hwmon_temp_max:
> >> +   case hwmon_temp_max_hyst:
> >> +   case hwmon_temp_crit:
> >> +   case hw

Re: [Nouveau] [PATCH v2 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-20 Thread Oscar Salvador
Hi Karol,

I don't get what you mean with return due to fallthrough. I mean, I
know what is it, but I don't see how I can do it there.
Moving the check before the switch looks like that:

if (!iccsense)
return 0;

switch (attr) {
case hwmon_power_input:
if (iccsense->data_valid &&
!list_empty(>rails))
return 0444;
case hwmon_power_max:
if (iccsense->power_w_max)
return 0444;
case hwmon_power_crit:
if (iccsense->power_w_crit)
return 0444;
default:
return 0;
}

Could you drop me a hint?


On 18 April 2017 at 09:56, Karol Herbst <karolher...@gmail.com> wrote:
> 2017-04-17 9:47 GMT+02:00 Oscar Salvador <osalvador.vilard...@gmail.com>:
>> This patch introduces the nouveau_hwmon_ops structure, sets up
>> .is_visible and .read_string operations and adds all the functions
>> for these operations.
>> This is also a preparation for the next patches, where most of the
>> work is being done.
>> This code doesn't interacture with the old one.
>> It's just to make easier the review of all patches.
>> ---
>>  drivers/gpu/drm/nouveau/nouveau_hwmon.c | 166 
>> 
>>  1 file changed, 166 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
>> b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> index 24b40c5..9b6423c 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> @@ -764,6 +764,172 @@ static const struct hwmon_channel_info *nouveau_info[] 
>> = {
>> _power,
>> NULL
>>  };
>> +
>> +static umode_t
>> +nouveau_chip_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   switch (attr) {
>> +   case hwmon_chip_update_interval:
>> +   return 0444;
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_power_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
>> +
>> +   switch (attr) {
>> +   case hwmon_power_input:
>> +   if (iccsense &&
>
> move the pointer check before the switch, because you need to check it
> in every case (or move it to every case, but doing it once is
> simplier/cleaner)
>
>> +   iccsense->data_valid &&
>> +   !list_empty(>rails))
>> +   return 0444;
>
> add return due to fallthrough
>
>> +   case hwmon_power_max:
>> +   if (iccsense->power_w_max)
>> +   return 0444;
>
> add return due to fallthrough
>
>> +   case hwmon_power_crit:
>> +   if (iccsense->power_w_crit)
>> +   return 0444;
>
> add return due to fallthrough
>
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_therm *therm = nvxx_therm(>client.device);
>> +
>> +   if (therm &&
>> +   therm->attr_get &&
>> +   therm->attr_set &&
>> +   nvkm_therm_temp_get(therm) < 0)
>> +   return 0;
>> +
>> +   switch (attr) {
>> +   case hwmon_temp_input:
>> +   case hwmon_temp_max:
>> +   case hwmon_temp_max_hyst:
>> +   case hwmon_temp_crit:
>> +   case hwmon_temp_crit_hyst:
>> +   case hwmon_temp_emergency:
>> +   case hwmon_temp_emergency_hyst:
>> +   return 0444;
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_therm *therm = nvxx_therm(>client.device);
>> +
>> +   if (therm &&
>> +   therm->attr_get &&
>> +   therm->fan_get &&
>> +

Re: [Nouveau] [PATCH v2 1/5] nouveau_hwmon: Add config for all sensors and their settings

2017-04-19 Thread Oscar Salvador
Got it, I'll make a v3 with that line in all patches.

Thanks!

On 19 April 2017 at 20:11, Ilia Mirkin <imir...@alum.mit.edu> wrote:
> All kernel patches must have a Signed-off-by: $user. See
> https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin
>
> On Mon, Apr 17, 2017 at 3:47 AM, Oscar Salvador
> <osalvador.vilard...@gmail.com> wrote:
>> This is a preparation for the next patches. It just adds the sensors with
>> their possible configurable settings and then fills the struct 
>> hwmon_channel_info
>> with all this information.
>> ---
>>  drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 
>> +
>>  1 file changed, 72 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
>> b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> index 23b1670..24b40c5 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
>> @@ -692,6 +692,78 @@ static const struct attribute_group 
>> hwmon_power_attrgroup = {
>>  static const struct attribute_group hwmon_power_caps_attrgroup = {
>> .attrs = hwmon_power_caps_attributes,
>>  };
>> +
>> +static const u32 nouveau_config_chip[] = {
>> +   HWMON_C_UPDATE_INTERVAL,
>> +   0
>> +};
>> +
>> +static const u32 nouveau_config_in[] = {
>> +   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
>> +   0
>> +};
>> +
>> +static const u32 nouveau_config_temp[] = {
>> +   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
>> +   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
>> +   HWMON_T_EMERGENCY_HYST,
>> +   0
>> +};
>> +
>> +static const u32 nouveau_config_fan[] = {
>> +   HWMON_F_INPUT,
>> +   0
>> +};
>> +
>> +static const u32 nouveau_config_pwm[] = {
>> +   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
>> +   0
>> +};
>> +
>> +static const u32 nouveau_config_power[] = {
>> +   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
>> +   0
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_chip = {
>> +   .type = hwmon_chip,
>> +   .config = nouveau_config_chip,
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_temp = {
>> +   .type = hwmon_temp,
>> +   .config = nouveau_config_temp,
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_fan = {
>> +   .type = hwmon_fan,
>> +   .config = nouveau_config_fan,
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_in = {
>> +   .type = hwmon_in,
>> +   .config = nouveau_config_in,
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_pwm = {
>> +   .type = hwmon_pwm,
>> +   .config = nouveau_config_pwm,
>> +};
>> +
>> +static const struct hwmon_channel_info nouveau_power = {
>> +   .type = hwmon_power,
>> +   .config = nouveau_config_power,
>> +};
>> +
>> +static const struct hwmon_channel_info *nouveau_info[] = {
>> +   _chip,
>> +   _temp,
>> +   _fan,
>> +   _in,
>> +   _pwm,
>> +   _power,
>> +   NULL
>> +};
>>  #endif
>>
>>  int
>> --
>> 2.1.4
>>
>> ___
>> Nouveau mailing list
>> nouv...@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/nouveau
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 3/5] nouveau_hwmon: Remove old code, add .write/.read operations

2017-04-17 Thread Oscar Salvador
This patch removes old code related to the old api and transforms the
functions for the new api. It also adds the .write and .read operations.

Since we don't want to support changing hwmon_temp_* values, this patch
deletes all write-functions for these attributes too.
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 719 +++-
 1 file changed, 248 insertions(+), 471 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 9b6423c..538bf67 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,312 +125,100 @@ static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 
S_IRUGO | S_IWUSR,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
 
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
 
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
-
-   return count;
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 
1000;
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
-{
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
-   struct nvkm_therm *therm = nvxx_therm(>client.device);
-
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_CRITICAL) * 1000);
-}
-static ssize_t
-nouveau_hwmon_set_critical_temp(struct device *d, struct device_attribute *a,
-   const char *buf,
-

[PATCH v2 5/5] nouveau_hwmon: Change permissions to numeric

2017-04-17 Thread Oscar Salvador
This patch replaces the symbolic permissions with the numeric ones,
and adds me to the authors too.
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 655ae11..99e2a3a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp(struct device *d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp_hyst(struct device 
*d,
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -255,7 +255,7 @@ nouveau_hwmon_set_pwm1_min(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -295,7 +295,7 @@ nouveau_hwmon_set_pwm1_max(struct device *d, struct 
device_attribute *a,
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 4/5] nouveau_hwmon: Add support for auto_point attributes

2017-04-17 Thread Oscar Salvador
This patch creates a special group attributes for attrs like "*auto_point*".
We check if we have support for them, and if we do, we gather them all in
an attribute_group's structure which is the parameter regarding special groups
of hwmon_device_register_with_info.
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 29 -
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 538bf67..655ae11 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -359,6 +359,23 @@ nouveau_hwmon_get_power1_crit(struct nouveau_drm *drm)
return iccsense->power_w_crit;
 }
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -789,17 +806,27 @@ nouveau_hwmon_init(struct drm_device *dev)
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, NULL);
+   _chip_info, special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 1/5] nouveau_hwmon: Add config for all sensors and their settings

2017-04-17 Thread Oscar Salvador
This is a preparation for the next patches. It just adds the sensors with
their possible configurable settings and then fills the struct 
hwmon_channel_info
with all this information.
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 72 +
 1 file changed, 72 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 23b1670..24b40c5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -692,6 +692,78 @@ static const struct attribute_group hwmon_power_attrgroup 
= {
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 2/5] nouveau_hwmon: Add nouveau_hwmon_ops structure with .is_visible/.read_string

2017-04-17 Thread Oscar Salvador
This patch introduces the nouveau_hwmon_ops structure, sets up
.is_visible and .read_string operations and adds all the functions
for these operations.
This is also a preparation for the next patches, where most of the
work is being done.
This code doesn't interacture with the old one.
It's just to make easier the review of all patches.
---
 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 166 
 1 file changed, 166 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c 
b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
index 24b40c5..9b6423c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c
@@ -764,6 +764,172 @@ static const struct hwmon_channel_info *nouveau_info[] = {
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   switch (attr) {
+   case hwmon_power_input:
+   if (iccsense &&
+   iccsense->data_valid &&
+   !list_empty(>rails))
+   return 0444;
+   case hwmon_power_max:
+   if (iccsense->power_w_max)
+   return 0444;
+   case hwmon_power_crit:
+   if (iccsense->power_w_crit)
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->attr_set &&
+   nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm &&
+   therm->attr_get &&
+   therm->fan_get &&
+   therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_is_visible(data, attr, channel);
+   default:
+   return 0;
+   }
+}
+
+static char *input_label = "GPU core";
+
+static int
+nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+  

[PATCH v2 0/5] replace hwmon_device_register for hwmon_device_register_with_info

2017-04-17 Thread Oscar Salvador
Hi!

This patchseries replaces the deprecated hwmon_device_register function with the
new one hwmon_device_register_with_info.
It also does some cleanup.

Here is the list of patches and what they do:

1/ Adds config structures for all sensors and their possible settings. This 
patch
   and the next one are just preparing the code for what it comes.

2/ Now everything goes through nouveua_hwmon_ops. There we set up wich 
functions will
   be called for read/write and for checking if an attribute should be created 
or not.
   In this patch we just add .is_visible/.read_string operations.
   Here we sill don't interactuate with the old code.

3/ Most of the work is being done here. We remove the old code and replace it 
with
   the new one related to the new api.
   Here we introduce the .write and .read operations, and create all functions
   regarding these operations.

4/ We add support for special attributes like *_auto_point*.

5/ Cleanup: Change permissions to numeric and add me to the author

Oscar Salvador (5):
  nouveau_hwmon: Add config for all sensors and their settings
  nouveau_hwmon: Add nouveau_hwmon_ops structure with
.is_visible/.read_string
  nouveau_hwmon: Remove old code, add .write/.read operations
  nouveau_hwmon: Add support for auto_point attributes
  nouveau_hwmon: Change permissions to numeric

 drivers/gpu/drm/nouveau/nouveau_hwmon.c | 946 +---
 1 file changed, 494 insertions(+), 452 deletions(-)

-- 
2.1.4

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Nouveau] [PATCH 1/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-14 Thread Oscar Salvador
Sorry, It's my first time sending a patch and I'm a bit lost. I didn't
know the first one must be a cover letter.
I'll write another series of patch doing it right and with the changes
you suggested in it.

I'll put v2 after PATCH.

Thanks

On 14 April 2017 at 01:21, Karol Herbst <karolher...@gmail.com> wrote:
> 2017-04-13 11:08 GMT+02:00 Oscar Salvador <osalvador.vilard...@gmail.com>:
>> This patch introduces the structure "struct hwmon_ops"  and sets up the  
>> ".visible" operation.
>> Is also a preparation for the next patch where all work is being done.
>>
>> --- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-12 
>> 19:22:29.070573187 +0200
>> +++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-12 
>> 19:21:32.391338011 +0200
>> @@ -764,6 +764,166 @@ static const struct hwmon_channel_info *
>> _power,
>> NULL
>>  };
>> +
>> +static umode_t
>> +nouveau_chip_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   switch (attr) {
>> +   case hwmon_chip_update_interval:
>> +   return 0444;
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_power_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
>> +
>> +   switch (attr) {
>> +   case hwmon_power_input:
>> +   if (iccsense && iccsense->data_valid &&
>> +   !list_empty(>rails))
>> +   return 0444;
>
> no fallthrough here.
>
>> +   case hwmon_power_max:
>> +   case hwmon_power_crit:
>> +   if (iccsense->power_w_max && iccsense->power_w_crit)
>> +   return 0444;
>
> it makes sense to split those
>
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_temp_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_therm *therm = nvxx_therm(>client.device);
>> +
>> +   if (therm && therm->attr_get && therm->attr_set)
>> +   if (nvkm_therm_temp_get(therm) < 0)
>> +   return 0;
>
> I think you can merge those if statements
>
>> +
>> +   switch (attr) {
>> +   case hwmon_temp_input:
>> +   return 0444;
>> +   case hwmon_temp_max:
>> +   case hwmon_temp_max_hyst:
>> +   case hwmon_temp_crit:
>> +   case hwmon_temp_crit_hyst:
>> +   case hwmon_temp_emergency:
>> +   case hwmon_temp_emergency_hyst:
>> +   return 0644;
>
> I doubt we ever want to support changing those, please leave them as read only
>
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_therm *therm = nvxx_therm(>client.device);
>> +
>> +   if (therm && therm->attr_get)
>> +   if (therm->fan_get && therm->fan_get(therm) < 0)
>> +   return 0;
>
> merge the ifs
>
>> +
>> +   switch (attr) {
>> +   case hwmon_pwm_enable:
>> +   case hwmon_pwm_input:
>> +   return 0644;
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_input_is_visible(const void *data, u32 attr, int channel)
>> +{
>> +   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
>> +   struct nvkm_volt *volt = nvxx_volt(>client.device);
>> +
>> +   if (!volt || nvkm_volt_get(volt) < 0)
>> +   return 0;
>> +
>> +   switch (attr) {
>> +   case hwmon_in_input:
>> +   case hwmon_in_label:
>> +   case hwmon_in_min:
>> +   case hwmon_in_max:
>> +   return 0444;
>> +   default:
>> +   return 0;
>> +   }
>> +}
>> +
>> +static umode_t
>> +nouveau_fan_is_visible(const void *data, u32 attr, int channel)

[PATCH 0/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
Hi again,

I've split the patches as Karol Herbst suggested.
I hope now it's fine.

This series of patches introduce the new hwmon_device_register_with_info
and gets rid of the old hwmon_device_register.

This patch adds the default sensors with their possible config values.
Just to prepare for the next patches


--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-12 
19:18:09.638073562 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-12 
19:19:44.244797202 +0200
@@ -692,6 +692,78 @@ static const struct attribute_group hwmo
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
This patch introduces the structure "struct hwmon_ops"  and sets up the  
".visible" operation.
Is also a preparation for the next patch.

--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-12 
19:18:09.638073562 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-12 
19:19:44.244797202 +0200
@@ -692,6 +692,78 @@ static const struct attribute_group hwmo
 static const struct attribute_group hwmon_power_caps_attrgroup = {
.attrs = hwmon_power_caps_attributes,
 };
+
+static const u32 nouveau_config_chip[] = {
+   HWMON_C_UPDATE_INTERVAL,
+   0
+};
+
+static const u32 nouveau_config_in[] = {
+   HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX | HWMON_I_LABEL,
+   0
+};
+
+static const u32 nouveau_config_temp[] = {
+   HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_MAX_HYST |
+   HWMON_T_CRIT | HWMON_T_CRIT_HYST | HWMON_T_EMERGENCY |
+   HWMON_T_EMERGENCY_HYST,
+   0
+};
+
+static const u32 nouveau_config_fan[] = {
+   HWMON_F_INPUT,
+   0
+};
+
+static const u32 nouveau_config_pwm[] = {
+   HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
+   0
+};
+
+static const u32 nouveau_config_power[] = {
+   HWMON_P_INPUT | HWMON_P_CAP_MAX | HWMON_P_CRIT,
+   0
+};
+
+static const struct hwmon_channel_info nouveau_chip = {
+   .type = hwmon_chip,
+   .config = nouveau_config_chip,
+};
+
+static const struct hwmon_channel_info nouveau_temp = {
+   .type = hwmon_temp,
+   .config = nouveau_config_temp,
+};
+
+static const struct hwmon_channel_info nouveau_fan = {
+   .type = hwmon_fan,
+   .config = nouveau_config_fan,
+};
+
+static const struct hwmon_channel_info nouveau_in = {
+   .type = hwmon_in,
+   .config = nouveau_config_in,
+};
+
+static const struct hwmon_channel_info nouveau_pwm = {
+   .type = hwmon_pwm,
+   .config = nouveau_config_pwm,
+};
+
+static const struct hwmon_channel_info nouveau_power = {
+   .type = hwmon_power,
+   .config = nouveau_config_power,
+};
+
+static const struct hwmon_channel_info *nouveau_info[] = {
+   _chip,
+   _temp,
+   _fan,
+   _in,
+   _pwm,
+   _power,
+   NULL
+};
 #endif
 
 int
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 1/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
This patch introduces the structure "struct hwmon_ops"  and sets up the  
".visible" operation.
Is also a preparation for the next patch where all work is being done.

--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-12 
19:22:29.070573187 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-12 
19:21:32.391338011 +0200
@@ -764,6 +764,166 @@ static const struct hwmon_channel_info *
_power,
NULL
 };
+
+static umode_t
+nouveau_chip_is_visible(const void *data, u32 attr, int channel)
+{
+   switch (attr) {
+   case hwmon_chip_update_interval:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_power_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_iccsense *iccsense = nvxx_iccsense(>client.device);
+
+   switch (attr) {
+   case hwmon_power_input:
+   if (iccsense && iccsense->data_valid &&
+   !list_empty(>rails))
+   return 0444;
+   case hwmon_power_max:
+   case hwmon_power_crit:
+   if (iccsense->power_w_max && iccsense->power_w_crit)
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_temp_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get && therm->attr_set)
+   if (nvkm_therm_temp_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_temp_input:
+   return 0444;
+   case hwmon_temp_max:
+   case hwmon_temp_max_hyst:
+   case hwmon_temp_crit:
+   case hwmon_temp_crit_hyst:
+   case hwmon_temp_emergency:
+   case hwmon_temp_emergency_hyst:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_pwm_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (therm && therm->attr_get)
+   if (therm->fan_get && therm->fan_get(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_pwm_enable:
+   case hwmon_pwm_input:
+   return 0644;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_input_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_volt *volt = nvxx_volt(>client.device);
+
+   if (!volt || nvkm_volt_get(volt) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_in_input:
+   case hwmon_in_label:
+   case hwmon_in_min:
+   case hwmon_in_max:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_fan_is_visible(const void *data, u32 attr, int channel)
+{
+   struct nouveau_drm *drm = nouveau_drm((struct drm_device *)data);
+   struct nvkm_therm *therm = nvxx_therm(>client.device);
+
+   if (!therm || !therm->attr_get || nvkm_therm_fan_sense(therm) < 0)
+   return 0;
+
+   switch (attr) {
+   case hwmon_fan_input:
+   return 0444;
+   default:
+   return 0;
+   }
+}
+
+static umode_t
+nouveau_is_visible(const void *data, enum hwmon_sensor_types type, u32 attr,
+   int channel)
+{
+   switch (type) {
+   case hwmon_chip:
+   return nouveau_chip_is_visible(data, attr, channel);
+   case hwmon_temp:
+   return nouveau_temp_is_visible(data, attr, channel);
+   case hwmon_fan:
+   return nouveau_fan_is_visible(data, attr, channel);
+   case hwmon_in:
+   return nouveau_input_is_visible(data, attr, channel);
+   case hwmon_pwm:
+   return nouveau_pwm_is_visible(data, attr, channel);
+   case hwmon_power:
+   return nouveau_power_is_visible(data, attr, channel);
+   default:
+   return 0;
+   }
+}
+
+static char *input_label = "GPU core";
+
+static int
+nouveau_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
+   int channel, char **buf)
+{
+   if (type == hwmon_in && attr == hwmon_in_label) {
+   *buf = input_label;
+   return 0;
+   }
+
+   return -EOPNOTSUPP;
+}
+
+static const struct hwmon_ops nouveau_hwmon_ops = {
+   .is_visible = nouveau_is_visible,
+   .read = NULL,
+   .read_string = nouveau_read_string,
+   .write = NULL,
+};
+

[PATCH 4/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
This patch replaces symbolic permissions with the numeric ones and adds me to 
the authors too.

--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-13 
10:18:37.471129756 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-13 
10:19:58.182025638 +0200
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -56,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -88,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -121,7 +121,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
@@ -313,7 +313,7 @@ nouveau_hwmon_set_pwm1_min(struct device
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_min, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_min, 0644,
  nouveau_hwmon_get_pwm1_min,
  nouveau_hwmon_set_pwm1_min, 0);
 
@@ -353,7 +353,7 @@ nouveau_hwmon_set_pwm1_max(struct device
return count;
 }
 
-static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(pwm1_max, 0644,
  nouveau_hwmon_get_pwm1_max,
  nouveau_hwmon_set_pwm1_max, 0);
 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
This patch creates special group attributes for special attrs like 
"*auto_point*".
We check if we need them, and if we do, we set them up in special_groups 
structure, that then
we pass to hwmon_device_register_with_info.

--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-13 
10:13:26.331391326 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-13 
10:15:02.274073273 +0200
@@ -417,6 +417,23 @@ nouveau_hwmon_get_power1_crit(struct nou
return iccsense->power_w_crit;
 }
 
+static struct attribute *pwm_fan_sensor_attrs[] = {
+   _dev_attr_pwm1_min.dev_attr.attr,
+   _dev_attr_pwm1_max.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(pwm_fan_sensor);
+
+static struct attribute *temp1_auto_point_sensor_attrs[] = {
+   _dev_attr_temp1_auto_point1_pwm.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp.dev_attr.attr,
+   _dev_attr_temp1_auto_point1_temp_hyst.dev_attr.attr,
+   NULL
+};
+ATTRIBUTE_GROUPS(temp1_auto_point_sensor);
+
+#define N_ATTR_GROUPS   3
+
 static const u32 nouveau_config_chip[] = {
HWMON_C_UPDATE_INTERVAL,
0
@@ -868,17 +885,27 @@ nouveau_hwmon_init(struct drm_device *de
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
+   const struct attribute_group *special_groups[N_ATTR_GROUPS];
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
+   int i = 0;
 
hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
if (!hwmon)
return -ENOMEM;
hwmon->dev = dev;
 
+   if (therm && therm->attr_get && therm->attr_set) {
+   if (nvkm_therm_temp_get(therm) >= 0)
+   special_groups[i++] = _auto_point_sensor_group;
+   if (therm->fan_get && therm->fan_get(therm) >= 0)
+   special_groups[i++] = _fan_sensor_group;
+   }
+
+   special_groups[i] = 0;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
-   _chip_info, NULL);
+   _chip_info, special_groups);
if (IS_ERR(hwmon_dev)) {
ret = PTR_ERR(hwmon_dev);
NV_ERROR(drm, "Unable to register hwmon device: %d\n", ret);
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 2/4] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-13 Thread Oscar Salvador
Here is where most of the work is being done.
We are replacing the old API with the new one, that means changing the 
functions layout and remove unnecessary code.
We also set up the other operations:
.read
.write
.read_string

--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-13 
10:11:29.24186 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-13 
10:12:38.016055129 +0200
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -129,311 +125,157 @@ static SENSOR_DEVICE_ATTR(temp1_auto_poi
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
+   return (therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
 }
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+
+static int
+nouveau_hwmon_set_max_temp(struct nouveau_drm *drm, long val)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
 
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK,
+   val / 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
+   return therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST)
+   * 1000;
 }
-static ssize_t
-nouveau_hwmon_set_max_temp_hyst(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+
+static int
+nouveau_hwmon_set_max_temp_hyst(struct nouveau_drm *drm, long val)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
-
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
-   value / 1000);
 
-   return count;
+   return therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST,
+   val / 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
- nouveau_hwmon_max_temp_hyst,
- nouveau_hwmon_set_max_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_critical_temp(struct device *d, struct device_attribute *a,
-   char *buf)
+static int
+nouveau_hwmon_critical_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = 

Re: [Nouveau] [PATCH 1/1] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-12 Thread Oscar Salvador
Sorry for that. I'll split the patch and I'll come again ;)

El dia 11/04/2017 22:12, "Karol Herbst" <karolher...@gmail.com> va escriure:

thanks for the work, but could you please split that patch?
It looks like you are doing several things at once and it isn't really
easy to review like this. And it isn't bisectable.

If there are clean ups here, please do it in a seperate patch. I
highly doubt that it all has to be done within one single big patch.

2017-04-11 18:54 GMT+02:00 Oscar Salvador <osalvador.vilard...@gmail.com>:
> Hi,
>
> this patch replaces the old hwmon_device_register with the new
> hwmon_device_register_with_info.
> I've tested it on my laptop with a GeForceGT 425M and it doesn't break
anything.
>
>
> --- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-11
18:27:15.477623009 +0200
> +++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-11
18:45:41.918688215 +0200
> @@ -1,5 +1,6 @@
>  /*
> - * Copyright 2010 Red Hat Inc.
> + * Copyright 2010 Red Hat Inc. (Ben Skeggs)
> + * Copyright 2017 Oscar Salvador
>   *
>   * Permission is hereby granted, free of charge, to any person obtaining
a
>   * copy of this software and associated documentation files (the
"Software"),
> @@ -19,7 +20,6 @@
>   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>   * OTHER DEALINGS IN THE SOFTWARE.
>   *
> - * Authors: Ben Skeggs
>   */
>
>  #ifdef CONFIG_ACPI
> @@ -38,21 +38,17 @@
>  #include 
>
>  #if defined(CONFIG_HWMON) || (defined(MODULE) &&
defined(CONFIG_HWMON_MODULE))
> -static ssize_t
> -nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a,
char *buf)
> +static int
> +nouveau_hwmon_show_temp(struct nouveau_drm *drm)
>  {
> -   struct drm_device *dev = dev_get_drvdata(d);
> -   struct nouveau_drm *drm = nouveau_drm(dev);
> struct nvkm_therm *therm = nvxx_therm(>client.device);
> int temp = nvkm_therm_temp_get(therm);
>
> if (temp < 0)
> return temp;
>
> -   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
> +   return (temp * 1000);
>  }
> -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
> - NULL, 0);
>
>  static ssize_t
>  nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
> @@ -60,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm
>  {
> return snprintf(buf, PAGE_SIZE, "%d\n", 100);
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
>   nouveau_hwmon_show_temp1_auto_point1_pwm, NULL,
0);
>
>  static ssize_t
> @@ -92,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp
>
> return count;
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
>   nouveau_hwmon_temp1_auto_point1_temp,
>   nouveau_hwmon_set_temp1_auto_point1_temp, 0);
>
> @@ -125,319 +121,176 @@ nouveau_hwmon_set_temp1_auto_point1_temp
>
> return count;
>  }
> -static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
> +static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
>   nouveau_hwmon_temp1_auto_point1_temp_hyst,
>   nouveau_hwmon_set_temp1_auto_point1_temp_hyst,
0);
>
> -static ssize_t
> -nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a,
char *buf)
> +static int
> +nouveau_hwmon_max_temp(struct nouveau_drm *drm)
>  {
> -   struct drm_device *dev = dev_get_drvdata(d);
> -   struct nouveau_drm *drm = nouveau_drm(dev);
> struct nvkm_therm *therm = nvxx_therm(>client.device);
>
> -   return snprintf(buf, PAGE_SIZE, "%d\n",
> -  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) *
1000);
> +   return (therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) *
1000);
>  }
> -static ssize_t
> -nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
> -   const char *buf, size_t
count)
> +
> +static int
> +nouveau_hwmon_set_max_temp(struct nouveau_drm *drm, long val)
>  {
> -   struct drm_device *dev = dev_get_drvdata(d);
> -   struct nouveau_drm *drm = nouveau_drm(dev);
> struct nvkm_therm *therm = nvxx_therm(>client.device);
> -   long value;
> -
> -   if (kstrtol(buf, 10, ) == -EINVAL)
> -   return count;
>
> -   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, va

[PATCH 1/1] nouveau_hwmon: migrate to hwmon_device_register_with_info

2017-04-11 Thread Oscar Salvador
Hi,

this patch replaces the old hwmon_device_register with the new
hwmon_device_register_with_info.
I've tested it on my laptop with a GeForceGT 425M and it doesn't break anything.


--- linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c.orig  2017-04-11 
18:27:15.477623009 +0200
+++ linux/drivers/gpu/drm/nouveau/nouveau_hwmon.c   2017-04-11 
18:45:41.918688215 +0200
@@ -1,5 +1,6 @@
 /*
- * Copyright 2010 Red Hat Inc.
+ * Copyright 2010 Red Hat Inc. (Ben Skeggs)
+ * Copyright 2017 Oscar Salvador
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -19,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  *
- * Authors: Ben Skeggs
  */
 
 #ifdef CONFIG_ACPI
@@ -38,21 +38,17 @@
 #include 
 
 #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
-static ssize_t
-nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char 
*buf)
+static int
+nouveau_hwmon_show_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
int temp = nvkm_therm_temp_get(therm);
 
if (temp < 0)
return temp;
 
-   return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000);
+   return (temp * 1000);
 }
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp,
- NULL, 0);
 
 static ssize_t
 nouveau_hwmon_show_temp1_auto_point1_pwm(struct device *d,
@@ -60,7 +56,7 @@ nouveau_hwmon_show_temp1_auto_point1_pwm
 {
return snprintf(buf, PAGE_SIZE, "%d\n", 100);
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_pwm, 0444,
  nouveau_hwmon_show_temp1_auto_point1_pwm, NULL, 0);
 
 static ssize_t
@@ -92,7 +88,7 @@ nouveau_hwmon_set_temp1_auto_point1_temp
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, 0644,
  nouveau_hwmon_temp1_auto_point1_temp,
  nouveau_hwmon_set_temp1_auto_point1_temp, 0);
 
@@ -125,319 +121,176 @@ nouveau_hwmon_set_temp1_auto_point1_temp
 
return count;
 }
-static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp_hyst, 0644,
  nouveau_hwmon_temp1_auto_point1_temp_hyst,
  nouveau_hwmon_set_temp1_auto_point1_temp_hyst, 0);
 
-static ssize_t
-nouveau_hwmon_max_temp(struct device *d, struct device_attribute *a, char *buf)
+static int
+nouveau_hwmon_max_temp(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
-  therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
+   return (therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK) * 1000);
 }
-static ssize_t
-nouveau_hwmon_set_max_temp(struct device *d, struct device_attribute *a,
-   const char *buf, size_t count)
+
+static int
+nouveau_hwmon_set_max_temp(struct nouveau_drm *drm, long val)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
-   long value;
-
-   if (kstrtol(buf, 10, ) == -EINVAL)
-   return count;
 
-   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, value / 1000);
-
-   return count;
+   therm->attr_set(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK, val / 1000);
+   return val;
 }
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_max_temp,
- nouveau_hwmon_set_max_temp,
- 0);
 
-static ssize_t
-nouveau_hwmon_max_temp_hyst(struct device *d, struct device_attribute *a,
-   char *buf)
+static int
+nouveau_hwmon_max_temp_hyst(struct nouveau_drm *drm)
 {
-   struct drm_device *dev = dev_get_drvdata(d);
-   struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(>client.device);
 
-   return snprintf(buf, PAGE_SIZE, "%d\n",
- therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST) * 1000);
+   return (therm->attr_get(therm, NVKM_THERM_ATTR_THRS_DOWN_CLK_HYST)
+   * 1000);
 }