0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "pad.h"
0025
0026 static void
0027 nvkm_i2c_pad_mode_locked(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode)
0028 {
0029 PAD_TRACE(pad, "-> %s", (mode == NVKM_I2C_PAD_AUX) ? "aux" :
0030 (mode == NVKM_I2C_PAD_I2C) ? "i2c" : "off");
0031 if (pad->func->mode)
0032 pad->func->mode(pad, mode);
0033 }
0034
0035 void
0036 nvkm_i2c_pad_mode(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode)
0037 {
0038 PAD_TRACE(pad, "mode %d", mode);
0039 mutex_lock(&pad->mutex);
0040 nvkm_i2c_pad_mode_locked(pad, mode);
0041 pad->mode = mode;
0042 mutex_unlock(&pad->mutex);
0043 }
0044
0045 void
0046 nvkm_i2c_pad_release(struct nvkm_i2c_pad *pad)
0047 {
0048 PAD_TRACE(pad, "release");
0049 if (pad->mode == NVKM_I2C_PAD_OFF)
0050 nvkm_i2c_pad_mode_locked(pad, pad->mode);
0051 mutex_unlock(&pad->mutex);
0052 }
0053
0054 int
0055 nvkm_i2c_pad_acquire(struct nvkm_i2c_pad *pad, enum nvkm_i2c_pad_mode mode)
0056 {
0057 PAD_TRACE(pad, "acquire");
0058 mutex_lock(&pad->mutex);
0059 if (pad->mode != mode) {
0060 if (pad->mode != NVKM_I2C_PAD_OFF) {
0061 mutex_unlock(&pad->mutex);
0062 return -EBUSY;
0063 }
0064 nvkm_i2c_pad_mode_locked(pad, mode);
0065 }
0066 return 0;
0067 }
0068
0069 void
0070 nvkm_i2c_pad_fini(struct nvkm_i2c_pad *pad)
0071 {
0072 PAD_TRACE(pad, "fini");
0073 nvkm_i2c_pad_mode_locked(pad, NVKM_I2C_PAD_OFF);
0074 }
0075
0076 void
0077 nvkm_i2c_pad_init(struct nvkm_i2c_pad *pad)
0078 {
0079 PAD_TRACE(pad, "init");
0080 nvkm_i2c_pad_mode_locked(pad, pad->mode);
0081 }
0082
0083 void
0084 nvkm_i2c_pad_del(struct nvkm_i2c_pad **ppad)
0085 {
0086 struct nvkm_i2c_pad *pad = *ppad;
0087 if (pad) {
0088 PAD_TRACE(pad, "dtor");
0089 list_del(&pad->head);
0090 kfree(pad);
0091 pad = NULL;
0092 }
0093 }
0094
0095 void
0096 nvkm_i2c_pad_ctor(const struct nvkm_i2c_pad_func *func, struct nvkm_i2c *i2c,
0097 int id, struct nvkm_i2c_pad *pad)
0098 {
0099 pad->func = func;
0100 pad->i2c = i2c;
0101 pad->id = id;
0102 pad->mode = NVKM_I2C_PAD_OFF;
0103 mutex_init(&pad->mutex);
0104 list_add_tail(&pad->head, &i2c->pad);
0105 PAD_TRACE(pad, "ctor");
0106 }
0107
0108 int
0109 nvkm_i2c_pad_new_(const struct nvkm_i2c_pad_func *func, struct nvkm_i2c *i2c,
0110 int id, struct nvkm_i2c_pad **ppad)
0111 {
0112 if (!(*ppad = kzalloc(sizeof(**ppad), GFP_KERNEL)))
0113 return -ENOMEM;
0114 nvkm_i2c_pad_ctor(func, i2c, id, *ppad);
0115 return 0;
0116 }