1477eb7f9SFrançois Tigeot /* 2477eb7f9SFrançois Tigeot * Copyright © 2012 Intel Corporation 3477eb7f9SFrançois Tigeot * 4477eb7f9SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 5477eb7f9SFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 6477eb7f9SFrançois Tigeot * to deal in the Software without restriction, including without limitation 7477eb7f9SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8477eb7f9SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 9477eb7f9SFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 10477eb7f9SFrançois Tigeot * 11477eb7f9SFrançois Tigeot * The above copyright notice and this permission notice (including the next 12477eb7f9SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the 13477eb7f9SFrançois Tigeot * Software. 14477eb7f9SFrançois Tigeot * 15477eb7f9SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16477eb7f9SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17477eb7f9SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18477eb7f9SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19477eb7f9SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20477eb7f9SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21477eb7f9SFrançois Tigeot * IN THE SOFTWARE. 22477eb7f9SFrançois Tigeot * 23477eb7f9SFrançois Tigeot * Authors: 24477eb7f9SFrançois Tigeot * Ben Widawsky <ben@bwidawsk.net> 25477eb7f9SFrançois Tigeot * 26477eb7f9SFrançois Tigeot */ 27477eb7f9SFrançois Tigeot 28477eb7f9SFrançois Tigeot #include <drm/drmP.h> 29477eb7f9SFrançois Tigeot #include <linux/device.h> 30477eb7f9SFrançois Tigeot #include <linux/module.h> 31477eb7f9SFrançois Tigeot #include "intel_drv.h" 32477eb7f9SFrançois Tigeot #include "i915_drv.h" 33477eb7f9SFrançois Tigeot 34477eb7f9SFrançois Tigeot #if 0 35477eb7f9SFrançois Tigeot #define dev_to_drm_minor(d) dev_get_drvdata((d)) 36477eb7f9SFrançois Tigeot 37477eb7f9SFrançois Tigeot #ifdef CONFIG_PM 38*aee94f86SFrançois Tigeot static u32 calc_residency(struct drm_device *dev, 39*aee94f86SFrançois Tigeot i915_reg_t reg) 40477eb7f9SFrançois Tigeot { 41477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 42477eb7f9SFrançois Tigeot u64 raw_time; /* 32b value may overflow during fixed point math */ 43352ff8bdSFrançois Tigeot u64 units = 128ULL, div = 100000ULL; 44477eb7f9SFrançois Tigeot u32 ret; 45477eb7f9SFrançois Tigeot 46477eb7f9SFrançois Tigeot if (!intel_enable_rc6(dev)) 47477eb7f9SFrançois Tigeot return 0; 48477eb7f9SFrançois Tigeot 49477eb7f9SFrançois Tigeot intel_runtime_pm_get(dev_priv); 50477eb7f9SFrançois Tigeot 51477eb7f9SFrançois Tigeot /* On VLV and CHV, residency time is in CZ units rather than 1.28us */ 52*aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { 53352ff8bdSFrançois Tigeot units = 1; 54352ff8bdSFrançois Tigeot div = dev_priv->czclk_freq; 55477eb7f9SFrançois Tigeot 56477eb7f9SFrançois Tigeot if (I915_READ(VLV_COUNTER_CONTROL) & VLV_COUNT_RANGE_HIGH) 57477eb7f9SFrançois Tigeot units <<= 8; 58352ff8bdSFrançois Tigeot } else if (IS_BROXTON(dev)) { 59352ff8bdSFrançois Tigeot units = 1; 60352ff8bdSFrançois Tigeot div = 1200; /* 833.33ns */ 61477eb7f9SFrançois Tigeot } 62477eb7f9SFrançois Tigeot 63477eb7f9SFrançois Tigeot raw_time = I915_READ(reg) * units; 64477eb7f9SFrançois Tigeot ret = DIV_ROUND_UP_ULL(raw_time, div); 65477eb7f9SFrançois Tigeot 66477eb7f9SFrançois Tigeot intel_runtime_pm_put(dev_priv); 67477eb7f9SFrançois Tigeot return ret; 68477eb7f9SFrançois Tigeot } 69477eb7f9SFrançois Tigeot 70477eb7f9SFrançois Tigeot static ssize_t 71477eb7f9SFrançois Tigeot show_rc6_mask(struct device *kdev, struct device_attribute *attr, char *buf) 72477eb7f9SFrançois Tigeot { 73477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_to_drm_minor(kdev); 74477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%x\n", intel_enable_rc6(dminor->dev)); 75477eb7f9SFrançois Tigeot } 76477eb7f9SFrançois Tigeot 77477eb7f9SFrançois Tigeot static ssize_t 78477eb7f9SFrançois Tigeot show_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf) 79477eb7f9SFrançois Tigeot { 80477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_get_drvdata(kdev); 81477eb7f9SFrançois Tigeot u32 rc6_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6); 82477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); 83477eb7f9SFrançois Tigeot } 84477eb7f9SFrançois Tigeot 85477eb7f9SFrançois Tigeot static ssize_t 86477eb7f9SFrançois Tigeot show_rc6p_ms(struct device *kdev, struct device_attribute *attr, char *buf) 87477eb7f9SFrançois Tigeot { 88477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_to_drm_minor(kdev); 89477eb7f9SFrançois Tigeot u32 rc6p_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6p); 90477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%u\n", rc6p_residency); 91477eb7f9SFrançois Tigeot } 92477eb7f9SFrançois Tigeot 93477eb7f9SFrançois Tigeot static ssize_t 94477eb7f9SFrançois Tigeot show_rc6pp_ms(struct device *kdev, struct device_attribute *attr, char *buf) 95477eb7f9SFrançois Tigeot { 96477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_to_drm_minor(kdev); 97477eb7f9SFrançois Tigeot u32 rc6pp_residency = calc_residency(dminor->dev, GEN6_GT_GFX_RC6pp); 98477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%u\n", rc6pp_residency); 99477eb7f9SFrançois Tigeot } 100477eb7f9SFrançois Tigeot 101477eb7f9SFrançois Tigeot static ssize_t 102477eb7f9SFrançois Tigeot show_media_rc6_ms(struct device *kdev, struct device_attribute *attr, char *buf) 103477eb7f9SFrançois Tigeot { 104477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_get_drvdata(kdev); 105477eb7f9SFrançois Tigeot u32 rc6_residency = calc_residency(dminor->dev, VLV_GT_MEDIA_RC6); 106477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%u\n", rc6_residency); 107477eb7f9SFrançois Tigeot } 108477eb7f9SFrançois Tigeot 109477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6_enable, S_IRUGO, show_rc6_mask, NULL); 110477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6_residency_ms, S_IRUGO, show_rc6_ms, NULL); 111477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6p_residency_ms, S_IRUGO, show_rc6p_ms, NULL); 112477eb7f9SFrançois Tigeot static DEVICE_ATTR(rc6pp_residency_ms, S_IRUGO, show_rc6pp_ms, NULL); 113477eb7f9SFrançois Tigeot static DEVICE_ATTR(media_rc6_residency_ms, S_IRUGO, show_media_rc6_ms, NULL); 114477eb7f9SFrançois Tigeot 115477eb7f9SFrançois Tigeot static struct attribute *rc6_attrs[] = { 116477eb7f9SFrançois Tigeot &dev_attr_rc6_enable.attr, 117477eb7f9SFrançois Tigeot &dev_attr_rc6_residency_ms.attr, 118477eb7f9SFrançois Tigeot NULL 119477eb7f9SFrançois Tigeot }; 120477eb7f9SFrançois Tigeot 121477eb7f9SFrançois Tigeot static struct attribute_group rc6_attr_group = { 122477eb7f9SFrançois Tigeot .name = power_group_name, 123477eb7f9SFrançois Tigeot .attrs = rc6_attrs 124477eb7f9SFrançois Tigeot }; 125477eb7f9SFrançois Tigeot 126477eb7f9SFrançois Tigeot static struct attribute *rc6p_attrs[] = { 127477eb7f9SFrançois Tigeot &dev_attr_rc6p_residency_ms.attr, 128477eb7f9SFrançois Tigeot &dev_attr_rc6pp_residency_ms.attr, 129477eb7f9SFrançois Tigeot NULL 130477eb7f9SFrançois Tigeot }; 131477eb7f9SFrançois Tigeot 132477eb7f9SFrançois Tigeot static struct attribute_group rc6p_attr_group = { 133477eb7f9SFrançois Tigeot .name = power_group_name, 134477eb7f9SFrançois Tigeot .attrs = rc6p_attrs 135477eb7f9SFrançois Tigeot }; 136477eb7f9SFrançois Tigeot 137477eb7f9SFrançois Tigeot static struct attribute *media_rc6_attrs[] = { 138477eb7f9SFrançois Tigeot &dev_attr_media_rc6_residency_ms.attr, 139477eb7f9SFrançois Tigeot NULL 140477eb7f9SFrançois Tigeot }; 141477eb7f9SFrançois Tigeot 142477eb7f9SFrançois Tigeot static struct attribute_group media_rc6_attr_group = { 143477eb7f9SFrançois Tigeot .name = power_group_name, 144477eb7f9SFrançois Tigeot .attrs = media_rc6_attrs 145477eb7f9SFrançois Tigeot }; 146477eb7f9SFrançois Tigeot #endif 147477eb7f9SFrançois Tigeot 148477eb7f9SFrançois Tigeot static int l3_access_valid(struct drm_device *dev, loff_t offset) 149477eb7f9SFrançois Tigeot { 150477eb7f9SFrançois Tigeot if (!HAS_L3_DPF(dev)) 151477eb7f9SFrançois Tigeot return -EPERM; 152477eb7f9SFrançois Tigeot 153477eb7f9SFrançois Tigeot if (offset % 4 != 0) 154477eb7f9SFrançois Tigeot return -EINVAL; 155477eb7f9SFrançois Tigeot 156477eb7f9SFrançois Tigeot if (offset >= GEN7_L3LOG_SIZE) 157477eb7f9SFrançois Tigeot return -ENXIO; 158477eb7f9SFrançois Tigeot 159477eb7f9SFrançois Tigeot return 0; 160477eb7f9SFrançois Tigeot } 161477eb7f9SFrançois Tigeot 162477eb7f9SFrançois Tigeot static ssize_t 163477eb7f9SFrançois Tigeot i915_l3_read(struct file *filp, struct kobject *kobj, 164477eb7f9SFrançois Tigeot struct bin_attribute *attr, char *buf, 165477eb7f9SFrançois Tigeot loff_t offset, size_t count) 166477eb7f9SFrançois Tigeot { 167477eb7f9SFrançois Tigeot struct device *dev = container_of(kobj, struct device, kobj); 168477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_to_drm_minor(dev); 169477eb7f9SFrançois Tigeot struct drm_device *drm_dev = dminor->dev; 170477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = drm_dev->dev_private; 171477eb7f9SFrançois Tigeot int slice = (int)(uintptr_t)attr->private; 172477eb7f9SFrançois Tigeot int ret; 173477eb7f9SFrançois Tigeot 174477eb7f9SFrançois Tigeot count = round_down(count, 4); 175477eb7f9SFrançois Tigeot 176477eb7f9SFrançois Tigeot ret = l3_access_valid(drm_dev, offset); 177477eb7f9SFrançois Tigeot if (ret) 178477eb7f9SFrançois Tigeot return ret; 179477eb7f9SFrançois Tigeot 180477eb7f9SFrançois Tigeot count = min_t(size_t, GEN7_L3LOG_SIZE - offset, count); 181477eb7f9SFrançois Tigeot 182477eb7f9SFrançois Tigeot ret = i915_mutex_lock_interruptible(drm_dev); 183477eb7f9SFrançois Tigeot if (ret) 184477eb7f9SFrançois Tigeot return ret; 185477eb7f9SFrançois Tigeot 186477eb7f9SFrançois Tigeot if (dev_priv->l3_parity.remap_info[slice]) 187477eb7f9SFrançois Tigeot memcpy(buf, 188477eb7f9SFrançois Tigeot dev_priv->l3_parity.remap_info[slice] + (offset/4), 189477eb7f9SFrançois Tigeot count); 190477eb7f9SFrançois Tigeot else 191477eb7f9SFrançois Tigeot memset(buf, 0, count); 192477eb7f9SFrançois Tigeot 193477eb7f9SFrançois Tigeot mutex_unlock(&drm_dev->struct_mutex); 194477eb7f9SFrançois Tigeot 195477eb7f9SFrançois Tigeot return count; 196477eb7f9SFrançois Tigeot } 197477eb7f9SFrançois Tigeot 198477eb7f9SFrançois Tigeot static ssize_t 199477eb7f9SFrançois Tigeot i915_l3_write(struct file *filp, struct kobject *kobj, 200477eb7f9SFrançois Tigeot struct bin_attribute *attr, char *buf, 201477eb7f9SFrançois Tigeot loff_t offset, size_t count) 202477eb7f9SFrançois Tigeot { 203477eb7f9SFrançois Tigeot struct device *dev = container_of(kobj, struct device, kobj); 204477eb7f9SFrançois Tigeot struct drm_minor *dminor = dev_to_drm_minor(dev); 205477eb7f9SFrançois Tigeot struct drm_device *drm_dev = dminor->dev; 206477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = drm_dev->dev_private; 207477eb7f9SFrançois Tigeot struct intel_context *ctx; 208477eb7f9SFrançois Tigeot u32 *temp = NULL; /* Just here to make handling failures easy */ 209477eb7f9SFrançois Tigeot int slice = (int)(uintptr_t)attr->private; 210477eb7f9SFrançois Tigeot int ret; 211477eb7f9SFrançois Tigeot 212477eb7f9SFrançois Tigeot if (!HAS_HW_CONTEXTS(drm_dev)) 213477eb7f9SFrançois Tigeot return -ENXIO; 214477eb7f9SFrançois Tigeot 215477eb7f9SFrançois Tigeot ret = l3_access_valid(drm_dev, offset); 216477eb7f9SFrançois Tigeot if (ret) 217477eb7f9SFrançois Tigeot return ret; 218477eb7f9SFrançois Tigeot 219477eb7f9SFrançois Tigeot ret = i915_mutex_lock_interruptible(drm_dev); 220477eb7f9SFrançois Tigeot if (ret) 221477eb7f9SFrançois Tigeot return ret; 222477eb7f9SFrançois Tigeot 223477eb7f9SFrançois Tigeot if (!dev_priv->l3_parity.remap_info[slice]) { 224477eb7f9SFrançois Tigeot temp = kzalloc(GEN7_L3LOG_SIZE, GFP_KERNEL); 225477eb7f9SFrançois Tigeot if (!temp) { 226477eb7f9SFrançois Tigeot mutex_unlock(&drm_dev->struct_mutex); 227477eb7f9SFrançois Tigeot return -ENOMEM; 228477eb7f9SFrançois Tigeot } 229477eb7f9SFrançois Tigeot } 230477eb7f9SFrançois Tigeot 231477eb7f9SFrançois Tigeot ret = i915_gpu_idle(drm_dev); 232477eb7f9SFrançois Tigeot if (ret) { 233477eb7f9SFrançois Tigeot kfree(temp); 234477eb7f9SFrançois Tigeot mutex_unlock(&drm_dev->struct_mutex); 235477eb7f9SFrançois Tigeot return ret; 236477eb7f9SFrançois Tigeot } 237477eb7f9SFrançois Tigeot 238477eb7f9SFrançois Tigeot /* TODO: Ideally we really want a GPU reset here to make sure errors 239477eb7f9SFrançois Tigeot * aren't propagated. Since I cannot find a stable way to reset the GPU 240477eb7f9SFrançois Tigeot * at this point it is left as a TODO. 241477eb7f9SFrançois Tigeot */ 242477eb7f9SFrançois Tigeot if (temp) 243477eb7f9SFrançois Tigeot dev_priv->l3_parity.remap_info[slice] = temp; 244477eb7f9SFrançois Tigeot 245477eb7f9SFrançois Tigeot memcpy(dev_priv->l3_parity.remap_info[slice] + (offset/4), buf, count); 246477eb7f9SFrançois Tigeot 247477eb7f9SFrançois Tigeot /* NB: We defer the remapping until we switch to the context */ 248477eb7f9SFrançois Tigeot list_for_each_entry(ctx, &dev_priv->context_list, link) 249477eb7f9SFrançois Tigeot ctx->remap_slice |= (1<<slice); 250477eb7f9SFrançois Tigeot 251477eb7f9SFrançois Tigeot mutex_unlock(&drm_dev->struct_mutex); 252477eb7f9SFrançois Tigeot 253477eb7f9SFrançois Tigeot return count; 254477eb7f9SFrançois Tigeot } 255477eb7f9SFrançois Tigeot 256477eb7f9SFrançois Tigeot static struct bin_attribute dpf_attrs = { 257477eb7f9SFrançois Tigeot .attr = {.name = "l3_parity", .mode = (S_IRUSR | S_IWUSR)}, 258477eb7f9SFrançois Tigeot .size = GEN7_L3LOG_SIZE, 259477eb7f9SFrançois Tigeot .read = i915_l3_read, 260477eb7f9SFrançois Tigeot .write = i915_l3_write, 261477eb7f9SFrançois Tigeot .mmap = NULL, 262477eb7f9SFrançois Tigeot .private = (void *)0 263477eb7f9SFrançois Tigeot }; 264477eb7f9SFrançois Tigeot 265477eb7f9SFrançois Tigeot static struct bin_attribute dpf_attrs_1 = { 266477eb7f9SFrançois Tigeot .attr = {.name = "l3_parity_slice_1", .mode = (S_IRUSR | S_IWUSR)}, 267477eb7f9SFrançois Tigeot .size = GEN7_L3LOG_SIZE, 268477eb7f9SFrançois Tigeot .read = i915_l3_read, 269477eb7f9SFrançois Tigeot .write = i915_l3_write, 270477eb7f9SFrançois Tigeot .mmap = NULL, 271477eb7f9SFrançois Tigeot .private = (void *)1 272477eb7f9SFrançois Tigeot }; 273477eb7f9SFrançois Tigeot 274477eb7f9SFrançois Tigeot static ssize_t gt_act_freq_mhz_show(struct device *kdev, 275477eb7f9SFrançois Tigeot struct device_attribute *attr, char *buf) 276477eb7f9SFrançois Tigeot { 277477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 278477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 279477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 280477eb7f9SFrançois Tigeot int ret; 281477eb7f9SFrançois Tigeot 282477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 283477eb7f9SFrançois Tigeot 284477eb7f9SFrançois Tigeot intel_runtime_pm_get(dev_priv); 285477eb7f9SFrançois Tigeot 286477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 287*aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 288477eb7f9SFrançois Tigeot u32 freq; 289477eb7f9SFrançois Tigeot freq = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS); 290477eb7f9SFrançois Tigeot ret = intel_gpu_freq(dev_priv, (freq >> 8) & 0xff); 291477eb7f9SFrançois Tigeot } else { 292477eb7f9SFrançois Tigeot u32 rpstat = I915_READ(GEN6_RPSTAT1); 293477eb7f9SFrançois Tigeot if (IS_GEN9(dev_priv)) 294477eb7f9SFrançois Tigeot ret = (rpstat & GEN9_CAGF_MASK) >> GEN9_CAGF_SHIFT; 295477eb7f9SFrançois Tigeot else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) 296477eb7f9SFrançois Tigeot ret = (rpstat & HSW_CAGF_MASK) >> HSW_CAGF_SHIFT; 297477eb7f9SFrançois Tigeot else 298477eb7f9SFrançois Tigeot ret = (rpstat & GEN6_CAGF_MASK) >> GEN6_CAGF_SHIFT; 299477eb7f9SFrançois Tigeot ret = intel_gpu_freq(dev_priv, ret); 300477eb7f9SFrançois Tigeot } 301477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 302477eb7f9SFrançois Tigeot 303477eb7f9SFrançois Tigeot intel_runtime_pm_put(dev_priv); 304477eb7f9SFrançois Tigeot 305477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%d\n", ret); 306477eb7f9SFrançois Tigeot } 307477eb7f9SFrançois Tigeot 308477eb7f9SFrançois Tigeot static ssize_t gt_cur_freq_mhz_show(struct device *kdev, 309477eb7f9SFrançois Tigeot struct device_attribute *attr, char *buf) 310477eb7f9SFrançois Tigeot { 311477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 312477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 313477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 314477eb7f9SFrançois Tigeot int ret; 315477eb7f9SFrançois Tigeot 316477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 317477eb7f9SFrançois Tigeot 318477eb7f9SFrançois Tigeot intel_runtime_pm_get(dev_priv); 319477eb7f9SFrançois Tigeot 320477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 321477eb7f9SFrançois Tigeot ret = intel_gpu_freq(dev_priv, dev_priv->rps.cur_freq); 322477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 323477eb7f9SFrançois Tigeot 324477eb7f9SFrançois Tigeot intel_runtime_pm_put(dev_priv); 325477eb7f9SFrançois Tigeot 326477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%d\n", ret); 327477eb7f9SFrançois Tigeot } 328477eb7f9SFrançois Tigeot 329477eb7f9SFrançois Tigeot static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, 330477eb7f9SFrançois Tigeot struct device_attribute *attr, char *buf) 331477eb7f9SFrançois Tigeot { 332477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 333477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 334477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 335477eb7f9SFrançois Tigeot 336477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, 337477eb7f9SFrançois Tigeot "%d\n", 338477eb7f9SFrançois Tigeot intel_gpu_freq(dev_priv, dev_priv->rps.efficient_freq)); 339477eb7f9SFrançois Tigeot } 340477eb7f9SFrançois Tigeot 341477eb7f9SFrançois Tigeot static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) 342477eb7f9SFrançois Tigeot { 343477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 344477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 345477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 346477eb7f9SFrançois Tigeot int ret; 347477eb7f9SFrançois Tigeot 348477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 349477eb7f9SFrançois Tigeot 350477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 351477eb7f9SFrançois Tigeot ret = intel_gpu_freq(dev_priv, dev_priv->rps.max_freq_softlimit); 352477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 353477eb7f9SFrançois Tigeot 354477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%d\n", ret); 355477eb7f9SFrançois Tigeot } 356477eb7f9SFrançois Tigeot 357477eb7f9SFrançois Tigeot static ssize_t gt_max_freq_mhz_store(struct device *kdev, 358477eb7f9SFrançois Tigeot struct device_attribute *attr, 359477eb7f9SFrançois Tigeot const char *buf, size_t count) 360477eb7f9SFrançois Tigeot { 361477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 362477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 363477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 364477eb7f9SFrançois Tigeot u32 val; 365477eb7f9SFrançois Tigeot ssize_t ret; 366477eb7f9SFrançois Tigeot 367477eb7f9SFrançois Tigeot ret = kstrtou32(buf, 0, &val); 368477eb7f9SFrançois Tigeot if (ret) 369477eb7f9SFrançois Tigeot return ret; 370477eb7f9SFrançois Tigeot 371477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 372477eb7f9SFrançois Tigeot 373477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 374477eb7f9SFrançois Tigeot 375477eb7f9SFrançois Tigeot val = intel_freq_opcode(dev_priv, val); 376477eb7f9SFrançois Tigeot 377477eb7f9SFrançois Tigeot if (val < dev_priv->rps.min_freq || 378477eb7f9SFrançois Tigeot val > dev_priv->rps.max_freq || 379477eb7f9SFrançois Tigeot val < dev_priv->rps.min_freq_softlimit) { 380477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 381477eb7f9SFrançois Tigeot return -EINVAL; 382477eb7f9SFrançois Tigeot } 383477eb7f9SFrançois Tigeot 384477eb7f9SFrançois Tigeot if (val > dev_priv->rps.rp0_freq) 385477eb7f9SFrançois Tigeot DRM_DEBUG("User requested overclocking to %d\n", 386477eb7f9SFrançois Tigeot intel_gpu_freq(dev_priv, val)); 387477eb7f9SFrançois Tigeot 388477eb7f9SFrançois Tigeot dev_priv->rps.max_freq_softlimit = val; 389477eb7f9SFrançois Tigeot 390477eb7f9SFrançois Tigeot val = clamp_t(int, dev_priv->rps.cur_freq, 391477eb7f9SFrançois Tigeot dev_priv->rps.min_freq_softlimit, 392477eb7f9SFrançois Tigeot dev_priv->rps.max_freq_softlimit); 393477eb7f9SFrançois Tigeot 394477eb7f9SFrançois Tigeot /* We still need *_set_rps to process the new max_delay and 395477eb7f9SFrançois Tigeot * update the interrupt limits and PMINTRMSK even though 396477eb7f9SFrançois Tigeot * frequency request may be unchanged. */ 397477eb7f9SFrançois Tigeot intel_set_rps(dev, val); 398477eb7f9SFrançois Tigeot 399477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 400477eb7f9SFrançois Tigeot 401477eb7f9SFrançois Tigeot return count; 402477eb7f9SFrançois Tigeot } 403477eb7f9SFrançois Tigeot 404477eb7f9SFrançois Tigeot static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) 405477eb7f9SFrançois Tigeot { 406477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 407477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 408477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 409477eb7f9SFrançois Tigeot int ret; 410477eb7f9SFrançois Tigeot 411477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 412477eb7f9SFrançois Tigeot 413477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 414477eb7f9SFrançois Tigeot ret = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq_softlimit); 415477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 416477eb7f9SFrançois Tigeot 417477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%d\n", ret); 418477eb7f9SFrançois Tigeot } 419477eb7f9SFrançois Tigeot 420477eb7f9SFrançois Tigeot static ssize_t gt_min_freq_mhz_store(struct device *kdev, 421477eb7f9SFrançois Tigeot struct device_attribute *attr, 422477eb7f9SFrançois Tigeot const char *buf, size_t count) 423477eb7f9SFrançois Tigeot { 424477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 425477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 426477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 427477eb7f9SFrançois Tigeot u32 val; 428477eb7f9SFrançois Tigeot ssize_t ret; 429477eb7f9SFrançois Tigeot 430477eb7f9SFrançois Tigeot ret = kstrtou32(buf, 0, &val); 431477eb7f9SFrançois Tigeot if (ret) 432477eb7f9SFrançois Tigeot return ret; 433477eb7f9SFrançois Tigeot 434477eb7f9SFrançois Tigeot flush_delayed_work(&dev_priv->rps.delayed_resume_work); 435477eb7f9SFrançois Tigeot 436477eb7f9SFrançois Tigeot mutex_lock(&dev_priv->rps.hw_lock); 437477eb7f9SFrançois Tigeot 438477eb7f9SFrançois Tigeot val = intel_freq_opcode(dev_priv, val); 439477eb7f9SFrançois Tigeot 440477eb7f9SFrançois Tigeot if (val < dev_priv->rps.min_freq || 441477eb7f9SFrançois Tigeot val > dev_priv->rps.max_freq || 442477eb7f9SFrançois Tigeot val > dev_priv->rps.max_freq_softlimit) { 443477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 444477eb7f9SFrançois Tigeot return -EINVAL; 445477eb7f9SFrançois Tigeot } 446477eb7f9SFrançois Tigeot 447477eb7f9SFrançois Tigeot dev_priv->rps.min_freq_softlimit = val; 448477eb7f9SFrançois Tigeot 449477eb7f9SFrançois Tigeot val = clamp_t(int, dev_priv->rps.cur_freq, 450477eb7f9SFrançois Tigeot dev_priv->rps.min_freq_softlimit, 451477eb7f9SFrançois Tigeot dev_priv->rps.max_freq_softlimit); 452477eb7f9SFrançois Tigeot 453477eb7f9SFrançois Tigeot /* We still need *_set_rps to process the new min_delay and 454477eb7f9SFrançois Tigeot * update the interrupt limits and PMINTRMSK even though 455477eb7f9SFrançois Tigeot * frequency request may be unchanged. */ 456477eb7f9SFrançois Tigeot intel_set_rps(dev, val); 457477eb7f9SFrançois Tigeot 458477eb7f9SFrançois Tigeot mutex_unlock(&dev_priv->rps.hw_lock); 459477eb7f9SFrançois Tigeot 460477eb7f9SFrançois Tigeot return count; 461477eb7f9SFrançois Tigeot 462477eb7f9SFrançois Tigeot } 463477eb7f9SFrançois Tigeot 464477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_act_freq_mhz, S_IRUGO, gt_act_freq_mhz_show, NULL); 465477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_cur_freq_mhz, S_IRUGO, gt_cur_freq_mhz_show, NULL); 466477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_max_freq_mhz, S_IRUGO | S_IWUSR, gt_max_freq_mhz_show, gt_max_freq_mhz_store); 467477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_min_freq_mhz, S_IRUGO | S_IWUSR, gt_min_freq_mhz_show, gt_min_freq_mhz_store); 468477eb7f9SFrançois Tigeot 469477eb7f9SFrançois Tigeot static DEVICE_ATTR(vlv_rpe_freq_mhz, S_IRUGO, vlv_rpe_freq_mhz_show, NULL); 470477eb7f9SFrançois Tigeot 471477eb7f9SFrançois Tigeot static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf); 472477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RP0_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); 473477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RP1_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); 474477eb7f9SFrançois Tigeot static DEVICE_ATTR(gt_RPn_freq_mhz, S_IRUGO, gt_rp_mhz_show, NULL); 475477eb7f9SFrançois Tigeot 476477eb7f9SFrançois Tigeot /* For now we have a static number of RP states */ 477477eb7f9SFrançois Tigeot static ssize_t gt_rp_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) 478477eb7f9SFrançois Tigeot { 479477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 480477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 481477eb7f9SFrançois Tigeot struct drm_i915_private *dev_priv = dev->dev_private; 482477eb7f9SFrançois Tigeot u32 val; 483477eb7f9SFrançois Tigeot 484477eb7f9SFrançois Tigeot if (attr == &dev_attr_gt_RP0_freq_mhz) 485477eb7f9SFrançois Tigeot val = intel_gpu_freq(dev_priv, dev_priv->rps.rp0_freq); 486477eb7f9SFrançois Tigeot else if (attr == &dev_attr_gt_RP1_freq_mhz) 487477eb7f9SFrançois Tigeot val = intel_gpu_freq(dev_priv, dev_priv->rps.rp1_freq); 488477eb7f9SFrançois Tigeot else if (attr == &dev_attr_gt_RPn_freq_mhz) 489477eb7f9SFrançois Tigeot val = intel_gpu_freq(dev_priv, dev_priv->rps.min_freq); 490477eb7f9SFrançois Tigeot else 491477eb7f9SFrançois Tigeot BUG(); 492477eb7f9SFrançois Tigeot 493477eb7f9SFrançois Tigeot return snprintf(buf, PAGE_SIZE, "%d\n", val); 494477eb7f9SFrançois Tigeot } 495477eb7f9SFrançois Tigeot 496477eb7f9SFrançois Tigeot static const struct attribute *gen6_attrs[] = { 497477eb7f9SFrançois Tigeot &dev_attr_gt_act_freq_mhz.attr, 498477eb7f9SFrançois Tigeot &dev_attr_gt_cur_freq_mhz.attr, 499477eb7f9SFrançois Tigeot &dev_attr_gt_max_freq_mhz.attr, 500477eb7f9SFrançois Tigeot &dev_attr_gt_min_freq_mhz.attr, 501477eb7f9SFrançois Tigeot &dev_attr_gt_RP0_freq_mhz.attr, 502477eb7f9SFrançois Tigeot &dev_attr_gt_RP1_freq_mhz.attr, 503477eb7f9SFrançois Tigeot &dev_attr_gt_RPn_freq_mhz.attr, 504477eb7f9SFrançois Tigeot NULL, 505477eb7f9SFrançois Tigeot }; 506477eb7f9SFrançois Tigeot 507477eb7f9SFrançois Tigeot static const struct attribute *vlv_attrs[] = { 508477eb7f9SFrançois Tigeot &dev_attr_gt_act_freq_mhz.attr, 509477eb7f9SFrançois Tigeot &dev_attr_gt_cur_freq_mhz.attr, 510477eb7f9SFrançois Tigeot &dev_attr_gt_max_freq_mhz.attr, 511477eb7f9SFrançois Tigeot &dev_attr_gt_min_freq_mhz.attr, 512477eb7f9SFrançois Tigeot &dev_attr_gt_RP0_freq_mhz.attr, 513477eb7f9SFrançois Tigeot &dev_attr_gt_RP1_freq_mhz.attr, 514477eb7f9SFrançois Tigeot &dev_attr_gt_RPn_freq_mhz.attr, 515477eb7f9SFrançois Tigeot &dev_attr_vlv_rpe_freq_mhz.attr, 516477eb7f9SFrançois Tigeot NULL, 517477eb7f9SFrançois Tigeot }; 518477eb7f9SFrançois Tigeot 519477eb7f9SFrançois Tigeot static ssize_t error_state_read(struct file *filp, struct kobject *kobj, 520477eb7f9SFrançois Tigeot struct bin_attribute *attr, char *buf, 521477eb7f9SFrançois Tigeot loff_t off, size_t count) 522477eb7f9SFrançois Tigeot { 523477eb7f9SFrançois Tigeot 524477eb7f9SFrançois Tigeot struct device *kdev = container_of(kobj, struct device, kobj); 525477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 526477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 527477eb7f9SFrançois Tigeot struct i915_error_state_file_priv error_priv; 528477eb7f9SFrançois Tigeot struct drm_i915_error_state_buf error_str; 529477eb7f9SFrançois Tigeot ssize_t ret_count = 0; 530477eb7f9SFrançois Tigeot int ret; 531477eb7f9SFrançois Tigeot 532477eb7f9SFrançois Tigeot memset(&error_priv, 0, sizeof(error_priv)); 533477eb7f9SFrançois Tigeot 534477eb7f9SFrançois Tigeot ret = i915_error_state_buf_init(&error_str, to_i915(dev), count, off); 535477eb7f9SFrançois Tigeot if (ret) 536477eb7f9SFrançois Tigeot return ret; 537477eb7f9SFrançois Tigeot 538477eb7f9SFrançois Tigeot error_priv.dev = dev; 539477eb7f9SFrançois Tigeot i915_error_state_get(dev, &error_priv); 540477eb7f9SFrançois Tigeot 541477eb7f9SFrançois Tigeot ret = i915_error_state_to_str(&error_str, &error_priv); 542477eb7f9SFrançois Tigeot if (ret) 543477eb7f9SFrançois Tigeot goto out; 544477eb7f9SFrançois Tigeot 545477eb7f9SFrançois Tigeot ret_count = count < error_str.bytes ? count : error_str.bytes; 546477eb7f9SFrançois Tigeot 547477eb7f9SFrançois Tigeot memcpy(buf, error_str.buf, ret_count); 548477eb7f9SFrançois Tigeot out: 549477eb7f9SFrançois Tigeot i915_error_state_put(&error_priv); 550477eb7f9SFrançois Tigeot i915_error_state_buf_release(&error_str); 551477eb7f9SFrançois Tigeot 552477eb7f9SFrançois Tigeot return ret ?: ret_count; 553477eb7f9SFrançois Tigeot } 554477eb7f9SFrançois Tigeot 555477eb7f9SFrançois Tigeot static ssize_t error_state_write(struct file *file, struct kobject *kobj, 556477eb7f9SFrançois Tigeot struct bin_attribute *attr, char *buf, 557477eb7f9SFrançois Tigeot loff_t off, size_t count) 558477eb7f9SFrançois Tigeot { 559477eb7f9SFrançois Tigeot struct device *kdev = container_of(kobj, struct device, kobj); 560477eb7f9SFrançois Tigeot struct drm_minor *minor = dev_to_drm_minor(kdev); 561477eb7f9SFrançois Tigeot struct drm_device *dev = minor->dev; 562477eb7f9SFrançois Tigeot int ret; 563477eb7f9SFrançois Tigeot 564477eb7f9SFrançois Tigeot DRM_DEBUG_DRIVER("Resetting error state\n"); 565477eb7f9SFrançois Tigeot 566477eb7f9SFrançois Tigeot ret = mutex_lock_interruptible(&dev->struct_mutex); 567477eb7f9SFrançois Tigeot if (ret) 568477eb7f9SFrançois Tigeot return ret; 569477eb7f9SFrançois Tigeot 570477eb7f9SFrançois Tigeot i915_destroy_error_state(dev); 571477eb7f9SFrançois Tigeot mutex_unlock(&dev->struct_mutex); 572477eb7f9SFrançois Tigeot 573477eb7f9SFrançois Tigeot return count; 574477eb7f9SFrançois Tigeot } 575477eb7f9SFrançois Tigeot 576477eb7f9SFrançois Tigeot static struct bin_attribute error_state_attr = { 577477eb7f9SFrançois Tigeot .attr.name = "error", 578477eb7f9SFrançois Tigeot .attr.mode = S_IRUSR | S_IWUSR, 579477eb7f9SFrançois Tigeot .size = 0, 580477eb7f9SFrançois Tigeot .read = error_state_read, 581477eb7f9SFrançois Tigeot .write = error_state_write, 582477eb7f9SFrançois Tigeot }; 583477eb7f9SFrançois Tigeot #endif 584477eb7f9SFrançois Tigeot 585477eb7f9SFrançois Tigeot void i915_setup_sysfs(struct drm_device *dev) 586477eb7f9SFrançois Tigeot { 587477eb7f9SFrançois Tigeot #if 0 588477eb7f9SFrançois Tigeot int ret; 589477eb7f9SFrançois Tigeot 590477eb7f9SFrançois Tigeot #ifdef CONFIG_PM 591477eb7f9SFrançois Tigeot if (HAS_RC6(dev)) { 592477eb7f9SFrançois Tigeot ret = sysfs_merge_group(&dev->primary->kdev->kobj, 593477eb7f9SFrançois Tigeot &rc6_attr_group); 594477eb7f9SFrançois Tigeot if (ret) 595477eb7f9SFrançois Tigeot DRM_ERROR("RC6 residency sysfs setup failed\n"); 596477eb7f9SFrançois Tigeot } 597477eb7f9SFrançois Tigeot if (HAS_RC6p(dev)) { 598477eb7f9SFrançois Tigeot ret = sysfs_merge_group(&dev->primary->kdev->kobj, 599477eb7f9SFrançois Tigeot &rc6p_attr_group); 600477eb7f9SFrançois Tigeot if (ret) 601477eb7f9SFrançois Tigeot DRM_ERROR("RC6p residency sysfs setup failed\n"); 602477eb7f9SFrançois Tigeot } 603*aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { 604477eb7f9SFrançois Tigeot ret = sysfs_merge_group(&dev->primary->kdev->kobj, 605477eb7f9SFrançois Tigeot &media_rc6_attr_group); 606477eb7f9SFrançois Tigeot if (ret) 607477eb7f9SFrançois Tigeot DRM_ERROR("Media RC6 residency sysfs setup failed\n"); 608477eb7f9SFrançois Tigeot } 609477eb7f9SFrançois Tigeot #endif 610477eb7f9SFrançois Tigeot if (HAS_L3_DPF(dev)) { 611477eb7f9SFrançois Tigeot ret = device_create_bin_file(dev->primary->kdev, &dpf_attrs); 612477eb7f9SFrançois Tigeot if (ret) 613477eb7f9SFrançois Tigeot DRM_ERROR("l3 parity sysfs setup failed\n"); 614477eb7f9SFrançois Tigeot 615477eb7f9SFrançois Tigeot if (NUM_L3_SLICES(dev) > 1) { 616477eb7f9SFrançois Tigeot ret = device_create_bin_file(dev->primary->kdev, 617477eb7f9SFrançois Tigeot &dpf_attrs_1); 618477eb7f9SFrançois Tigeot if (ret) 619477eb7f9SFrançois Tigeot DRM_ERROR("l3 parity slice 1 setup failed\n"); 620477eb7f9SFrançois Tigeot } 621477eb7f9SFrançois Tigeot } 622477eb7f9SFrançois Tigeot 623477eb7f9SFrançois Tigeot ret = 0; 624*aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) 625477eb7f9SFrançois Tigeot ret = sysfs_create_files(&dev->primary->kdev->kobj, vlv_attrs); 626477eb7f9SFrançois Tigeot else if (INTEL_INFO(dev)->gen >= 6) 627477eb7f9SFrançois Tigeot ret = sysfs_create_files(&dev->primary->kdev->kobj, gen6_attrs); 628477eb7f9SFrançois Tigeot if (ret) 629477eb7f9SFrançois Tigeot DRM_ERROR("RPS sysfs setup failed\n"); 630477eb7f9SFrançois Tigeot 631477eb7f9SFrançois Tigeot ret = sysfs_create_bin_file(&dev->primary->kdev->kobj, 632477eb7f9SFrançois Tigeot &error_state_attr); 633477eb7f9SFrançois Tigeot if (ret) 634477eb7f9SFrançois Tigeot DRM_ERROR("error_state sysfs setup failed\n"); 635477eb7f9SFrançois Tigeot #endif 636477eb7f9SFrançois Tigeot } 637477eb7f9SFrançois Tigeot 638477eb7f9SFrançois Tigeot void i915_teardown_sysfs(struct drm_device *dev) 639477eb7f9SFrançois Tigeot { 640477eb7f9SFrançois Tigeot #if 0 641477eb7f9SFrançois Tigeot sysfs_remove_bin_file(&dev->primary->kdev->kobj, &error_state_attr); 642*aee94f86SFrançois Tigeot if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) 643477eb7f9SFrançois Tigeot sysfs_remove_files(&dev->primary->kdev->kobj, vlv_attrs); 644477eb7f9SFrançois Tigeot else 645477eb7f9SFrançois Tigeot sysfs_remove_files(&dev->primary->kdev->kobj, gen6_attrs); 646477eb7f9SFrançois Tigeot device_remove_bin_file(dev->primary->kdev, &dpf_attrs_1); 647477eb7f9SFrançois Tigeot device_remove_bin_file(dev->primary->kdev, &dpf_attrs); 648477eb7f9SFrançois Tigeot #ifdef CONFIG_PM 649477eb7f9SFrançois Tigeot sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6_attr_group); 650477eb7f9SFrançois Tigeot sysfs_unmerge_group(&dev->primary->kdev->kobj, &rc6p_attr_group); 651477eb7f9SFrançois Tigeot #endif 652477eb7f9SFrançois Tigeot #endif 653477eb7f9SFrançois Tigeot } 654