aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h1
6 files changed, 65 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
index eef54e9b5d77..7957eafa5f0e 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h
@@ -38,6 +38,7 @@ struct nvkm_i2c_bus {
38 struct mutex mutex; 38 struct mutex mutex;
39 struct list_head head; 39 struct list_head head;
40 struct i2c_adapter i2c; 40 struct i2c_adapter i2c;
41 u8 enabled;
41}; 42};
42 43
43int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *); 44int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *);
@@ -57,6 +58,7 @@ struct nvkm_i2c_aux {
57 struct mutex mutex; 58 struct mutex mutex;
58 struct list_head head; 59 struct list_head head;
59 struct i2c_adapter i2c; 60 struct i2c_adapter i2c;
61 u8 enabled;
60 62
61 u32 intr; 63 u32 intr;
62}; 64};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
index 4c1f547da463..b4e7404fe660 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
@@ -105,9 +105,15 @@ nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *aux)
105{ 105{
106 struct nvkm_i2c_pad *pad = aux->pad; 106 struct nvkm_i2c_pad *pad = aux->pad;
107 int ret; 107 int ret;
108
108 AUX_TRACE(aux, "acquire"); 109 AUX_TRACE(aux, "acquire");
109 mutex_lock(&aux->mutex); 110 mutex_lock(&aux->mutex);
110 ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); 111
112 if (aux->enabled)
113 ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX);
114 else
115 ret = -EIO;
116
111 if (ret) 117 if (ret)
112 mutex_unlock(&aux->mutex); 118 mutex_unlock(&aux->mutex);
113 return ret; 119 return ret;
@@ -145,6 +151,24 @@ nvkm_i2c_aux_del(struct nvkm_i2c_aux **paux)
145 } 151 }
146} 152}
147 153
154void
155nvkm_i2c_aux_init(struct nvkm_i2c_aux *aux)
156{
157 AUX_TRACE(aux, "init");
158 mutex_lock(&aux->mutex);
159 aux->enabled = true;
160 mutex_unlock(&aux->mutex);
161}
162
163void
164nvkm_i2c_aux_fini(struct nvkm_i2c_aux *aux)
165{
166 AUX_TRACE(aux, "fini");
167 mutex_lock(&aux->mutex);
168 aux->enabled = false;
169 mutex_unlock(&aux->mutex);
170}
171
148int 172int
149nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func, 173nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func,
150 struct nvkm_i2c_pad *pad, int id, 174 struct nvkm_i2c_pad *pad, int id,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
index 7d56c4ba693c..08f6b2ee64ab 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h
@@ -16,6 +16,8 @@ int nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
16int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, 16int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *,
17 int id, struct nvkm_i2c_aux **); 17 int id, struct nvkm_i2c_aux **);
18void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); 18void nvkm_i2c_aux_del(struct nvkm_i2c_aux **);
19void nvkm_i2c_aux_init(struct nvkm_i2c_aux *);
20void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *);
19int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, 21int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type,
20 u32 addr, u8 *data, u8 *size); 22 u32 addr, u8 *data, u8 *size);
21 23
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
index 4f197b15acf6..ecacb22834d7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
@@ -160,8 +160,18 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev, bool suspend)
160{ 160{
161 struct nvkm_i2c *i2c = nvkm_i2c(subdev); 161 struct nvkm_i2c *i2c = nvkm_i2c(subdev);
162 struct nvkm_i2c_pad *pad; 162 struct nvkm_i2c_pad *pad;
163 struct nvkm_i2c_bus *bus;
164 struct nvkm_i2c_aux *aux;
163 u32 mask; 165 u32 mask;
164 166
167 list_for_each_entry(aux, &i2c->aux, head) {
168 nvkm_i2c_aux_fini(aux);
169 }
170
171 list_for_each_entry(bus, &i2c->bus, head) {
172 nvkm_i2c_bus_fini(bus);
173 }
174
165 if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) { 175 if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) {
166 i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0); 176 i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0);
167 i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask); 177 i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask);
@@ -180,6 +190,7 @@ nvkm_i2c_init(struct nvkm_subdev *subdev)
180 struct nvkm_i2c *i2c = nvkm_i2c(subdev); 190 struct nvkm_i2c *i2c = nvkm_i2c(subdev);
181 struct nvkm_i2c_bus *bus; 191 struct nvkm_i2c_bus *bus;
182 struct nvkm_i2c_pad *pad; 192 struct nvkm_i2c_pad *pad;
193 struct nvkm_i2c_aux *aux;
183 194
184 list_for_each_entry(pad, &i2c->pad, head) { 195 list_for_each_entry(pad, &i2c->pad, head) {
185 nvkm_i2c_pad_init(pad); 196 nvkm_i2c_pad_init(pad);
@@ -189,6 +200,10 @@ nvkm_i2c_init(struct nvkm_subdev *subdev)
189 nvkm_i2c_bus_init(bus); 200 nvkm_i2c_bus_init(bus);
190 } 201 }
191 202
203 list_for_each_entry(aux, &i2c->aux, head) {
204 nvkm_i2c_aux_init(aux);
205 }
206
192 return 0; 207 return 0;
193} 208}
194 209
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
index 807a2b67bd64..ed50cc3736b9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c
@@ -110,6 +110,19 @@ nvkm_i2c_bus_init(struct nvkm_i2c_bus *bus)
110 BUS_TRACE(bus, "init"); 110 BUS_TRACE(bus, "init");
111 if (bus->func->init) 111 if (bus->func->init)
112 bus->func->init(bus); 112 bus->func->init(bus);
113
114 mutex_lock(&bus->mutex);
115 bus->enabled = true;
116 mutex_unlock(&bus->mutex);
117}
118
119void
120nvkm_i2c_bus_fini(struct nvkm_i2c_bus *bus)
121{
122 BUS_TRACE(bus, "fini");
123 mutex_lock(&bus->mutex);
124 bus->enabled = false;
125 mutex_unlock(&bus->mutex);
113} 126}
114 127
115void 128void
@@ -126,9 +139,15 @@ nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *bus)
126{ 139{
127 struct nvkm_i2c_pad *pad = bus->pad; 140 struct nvkm_i2c_pad *pad = bus->pad;
128 int ret; 141 int ret;
142
129 BUS_TRACE(bus, "acquire"); 143 BUS_TRACE(bus, "acquire");
130 mutex_lock(&bus->mutex); 144 mutex_lock(&bus->mutex);
131 ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); 145
146 if (bus->enabled)
147 ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C);
148 else
149 ret = -EIO;
150
132 if (ret) 151 if (ret)
133 mutex_unlock(&bus->mutex); 152 mutex_unlock(&bus->mutex);
134 return ret; 153 return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
index bea0dd33961e..465464bba58b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h
@@ -18,6 +18,7 @@ int nvkm_i2c_bus_new_(const struct nvkm_i2c_bus_func *, struct nvkm_i2c_pad *,
18 int id, struct nvkm_i2c_bus **); 18 int id, struct nvkm_i2c_bus **);
19void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); 19void nvkm_i2c_bus_del(struct nvkm_i2c_bus **);
20void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); 20void nvkm_i2c_bus_init(struct nvkm_i2c_bus *);
21void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *);
21 22
22int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); 23int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int);
23 24