CC: kbuild-all(a)lists.01.org CC: linux-kernel(a)vger.kernel.org TO: Mauro Carvalho Chehab CC: linux-media(a)vger.kernel.org Hi Mauro, First bad commit (maybe != root cause): tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: 2ac69819ba9e3d8d550bb5d2d2df74848e556812 commit: a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a media: Kconfig: not all V4L2 platform drivers are for camera date: 4 months ago :::::: branch date: 12 hours ago :::::: commit date: 4 months ago config: riscv-randconfig-m031-20200826 (attached as .config) compiler: riscv64-linux-gcc (GCC) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot Reported-by: Dan Carpenter New smatch warnings: drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 188) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 188) drivers/media/platform/marvell-ccic/cafe-driver.c:269 cafe_smbus_read_data() error: double unlocked 'mcam->dev_lock' (orig line 267) drivers/media/platform/marvell-ccic/cafe-driver.c:404 cafe_ctlr_init() error: double unlocked 'mcam->dev_lock' (orig line 394) Old smatch warnings: drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:208 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:213 cafe_smbus_write_data() error: double unlocked 'mcam->dev_lock' (orig line 208) drivers/media/platform/marvell-ccic/cafe-driver.c:269 cafe_smbus_read_data() error: double unlocked 'mcam->dev_lock' (orig line 269) drivers/media/platform/marvell-ccic/cafe-driver.c:269 cafe_smbus_read_data() error: double unlocked 'mcam->dev_lock' (orig line 269) drivers/media/platform/marvell-ccic/cafe-driver.c:269 cafe_smbus_read_data() error: double unlocked 'mcam->dev_lock' (orig line 269) drivers/media/platform/marvell-ccic/cafe-driver.c:273 cafe_smbus_read_data() error: double unlocked 'mcam->dev_lock' (orig line 269) # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git git fetch --no-tags linus master git checkout a19f228b8dd9a67e8de4ebd4eac8a4c94ec39d1a vim +208 drivers/media/platform/marvell-ccic/cafe-driver.c abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 169 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 170 static int cafe_smbus_write_data(struct cafe_camera *cam, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 171 u16 addr, u8 command, u8 value) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 172 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 173 unsigned int rval; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 174 unsigned long flags; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 175 struct mcam_camera *mcam = &cam->mcam; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 176 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 177 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 178 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 179 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 180 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 181 * Marvell sez set clkdiv to all 1's for now. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 182 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 183 rval |= TWSIC0_CLKDIV; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 184 mcam_reg_write(mcam, REG_TWSIC0, rval); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 185 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 186 rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 187 mcam_reg_write(mcam, REG_TWSIC1, rval); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @188 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 189 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 190 /* Unfortunately, reading TWSIC1 too soon after sending a command abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 191 * causes the device to die. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 192 * Use a busy-wait because we often send a large quantity of small abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 193 * commands at-once; using msleep() would cause a lot of context abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 194 * switches which take longer than 2ms, resulting in a noticeable abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 195 * boot-time and capture-start delays. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 196 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 197 mdelay(2); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 198 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 199 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 200 * Another sad fact is that sometimes, commands silently complete but abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 201 * cafe_smbus_write_done() never becomes aware of this. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 202 * This happens at random and appears to possible occur with any abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 203 * command. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 204 * We don't understand why this is. We work around this issue abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 205 * with the timeout in the wait below, assuming that all commands abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 206 * complete within the timeout. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 207 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @208 wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(mcam), abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 209 CAFE_SMBUS_TIMEOUT); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 210 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 211 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 212 rval = mcam_reg_read(mcam, REG_TWSIC1); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 213 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 214 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 215 if (rval & TWSIC1_WSTAT) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 216 cam_err(cam, "SMBUS write (%02x/%02x/%02x) timed out\n", addr, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 217 command, value); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 218 return -EIO; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 219 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 220 if (rval & TWSIC1_ERROR) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 221 cam_err(cam, "SMBUS write (%02x/%02x/%02x) error\n", addr, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 222 command, value); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 223 return -EIO; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 224 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 225 return 0; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 226 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 227 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 228 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 229 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 230 static int cafe_smbus_read_done(struct mcam_camera *mcam) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 231 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 232 unsigned long flags; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 233 int c1; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 234 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 235 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 236 * We must delay after the interrupt, or the controller gets confused abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 237 * and never does give us good status. Fortunately, we don't do this abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 238 * often. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 239 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 240 udelay(20); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 241 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 242 c1 = mcam_reg_read(mcam, REG_TWSIC1); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 243 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 244 return c1 & (TWSIC1_RVALID|TWSIC1_ERROR); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 245 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 246 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 247 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 248 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 249 static int cafe_smbus_read_data(struct cafe_camera *cam, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 250 u16 addr, u8 command, u8 *value) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 251 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 252 unsigned int rval; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 253 unsigned long flags; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 254 struct mcam_camera *mcam = &cam->mcam; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 255 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 256 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 257 rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 258 rval |= TWSIC0_OVMAGIC; /* Make OV sensors work */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 259 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 260 * Marvel sez set clkdiv to all 1's for now. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 261 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 262 rval |= TWSIC0_CLKDIV; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 263 mcam_reg_write(mcam, REG_TWSIC0, rval); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 264 (void) mcam_reg_read(mcam, REG_TWSIC1); /* force write */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 265 rval = TWSIC1_READ | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 266 mcam_reg_write(mcam, REG_TWSIC1, rval); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @267 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 268 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @269 wait_event_timeout(cam->smbus_wait, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 270 cafe_smbus_read_done(mcam), CAFE_SMBUS_TIMEOUT); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 271 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 272 rval = mcam_reg_read(mcam, REG_TWSIC1); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 273 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 274 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 275 if (rval & TWSIC1_ERROR) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 276 cam_err(cam, "SMBUS read (%02x/%02x) error\n", addr, command); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 277 return -EIO; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 278 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 279 if (!(rval & TWSIC1_RVALID)) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 280 cam_err(cam, "SMBUS read (%02x/%02x) timed out\n", addr, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 281 command); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 282 return -EIO; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 283 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 284 *value = rval & 0xff; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 285 return 0; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 286 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 287 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 288 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 289 * Perform a transfer over SMBUS. This thing is called under abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 290 * the i2c bus lock, so we shouldn't race with ourselves... abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 291 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 292 static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 293 unsigned short flags, char rw, u8 command, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 294 int size, union i2c_smbus_data *data) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 295 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 296 struct cafe_camera *cam = i2c_get_adapdata(adapter); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 297 int ret = -EINVAL; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 298 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 299 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 300 * This interface would appear to only do byte data ops. OK abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 301 * it can do word too, but the cam chip has no use for that. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 302 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 303 if (size != I2C_SMBUS_BYTE_DATA) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 304 cam_err(cam, "funky xfer size %d\n", size); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 305 return -EINVAL; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 306 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 307 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 308 if (rw == I2C_SMBUS_WRITE) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 309 ret = cafe_smbus_write_data(cam, addr, command, data->byte); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 310 else if (rw == I2C_SMBUS_READ) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 311 ret = cafe_smbus_read_data(cam, addr, command, &data->byte); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 312 return ret; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 313 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 314 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 315 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 316 static void cafe_smbus_enable_irq(struct cafe_camera *cam) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 317 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 318 unsigned long flags; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 319 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 320 spin_lock_irqsave(&cam->mcam.dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 321 mcam_reg_set_bit(&cam->mcam, REG_IRQMASK, TWSIIRQS); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 322 spin_unlock_irqrestore(&cam->mcam.dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 323 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 324 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 325 static u32 cafe_smbus_func(struct i2c_adapter *adapter) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 326 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 327 return I2C_FUNC_SMBUS_READ_BYTE_DATA | abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 328 I2C_FUNC_SMBUS_WRITE_BYTE_DATA; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 329 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 330 8e10fd851cb3e9 drivers/media/platform/marvell-ccic/cafe-driver.c Gustavo A. R. Silva 2017-07-09 331 static const struct i2c_algorithm cafe_smbus_algo = { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 332 .smbus_xfer = cafe_smbus_xfer, abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 333 .functionality = cafe_smbus_func abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 334 }; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 335 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 336 static int cafe_smbus_setup(struct cafe_camera *cam) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 337 { 595a93a47a3b7d drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 338 struct i2c_adapter *adap; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 339 int ret; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 340 595a93a47a3b7d drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 341 adap = kzalloc(sizeof(*adap), GFP_KERNEL); 595a93a47a3b7d drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 342 if (adap == NULL) 595a93a47a3b7d drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 343 return -ENOMEM; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 344 adap->owner = THIS_MODULE; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 345 adap->algo = &cafe_smbus_algo; cc1e6315e83db0 drivers/media/platform/marvell-ccic/cafe-driver.c Mauro Carvalho Chehab 2018-09-10 346 strscpy(adap->name, "cafe_ccic", sizeof(adap->name)); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 347 adap->dev.parent = &cam->pdev->dev; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 348 i2c_set_adapdata(adap, cam); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 349 ret = i2c_add_adapter(adap); 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 350 if (ret) { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 351 printk(KERN_ERR "Unable to register cafe i2c adapter\n"); 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 352 kfree(adap); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 353 return ret; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 354 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 355 3eefe36cc00c53 drivers/media/platform/marvell-ccic/cafe-driver.c Lubomir Rintel 2019-05-28 356 cam->i2c_adapter = adap; 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 357 cafe_smbus_enable_irq(cam); 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 358 return 0; 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 359 } 90ca75fd1945d9 drivers/media/platform/marvell-ccic/cafe-driver.c Alexey Khoroshilov 2015-04-03 360 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 361 static void cafe_smbus_shutdown(struct cafe_camera *cam) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 362 { 3eefe36cc00c53 drivers/media/platform/marvell-ccic/cafe-driver.c Lubomir Rintel 2019-05-28 363 i2c_del_adapter(cam->i2c_adapter); 3eefe36cc00c53 drivers/media/platform/marvell-ccic/cafe-driver.c Lubomir Rintel 2019-05-28 364 kfree(cam->i2c_adapter); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 365 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 366 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 367 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 368 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 369 * Controller-level stuff abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 370 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 371 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 372 static void cafe_ctlr_init(struct mcam_camera *mcam) abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 373 { abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 374 unsigned long flags; abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 375 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 376 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 377 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 378 * Added magic to bring up the hardware on the B-Test board abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 379 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 380 mcam_reg_write(mcam, 0x3038, 0x8); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 381 mcam_reg_write(mcam, 0x315c, 0x80008); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 382 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 383 * Go through the dance needed to wake the device up. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 384 * Note that these registers are global and shared abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 385 * with the NAND and SD devices. Interaction between the abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 386 * three still needs to be examined. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 387 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 388 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRS|GCSR_MRS); /* Needed? */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 389 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRC); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 390 mcam_reg_write(mcam, REG_GL_CSR, GCSR_SRC|GCSR_MRS); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 391 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 392 * Here we must wait a bit for the controller to come around. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 393 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @394 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 395 msleep(5); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 396 spin_lock_irqsave(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 397 abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 398 mcam_reg_write(mcam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 399 mcam_reg_set_bit(mcam, REG_GL_IMASK, GIMSK_CCIC_EN); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 400 /* abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 401 * Mask all interrupts. abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 402 */ abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 403 mcam_reg_write(mcam, REG_IRQMASK, 0); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 @404 spin_unlock_irqrestore(&mcam->dev_lock, flags); abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 405 } abfa3df36c01a3 drivers/media/video/marvell-ccic/cafe-driver.c Jonathan Corbet 2011-06-11 406 :::::: The code at line 208 was first introduced by commit :::::: abfa3df36c01a32b081fb448750181af76eb9d55 [media] marvell-cam: Separate out the Marvell camera core :::::: TO: Jonathan Corbet :::::: CC: Mauro Carvalho Chehab --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org