drm/nouveau/i2c: pass the function pointers in at creation time
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 23 Aug 2013 17:03:14 +0000 (13:03 -0400)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 4 Sep 2013 03:46:58 +0000 (13:46 +1000)
i2c_bit_add_bus can call the pre_xfer function, which expects the func
pointer to be set. Pass in func to the port creation logic so that it is
set before i2c_bit_add_bus.

See https://bugs.freedesktop.org/show_bug.cgi?id=68456

Reported-by: Hans-Peter Deifel <hpdeifel@gmx.de>
Tested-by: Hans-Peter Deifel <hpdeifel@gmx.de>
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c
drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c
drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c

index 888384c0bed86230914dac0a1991a37c6fff21c8..7e4e2775f249652459c83bd66d89eeb50f2899c2 100644 (file)
@@ -39,8 +39,8 @@ struct nouveau_i2c_func {
        int  (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe);
 };
 
-#define nouveau_i2c_port_create(p,e,o,i,a,d)                                   \
-       nouveau_i2c_port_create_((p), (e), (o), (i), (a),                      \
+#define nouveau_i2c_port_create(p,e,o,i,a,f,d)                                 \
+       nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f),                 \
                                 sizeof(**d), (void **)d)
 #define nouveau_i2c_port_destroy(p) ({                                         \
        struct nouveau_i2c_port *port = (p);                                   \
@@ -53,7 +53,9 @@ struct nouveau_i2c_func {
 
 int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *,
                             struct nouveau_oclass *, u8,
-                            const struct i2c_algorithm *, int, void **);
+                            const struct i2c_algorithm *,
+                            const struct nouveau_i2c_func *,
+                            int, void **);
 void _nouveau_i2c_port_dtor(struct nouveau_object *);
 #define _nouveau_i2c_port_init nouveau_object_init
 #define _nouveau_i2c_port_fini nouveau_object_fini
index dec94e9d776af97deeec8e44150e4fe744cc06cd..4b195ac4da6609dc2be937415822d5bf33ad1b35 100644 (file)
@@ -118,7 +118,8 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_aux_algo, &chan);
+                                     &nouveau_i2c_aux_algo, &anx9805_aux_func,
+                                     &chan);
        *pobject = nv_object(chan);
        if (ret)
                return ret;
@@ -140,8 +141,6 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent,
                struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
                algo->udelay = max(algo->udelay, 40);
        }
-
-       chan->base.func = &anx9805_aux_func;
        return 0;
 }
 
@@ -234,7 +233,8 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &anx9805_i2c_algo, &port);
+                                     &anx9805_i2c_algo, &anx9805_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
@@ -256,8 +256,6 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent,
                struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
                algo->udelay = max(algo->udelay, 40);
        }
-
-       port->base.func = &anx9805_i2c_func;
        return 0;
 }
 
index 8ae2625415e155b22b3c97459c54e3f3d939fd22..2895c19bb1529f14196a4ff36d6861af57c35dd4 100644 (file)
@@ -95,6 +95,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
                         struct nouveau_object *engine,
                         struct nouveau_oclass *oclass, u8 index,
                         const struct i2c_algorithm *algo,
+                        const struct nouveau_i2c_func *func,
                         int size, void **pobject)
 {
        struct nouveau_device *device = nv_device(parent);
@@ -112,6 +113,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
        port->adapter.owner = THIS_MODULE;
        port->adapter.dev.parent = &device->pdev->dev;
        port->index = index;
+       port->func = func;
        i2c_set_adapdata(&port->adapter, i2c);
 
        if ( algo == &nouveau_i2c_bit_algo &&
index 2ad18840fe63be9a83ac1511d150c0959860c8b8..860d5d2365dac4e6c76a7dcf7c6301b416bfba22 100644 (file)
@@ -91,12 +91,12 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_bit_algo, &port);
+                                     &nouveau_i2c_bit_algo, &nv04_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
 
-       port->base.func = &nv04_i2c_func;
        port->drive = info->drive;
        port->sense = info->sense;
        return 0;
index f501ae25dbb3e74ef2e8437f6006c3e99d73458a..0c2655a03bb43f98fbac43b8d0053259b78c57e5 100644 (file)
@@ -84,12 +84,12 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_bit_algo, &port);
+                                     &nouveau_i2c_bit_algo, &nv4e_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
 
-       port->base.func = &nv4e_i2c_func;
        port->addr = 0x600800 + info->drive;
        return 0;
 }
index 378dfa324e5f7e7f9b72e9490901f187f930201e..a8d67a287704df9272af233e5fc755780fca8670 100644 (file)
@@ -85,7 +85,8 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_bit_algo, &port);
+                                     &nouveau_i2c_bit_algo, &nv50_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
@@ -93,7 +94,6 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        if (info->drive >= nv50_i2c_addr_nr)
                return -EINVAL;
 
-       port->base.func = &nv50_i2c_func;
        port->state = 0x00000007;
        port->addr = nv50_i2c_addr[info->drive];
        return 0;
index 61b771670bfeac8de3f5d41957bb1d966eb2fd8d..df6d3e4b68bef1c5975f47f42cd1d6caa35a9b4d 100644 (file)
@@ -186,7 +186,8 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_bit_algo, &port);
+                                     &nouveau_i2c_bit_algo, &nv94_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
@@ -194,7 +195,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        if (info->drive >= nv50_i2c_addr_nr)
                return -EINVAL;
 
-       port->base.func = &nv94_i2c_func;
        port->state = 7;
        port->addr = nv50_i2c_addr[info->drive];
        if (info->share != DCB_I2C_UNUSED) {
@@ -221,12 +221,12 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_aux_algo, &port);
+                                     &nouveau_i2c_aux_algo, &nv94_aux_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
 
-       port->base.func = &nv94_aux_func;
        port->addr = info->drive;
        if (info->share != DCB_I2C_UNUSED) {
                port->ctrl = 0x00e500 + (info->drive * 0x50);
index f761b8a610f13692496f1454717d91ce17e4a2d6..29967d30f97cbcbb7a1c3e889dd7310a98897e02 100644 (file)
@@ -60,12 +60,12 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        int ret;
 
        ret = nouveau_i2c_port_create(parent, engine, oclass, index,
-                                    &nouveau_i2c_bit_algo, &port);
+                                     &nouveau_i2c_bit_algo, &nvd0_i2c_func,
+                                     &port);
        *pobject = nv_object(port);
        if (ret)
                return ret;
 
-       port->base.func = &nvd0_i2c_func;
        port->state = 0x00000007;
        port->addr = 0x00d014 + (info->drive * 0x20);
        if (info->share != DCB_I2C_UNUSED) {