提交 c865534f 编写于 作者: I Ilia Mirkin 提交者: Ben Skeggs

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=68456Reported-by: NHans-Peter Deifel <hpdeifel@gmx.de>
Tested-by: NHans-Peter Deifel <hpdeifel@gmx.de>
Signed-off-by: NIlia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 c4a62a76
...@@ -39,8 +39,8 @@ struct nouveau_i2c_func { ...@@ -39,8 +39,8 @@ struct nouveau_i2c_func {
int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe); int (*drv_ctl)(struct nouveau_i2c_port *, int lane, int sw, int pe);
}; };
#define nouveau_i2c_port_create(p,e,o,i,a,d) \ #define nouveau_i2c_port_create(p,e,o,i,a,f,d) \
nouveau_i2c_port_create_((p), (e), (o), (i), (a), \ nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \
sizeof(**d), (void **)d) sizeof(**d), (void **)d)
#define nouveau_i2c_port_destroy(p) ({ \ #define nouveau_i2c_port_destroy(p) ({ \
struct nouveau_i2c_port *port = (p); \ struct nouveau_i2c_port *port = (p); \
...@@ -53,7 +53,9 @@ struct nouveau_i2c_func { ...@@ -53,7 +53,9 @@ struct nouveau_i2c_func {
int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, u8, 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 *); void _nouveau_i2c_port_dtor(struct nouveau_object *);
#define _nouveau_i2c_port_init nouveau_object_init #define _nouveau_i2c_port_init nouveau_object_init
#define _nouveau_i2c_port_fini nouveau_object_fini #define _nouveau_i2c_port_fini nouveau_object_fini
......
...@@ -118,7 +118,8 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, ...@@ -118,7 +118,8 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(chan);
if (ret) if (ret)
return ret; return ret;
...@@ -140,8 +141,6 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, ...@@ -140,8 +141,6 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent,
struct i2c_algo_bit_data *algo = mast->adapter.algo_data; struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
algo->udelay = max(algo->udelay, 40); algo->udelay = max(algo->udelay, 40);
} }
chan->base.func = &anx9805_aux_func;
return 0; return 0;
} }
...@@ -234,7 +233,8 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, ...@@ -234,7 +233,8 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, ret = nouveau_i2c_port_create(parent, engine, oclass, index,
&anx9805_i2c_algo, &port); &anx9805_i2c_algo, &anx9805_i2c_func,
&port);
*pobject = nv_object(port); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
...@@ -256,8 +256,6 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, ...@@ -256,8 +256,6 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent,
struct i2c_algo_bit_data *algo = mast->adapter.algo_data; struct i2c_algo_bit_data *algo = mast->adapter.algo_data;
algo->udelay = max(algo->udelay, 40); algo->udelay = max(algo->udelay, 40);
} }
port->base.func = &anx9805_i2c_func;
return 0; return 0;
} }
......
...@@ -95,6 +95,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, ...@@ -95,6 +95,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
struct nouveau_object *engine, struct nouveau_object *engine,
struct nouveau_oclass *oclass, u8 index, struct nouveau_oclass *oclass, u8 index,
const struct i2c_algorithm *algo, const struct i2c_algorithm *algo,
const struct nouveau_i2c_func *func,
int size, void **pobject) int size, void **pobject)
{ {
struct nouveau_device *device = nv_device(parent); struct nouveau_device *device = nv_device(parent);
...@@ -112,6 +113,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, ...@@ -112,6 +113,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
port->adapter.owner = THIS_MODULE; port->adapter.owner = THIS_MODULE;
port->adapter.dev.parent = &device->pdev->dev; port->adapter.dev.parent = &device->pdev->dev;
port->index = index; port->index = index;
port->func = func;
i2c_set_adapdata(&port->adapter, i2c); i2c_set_adapdata(&port->adapter, i2c);
if ( algo == &nouveau_i2c_bit_algo && if ( algo == &nouveau_i2c_bit_algo &&
......
...@@ -91,12 +91,12 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -91,12 +91,12 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
port->base.func = &nv04_i2c_func;
port->drive = info->drive; port->drive = info->drive;
port->sense = info->sense; port->sense = info->sense;
return 0; return 0;
......
...@@ -84,12 +84,12 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -84,12 +84,12 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
port->base.func = &nv4e_i2c_func;
port->addr = 0x600800 + info->drive; port->addr = 0x600800 + info->drive;
return 0; return 0;
} }
......
...@@ -85,7 +85,8 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -85,7 +85,8 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
...@@ -93,7 +94,6 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -93,7 +94,6 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (info->drive >= nv50_i2c_addr_nr) if (info->drive >= nv50_i2c_addr_nr)
return -EINVAL; return -EINVAL;
port->base.func = &nv50_i2c_func;
port->state = 0x00000007; port->state = 0x00000007;
port->addr = nv50_i2c_addr[info->drive]; port->addr = nv50_i2c_addr[info->drive];
return 0; return 0;
......
...@@ -186,7 +186,8 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -186,7 +186,8 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
...@@ -194,7 +195,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -194,7 +195,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (info->drive >= nv50_i2c_addr_nr) if (info->drive >= nv50_i2c_addr_nr)
return -EINVAL; return -EINVAL;
port->base.func = &nv94_i2c_func;
port->state = 7; port->state = 7;
port->addr = nv50_i2c_addr[info->drive]; port->addr = nv50_i2c_addr[info->drive];
if (info->share != DCB_I2C_UNUSED) { if (info->share != DCB_I2C_UNUSED) {
...@@ -221,12 +221,12 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -221,12 +221,12 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
port->base.func = &nv94_aux_func;
port->addr = info->drive; port->addr = info->drive;
if (info->share != DCB_I2C_UNUSED) { if (info->share != DCB_I2C_UNUSED) {
port->ctrl = 0x00e500 + (info->drive * 0x50); port->ctrl = 0x00e500 + (info->drive * 0x50);
......
...@@ -60,12 +60,12 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -60,12 +60,12 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
int ret; int ret;
ret = nouveau_i2c_port_create(parent, engine, oclass, index, 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); *pobject = nv_object(port);
if (ret) if (ret)
return ret; return ret;
port->base.func = &nvd0_i2c_func;
port->state = 0x00000007; port->state = 0x00000007;
port->addr = 0x00d014 + (info->drive * 0x20); port->addr = 0x00d014 + (info->drive * 0x20);
if (info->share != DCB_I2C_UNUSED) { if (info->share != DCB_I2C_UNUSED) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册