Use with caution.
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
        int tstate; /* thermal adjustment (max-) */
        int dstate; /* display adjustment (min+) */
 
+       bool allow_reclock;
+
        int  (*read)(struct nouveau_clock *, enum nv_clk_src);
        int  (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
        int  (*prog)(struct nouveau_clock *);
        int mdiv;
 };
 
-#define nouveau_clock_create(p,e,o,i,d)                                        \
-       nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d)
+#define nouveau_clock_create(p,e,o,i,r,d)                                      \
+       nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d)
 #define nouveau_clock_destroy(p) ({                                            \
        struct nouveau_clock *clk = (p);                                       \
        _nouveau_clock_dtor(nv_object(clk));                                   \
 
 int  nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
                           struct nouveau_oclass *,
-                          struct nouveau_clocks *, int, void **);
+                          struct nouveau_clocks *, bool, int, void **);
 void _nouveau_clock_dtor(struct nouveau_object *);
 int _nouveau_clock_init(struct nouveau_object *);
 #define _nouveau_clock_fini _nouveau_subdev_fini
 
        struct nouveau_pstate *pstate;
        int i = 0;
 
-       /* YKW repellant */
-       return -ENOSYS;
+       if (!clk->allow_reclock)
+               return -ENOSYS;
 
        if (req != -1 && req != -2) {
                list_for_each_entry(pstate, &clk->states, head) {
                      struct nouveau_object *engine,
                      struct nouveau_oclass *oclass,
                      struct nouveau_clocks *clocks,
+                     bool allow_reclock,
                      int length, void **object)
 {
        struct nouveau_device *device = nv_device(parent);
                ret = nouveau_pstate_new(clk, idx++);
        } while (ret == 0);
 
+       clk->allow_reclock = allow_reclock;
+
        mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen);
        if (mode) {
                if (!strncasecmpz(mode, "disabled", arglen)) {
 
        struct nv04_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        struct nv40_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        int ret;
 
        ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
-                                 &priv);
+                                  false, &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        struct nva3_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        struct nvaa_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        struct nvc0_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;
 
        struct nve0_clock_priv *priv;
        int ret;
 
-       ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv);
+       ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true,
+                                  &priv);
        *pobject = nv_object(priv);
        if (ret)
                return ret;