diff options
| author | Ilia Mirkin <imirkin@alum.mit.edu> | 2013-08-23 13:03:14 -0400 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2013-09-03 23:46:58 -0400 |
| commit | c865534f1e5b5b4ef03f4a55cf4730f4b70dd75b (patch) | |
| tree | bd17cd7a9d546620acc877048cb48554e0e8068c /drivers | |
| parent | c4a62a766062c268d08c1aacf2e18e057e277db4 (diff) | |
drm/nouveau/i2c: pass the function pointers in at creation time
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>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/include/subdev/i2c.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c | 4 |
8 files changed, 23 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 888384c0bed8..7e4e2775f249 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h | |||
| @@ -39,8 +39,8 @@ struct nouveau_i2c_func { | |||
| 39 | int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); | 39 | int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | #define nouveau_i2c_port_create(p,e,o,i,a,d) \ | 42 | #define nouveau_i2c_port_create(p,e,o,i,a,f,d) \ |
| 43 | nouveau_i2c_port_create_((p), (e), (o), (i), (a), \ | 43 | nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \ |
| 44 | sizeof(**d), (void **)d) | 44 | sizeof(**d), (void **)d) |
| 45 | #define nouveau_i2c_port_destroy(p) ({ \ | 45 | #define nouveau_i2c_port_destroy(p) ({ \ |
| 46 | struct nouveau_i2c_port *port = (p); \ | 46 | struct nouveau_i2c_port *port = (p); \ |
| @@ -53,7 +53,9 @@ struct nouveau_i2c_func { | |||
| 53 | 53 | ||
| 54 | int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, | 54 | int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, |
| 55 | struct nouveau_oclass *, u8, | 55 | struct nouveau_oclass *, u8, |
| 56 | const struct i2c_algorithm *, int, void **); | 56 | const struct i2c_algorithm *, |
| 57 | const struct nouveau_i2c_func *, | ||
| 58 | int, void **); | ||
| 57 | void _nouveau_i2c_port_dtor(struct nouveau_object *); | 59 | void _nouveau_i2c_port_dtor(struct nouveau_object *); |
| 58 | #define _nouveau_i2c_port_init nouveau_object_init | 60 | #define _nouveau_i2c_port_init nouveau_object_init |
| 59 | #define _nouveau_i2c_port_fini nouveau_object_fini | 61 | #define _nouveau_i2c_port_fini nouveau_object_fini |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c index dec94e9d776a..4b195ac4da66 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c | |||
| @@ -118,7 +118,8 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, | |||
| 118 | int ret; | 118 | int ret; |
| 119 | 119 | ||
| 120 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 120 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 121 | &nouveau_i2c_aux_algo, &chan); | 121 | &nouveau_i2c_aux_algo, &anx9805_aux_func, |
| 122 | &chan); | ||
| 122 | *pobject = nv_object(chan); | 123 | *pobject = nv_object(chan); |
| 123 | if (ret) | 124 | if (ret) |
| 124 | return ret; | 125 | return ret; |
| @@ -140,8 +141,6 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, | |||
| 140 | struct i2c_algo_bit_data *algo = mast->adapter.algo_data; | 141 | struct i2c_algo_bit_data *algo = mast->adapter.algo_data; |
| 141 | algo->udelay = max(algo->udelay, 40); | 142 | algo->udelay = max(algo->udelay, 40); |
| 142 | } | 143 | } |
| 143 | |||
| 144 | chan->base.func = &anx9805_aux_func; | ||
| 145 | return 0; | 144 | return 0; |
| 146 | } | 145 | } |
| 147 | 146 | ||
| @@ -234,7 +233,8 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, | |||
| 234 | int ret; | 233 | int ret; |
| 235 | 234 | ||
| 236 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 235 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 237 | &anx9805_i2c_algo, &port); | 236 | &anx9805_i2c_algo, &anx9805_i2c_func, |
| 237 | &port); | ||
| 238 | *pobject = nv_object(port); | 238 | *pobject = nv_object(port); |
| 239 | if (ret) | 239 | if (ret) |
| 240 | return ret; | 240 | return ret; |
| @@ -256,8 +256,6 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, | |||
| 256 | struct i2c_algo_bit_data *algo = mast->adapter.algo_data; | 256 | struct i2c_algo_bit_data *algo = mast->adapter.algo_data; |
| 257 | algo->udelay = max(algo->udelay, 40); | 257 | algo->udelay = max(algo->udelay, 40); |
| 258 | } | 258 | } |
| 259 | |||
| 260 | port->base.func = &anx9805_i2c_func; | ||
| 261 | return 0; | 259 | return 0; |
| 262 | } | 260 | } |
| 263 | 261 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 8ae2625415e1..2895c19bb152 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | |||
| @@ -95,6 +95,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, | |||
| 95 | struct nouveau_object *engine, | 95 | struct nouveau_object *engine, |
| 96 | struct nouveau_oclass *oclass, u8 index, | 96 | struct nouveau_oclass *oclass, u8 index, |
| 97 | const struct i2c_algorithm *algo, | 97 | const struct i2c_algorithm *algo, |
| 98 | const struct nouveau_i2c_func *func, | ||
| 98 | int size, void **pobject) | 99 | int size, void **pobject) |
| 99 | { | 100 | { |
| 100 | struct nouveau_device *device = nv_device(parent); | 101 | struct nouveau_device *device = nv_device(parent); |
| @@ -112,6 +113,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, | |||
| 112 | port->adapter.owner = THIS_MODULE; | 113 | port->adapter.owner = THIS_MODULE; |
| 113 | port->adapter.dev.parent = &device->pdev->dev; | 114 | port->adapter.dev.parent = &device->pdev->dev; |
| 114 | port->index = index; | 115 | port->index = index; |
| 116 | port->func = func; | ||
| 115 | i2c_set_adapdata(&port->adapter, i2c); | 117 | i2c_set_adapdata(&port->adapter, i2c); |
| 116 | 118 | ||
| 117 | if ( algo == &nouveau_i2c_bit_algo && | 119 | if ( algo == &nouveau_i2c_bit_algo && |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c index 2ad18840fe63..860d5d2365da 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c | |||
| @@ -91,12 +91,12 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 91 | int ret; | 91 | int ret; |
| 92 | 92 | ||
| 93 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 93 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 94 | &nouveau_i2c_bit_algo, &port); | 94 | &nouveau_i2c_bit_algo, &nv04_i2c_func, |
| 95 | &port); | ||
| 95 | *pobject = nv_object(port); | 96 | *pobject = nv_object(port); |
| 96 | if (ret) | 97 | if (ret) |
| 97 | return ret; | 98 | return ret; |
| 98 | 99 | ||
| 99 | port->base.func = &nv04_i2c_func; | ||
| 100 | port->drive = info->drive; | 100 | port->drive = info->drive; |
| 101 | port->sense = info->sense; | 101 | port->sense = info->sense; |
| 102 | return 0; | 102 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c index f501ae25dbb3..0c2655a03bb4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c | |||
| @@ -84,12 +84,12 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 84 | int ret; | 84 | int ret; |
| 85 | 85 | ||
| 86 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 86 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 87 | &nouveau_i2c_bit_algo, &port); | 87 | &nouveau_i2c_bit_algo, &nv4e_i2c_func, |
| 88 | &port); | ||
| 88 | *pobject = nv_object(port); | 89 | *pobject = nv_object(port); |
| 89 | if (ret) | 90 | if (ret) |
| 90 | return ret; | 91 | return ret; |
| 91 | 92 | ||
| 92 | port->base.func = &nv4e_i2c_func; | ||
| 93 | port->addr = 0x600800 + info->drive; | 93 | port->addr = 0x600800 + info->drive; |
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c index 378dfa324e5f..a8d67a287704 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c | |||
| @@ -85,7 +85,8 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 85 | int ret; | 85 | int ret; |
| 86 | 86 | ||
| 87 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 87 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 88 | &nouveau_i2c_bit_algo, &port); | 88 | &nouveau_i2c_bit_algo, &nv50_i2c_func, |
| 89 | &port); | ||
| 89 | *pobject = nv_object(port); | 90 | *pobject = nv_object(port); |
| 90 | if (ret) | 91 | if (ret) |
| 91 | return ret; | 92 | return ret; |
| @@ -93,7 +94,6 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 93 | if (info->drive >= nv50_i2c_addr_nr) | 94 | if (info->drive >= nv50_i2c_addr_nr) |
| 94 | return -EINVAL; | 95 | return -EINVAL; |
| 95 | 96 | ||
| 96 | port->base.func = &nv50_i2c_func; | ||
| 97 | port->state = 0x00000007; | 97 | port->state = 0x00000007; |
| 98 | port->addr = nv50_i2c_addr[info->drive]; | 98 | port->addr = nv50_i2c_addr[info->drive]; |
| 99 | return 0; | 99 | return 0; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c index 61b771670bfe..df6d3e4b68be 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c | |||
| @@ -186,7 +186,8 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 186 | int ret; | 186 | int ret; |
| 187 | 187 | ||
| 188 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 188 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 189 | &nouveau_i2c_bit_algo, &port); | 189 | &nouveau_i2c_bit_algo, &nv94_i2c_func, |
| 190 | &port); | ||
| 190 | *pobject = nv_object(port); | 191 | *pobject = nv_object(port); |
| 191 | if (ret) | 192 | if (ret) |
| 192 | return ret; | 193 | return ret; |
| @@ -194,7 +195,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 194 | if (info->drive >= nv50_i2c_addr_nr) | 195 | if (info->drive >= nv50_i2c_addr_nr) |
| 195 | return -EINVAL; | 196 | return -EINVAL; |
| 196 | 197 | ||
| 197 | port->base.func = &nv94_i2c_func; | ||
| 198 | port->state = 7; | 198 | port->state = 7; |
| 199 | port->addr = nv50_i2c_addr[info->drive]; | 199 | port->addr = nv50_i2c_addr[info->drive]; |
| 200 | if (info->share != DCB_I2C_UNUSED) { | 200 | if (info->share != DCB_I2C_UNUSED) { |
| @@ -221,12 +221,12 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 221 | int ret; | 221 | int ret; |
| 222 | 222 | ||
| 223 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 223 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 224 | &nouveau_i2c_aux_algo, &port); | 224 | &nouveau_i2c_aux_algo, &nv94_aux_func, |
| 225 | &port); | ||
| 225 | *pobject = nv_object(port); | 226 | *pobject = nv_object(port); |
| 226 | if (ret) | 227 | if (ret) |
| 227 | return ret; | 228 | return ret; |
| 228 | 229 | ||
| 229 | port->base.func = &nv94_aux_func; | ||
| 230 | port->addr = info->drive; | 230 | port->addr = info->drive; |
| 231 | if (info->share != DCB_I2C_UNUSED) { | 231 | if (info->share != DCB_I2C_UNUSED) { |
| 232 | port->ctrl = 0x00e500 + (info->drive * 0x50); | 232 | port->ctrl = 0x00e500 + (info->drive * 0x50); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c index f761b8a610f1..29967d30f97c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c | |||
| @@ -60,12 +60,12 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
| 60 | int ret; | 60 | int ret; |
| 61 | 61 | ||
| 62 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, | 62 | ret = nouveau_i2c_port_create(parent, engine, oclass, index, |
| 63 | &nouveau_i2c_bit_algo, &port); | 63 | &nouveau_i2c_bit_algo, &nvd0_i2c_func, |
| 64 | &port); | ||
| 64 | *pobject = nv_object(port); | 65 | *pobject = nv_object(port); |
| 65 | if (ret) | 66 | if (ret) |
| 66 | return ret; | 67 | return ret; |
| 67 | 68 | ||
| 68 | port->base.func = &nvd0_i2c_func; | ||
| 69 | port->state = 0x00000007; | 69 | port->state = 0x00000007; |
| 70 | port->addr = 0x00d014 + (info->drive * 0x20); | 70 | port->addr = 0x00d014 + (info->drive * 0x20); |
| 71 | if (info->share != DCB_I2C_UNUSED) { | 71 | if (info->share != DCB_I2C_UNUSED) { |
