diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c | 26 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h | 1 |
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 | ||
| 43 | int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *); | 44 | int 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 | ||
| 154 | void | ||
| 155 | nvkm_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 | |||
| 163 | void | ||
| 164 | nvkm_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 | |||
| 148 | int | 172 | int |
| 149 | nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func, | 173 | nvkm_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 *, | |||
| 16 | int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, | 16 | int 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 **); |
| 18 | void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); | 18 | void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); |
| 19 | void nvkm_i2c_aux_init(struct nvkm_i2c_aux *); | ||
| 20 | void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *); | ||
| 19 | int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, | 21 | int 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 | |||
| 119 | void | ||
| 120 | nvkm_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 | ||
| 115 | void | 128 | void |
| @@ -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 **); |
| 19 | void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); | 19 | void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); |
| 20 | void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); | 20 | void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); |
| 21 | void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *); | ||
| 21 | 22 | ||
| 22 | int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); | 23 | int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); |
| 23 | 24 | ||
