linux/drivers/staging/media/omap4iss/iss.c
<<
>>
Prefs
   1/*
   2 * TI OMAP4 ISS V4L2 Driver
   3 *
   4 * Copyright (C) 2012, Texas Instruments
   5 *
   6 * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 */
  13
  14#include <linux/clk.h>
  15#include <linux/delay.h>
  16#include <linux/device.h>
  17#include <linux/dma-mapping.h>
  18#include <linux/i2c.h>
  19#include <linux/interrupt.h>
  20#include <linux/module.h>
  21#include <linux/platform_device.h>
  22#include <linux/slab.h>
  23#include <linux/sched.h>
  24#include <linux/vmalloc.h>
  25
  26#include <media/v4l2-common.h>
  27#include <media/v4l2-device.h>
  28#include <media/v4l2-ctrls.h>
  29
  30#include "iss.h"
  31#include "iss_regs.h"
  32
  33#define ISS_PRINT_REGISTER(iss, name)\
  34        dev_dbg(iss->dev, "###ISS " #name "=0x%08x\n", \
  35                iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_##name))
  36
  37static void iss_print_status(struct iss_device *iss)
  38{
  39        dev_dbg(iss->dev, "-------------ISS HL Register dump-------------\n");
  40
  41        ISS_PRINT_REGISTER(iss, HL_REVISION);
  42        ISS_PRINT_REGISTER(iss, HL_SYSCONFIG);
  43        ISS_PRINT_REGISTER(iss, HL_IRQSTATUS(5));
  44        ISS_PRINT_REGISTER(iss, HL_IRQENABLE_SET(5));
  45        ISS_PRINT_REGISTER(iss, HL_IRQENABLE_CLR(5));
  46        ISS_PRINT_REGISTER(iss, CTRL);
  47        ISS_PRINT_REGISTER(iss, CLKCTRL);
  48        ISS_PRINT_REGISTER(iss, CLKSTAT);
  49
  50        dev_dbg(iss->dev, "-----------------------------------------------\n");
  51}
  52
  53/*
  54 * omap4iss_flush - Post pending L3 bus writes by doing a register readback
  55 * @iss: OMAP4 ISS device
  56 *
  57 * In order to force posting of pending writes, we need to write and
  58 * readback the same register, in this case the revision register.
  59 *
  60 * See this link for reference:
  61 *   http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
  62 */
  63void omap4iss_flush(struct iss_device *iss)
  64{
  65        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION, 0);
  66        iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
  67}
  68
  69/*
  70 * iss_isp_enable_interrupts - Enable ISS ISP interrupts.
  71 * @iss: OMAP4 ISS device
  72 */
  73static void omap4iss_isp_enable_interrupts(struct iss_device *iss)
  74{
  75        static const u32 isp_irq = ISP5_IRQ_OCP_ERR |
  76                                   ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
  77                                   ISP5_IRQ_RSZ_FIFO_OVF |
  78                                   ISP5_IRQ_RSZ_INT_DMA |
  79                                   ISP5_IRQ_ISIF_INT(0);
  80
  81        /* Enable ISP interrupts */
  82        iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0), isp_irq);
  83        iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_SET(0),
  84                      isp_irq);
  85}
  86
  87/*
  88 * iss_isp_disable_interrupts - Disable ISS interrupts.
  89 * @iss: OMAP4 ISS device
  90 */
  91static void omap4iss_isp_disable_interrupts(struct iss_device *iss)
  92{
  93        iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQENABLE_CLR(0), ~0);
  94}
  95
  96/*
  97 * iss_enable_interrupts - Enable ISS interrupts.
  98 * @iss: OMAP4 ISS device
  99 */
 100static void iss_enable_interrupts(struct iss_device *iss)
 101{
 102        static const u32 hl_irq = ISS_HL_IRQ_CSIA | ISS_HL_IRQ_CSIB
 103                                | ISS_HL_IRQ_ISP(0);
 104
 105        /* Enable HL interrupts */
 106        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), hl_irq);
 107        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_SET(5), hl_irq);
 108
 109        if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
 110                omap4iss_isp_enable_interrupts(iss);
 111}
 112
 113/*
 114 * iss_disable_interrupts - Disable ISS interrupts.
 115 * @iss: OMAP4 ISS device
 116 */
 117static void iss_disable_interrupts(struct iss_device *iss)
 118{
 119        if (iss->regs[OMAP4_ISS_MEM_ISP_SYS1])
 120                omap4iss_isp_disable_interrupts(iss);
 121
 122        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQENABLE_CLR(5), ~0);
 123}
 124
 125int omap4iss_get_external_info(struct iss_pipeline *pipe,
 126                               struct media_link *link)
 127{
 128        struct iss_device *iss =
 129                container_of(pipe, struct iss_video, pipe)->iss;
 130        struct v4l2_subdev_format fmt;
 131        struct v4l2_ctrl *ctrl;
 132        int ret;
 133
 134        if (!pipe->external)
 135                return 0;
 136
 137        if (pipe->external_rate)
 138                return 0;
 139
 140        memset(&fmt, 0, sizeof(fmt));
 141
 142        fmt.pad = link->source->index;
 143        fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 144        ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(link->sink->entity),
 145                               pad, get_fmt, NULL, &fmt);
 146        if (ret < 0)
 147                return -EPIPE;
 148
 149        pipe->external_bpp = omap4iss_video_format_info(fmt.format.code)->bpp;
 150
 151        ctrl = v4l2_ctrl_find(pipe->external->ctrl_handler,
 152                              V4L2_CID_PIXEL_RATE);
 153        if (ctrl == NULL) {
 154                dev_warn(iss->dev, "no pixel rate control in subdev %s\n",
 155                         pipe->external->name);
 156                return -EPIPE;
 157        }
 158
 159        pipe->external_rate = v4l2_ctrl_g_ctrl_int64(ctrl);
 160
 161        return 0;
 162}
 163
 164/*
 165 * Configure the bridge. Valid inputs are
 166 *
 167 * IPIPEIF_INPUT_CSI2A: CSI2a receiver
 168 * IPIPEIF_INPUT_CSI2B: CSI2b receiver
 169 *
 170 * The bridge and lane shifter are configured according to the selected input
 171 * and the ISP platform data.
 172 */
 173void omap4iss_configure_bridge(struct iss_device *iss,
 174                               enum ipipeif_input_entity input)
 175{
 176        u32 issctrl_val;
 177        u32 isp5ctrl_val;
 178
 179        issctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL);
 180        issctrl_val &= ~ISS_CTRL_INPUT_SEL_MASK;
 181        issctrl_val &= ~ISS_CTRL_CLK_DIV_MASK;
 182
 183        isp5ctrl_val = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL);
 184
 185        switch (input) {
 186        case IPIPEIF_INPUT_CSI2A:
 187                issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2A;
 188                break;
 189
 190        case IPIPEIF_INPUT_CSI2B:
 191                issctrl_val |= ISS_CTRL_INPUT_SEL_CSI2B;
 192                break;
 193
 194        default:
 195                return;
 196        }
 197
 198        issctrl_val |= ISS_CTRL_SYNC_DETECT_VS_RAISING;
 199
 200        isp5ctrl_val |= ISP5_CTRL_VD_PULSE_EXT | ISP5_CTRL_PSYNC_CLK_SEL |
 201                        ISP5_CTRL_SYNC_ENABLE;
 202
 203        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_CTRL, issctrl_val);
 204        iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, isp5ctrl_val);
 205}
 206
 207#ifdef ISS_ISR_DEBUG
 208static void iss_isr_dbg(struct iss_device *iss, u32 irqstatus)
 209{
 210        static const char * const name[] = {
 211                "ISP_0",
 212                "ISP_1",
 213                "ISP_2",
 214                "ISP_3",
 215                "CSIA",
 216                "CSIB",
 217                "CCP2_0",
 218                "CCP2_1",
 219                "CCP2_2",
 220                "CCP2_3",
 221                "CBUFF",
 222                "BTE",
 223                "SIMCOP_0",
 224                "SIMCOP_1",
 225                "SIMCOP_2",
 226                "SIMCOP_3",
 227                "CCP2_8",
 228                "HS_VS",
 229                "18",
 230                "19",
 231                "20",
 232                "21",
 233                "22",
 234                "23",
 235                "24",
 236                "25",
 237                "26",
 238                "27",
 239                "28",
 240                "29",
 241                "30",
 242                "31",
 243        };
 244        unsigned int i;
 245
 246        dev_dbg(iss->dev, "ISS IRQ: ");
 247
 248        for (i = 0; i < ARRAY_SIZE(name); i++) {
 249                if ((1 << i) & irqstatus)
 250                        pr_cont("%s ", name[i]);
 251        }
 252        pr_cont("\n");
 253}
 254
 255static void iss_isp_isr_dbg(struct iss_device *iss, u32 irqstatus)
 256{
 257        static const char * const name[] = {
 258                "ISIF_0",
 259                "ISIF_1",
 260                "ISIF_2",
 261                "ISIF_3",
 262                "IPIPEREQ",
 263                "IPIPELAST_PIX",
 264                "IPIPEDMA",
 265                "IPIPEBSC",
 266                "IPIPEHST",
 267                "IPIPEIF",
 268                "AEW",
 269                "AF",
 270                "H3A",
 271                "RSZ_REG",
 272                "RSZ_LAST_PIX",
 273                "RSZ_DMA",
 274                "RSZ_CYC_RZA",
 275                "RSZ_CYC_RZB",
 276                "RSZ_FIFO_OVF",
 277                "RSZ_FIFO_IN_BLK_ERR",
 278                "20",
 279                "21",
 280                "RSZ_EOF0",
 281                "RSZ_EOF1",
 282                "H3A_EOF",
 283                "IPIPE_EOF",
 284                "26",
 285                "IPIPE_DPC_INI",
 286                "IPIPE_DPC_RNEW0",
 287                "IPIPE_DPC_RNEW1",
 288                "30",
 289                "OCP_ERR",
 290        };
 291        unsigned int i;
 292
 293        dev_dbg(iss->dev, "ISP IRQ: ");
 294
 295        for (i = 0; i < ARRAY_SIZE(name); i++) {
 296                if ((1 << i) & irqstatus)
 297                        pr_cont("%s ", name[i]);
 298        }
 299        pr_cont("\n");
 300}
 301#endif
 302
 303/*
 304 * iss_isr - Interrupt Service Routine for ISS module.
 305 * @irq: Not used currently.
 306 * @_iss: Pointer to the OMAP4 ISS device
 307 *
 308 * Handles the corresponding callback if plugged in.
 309 *
 310 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
 311 * IRQ wasn't handled.
 312 */
 313static irqreturn_t iss_isr(int irq, void *_iss)
 314{
 315        static const u32 ipipeif_events = ISP5_IRQ_IPIPEIF_IRQ |
 316                                          ISP5_IRQ_ISIF_INT(0);
 317        static const u32 resizer_events = ISP5_IRQ_RSZ_FIFO_IN_BLK_ERR |
 318                                          ISP5_IRQ_RSZ_FIFO_OVF |
 319                                          ISP5_IRQ_RSZ_INT_DMA;
 320        struct iss_device *iss = _iss;
 321        u32 irqstatus;
 322
 323        irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5));
 324        iss_reg_write(iss, OMAP4_ISS_MEM_TOP, ISS_HL_IRQSTATUS(5), irqstatus);
 325
 326        if (irqstatus & ISS_HL_IRQ_CSIA)
 327                omap4iss_csi2_isr(&iss->csi2a);
 328
 329        if (irqstatus & ISS_HL_IRQ_CSIB)
 330                omap4iss_csi2_isr(&iss->csi2b);
 331
 332        if (irqstatus & ISS_HL_IRQ_ISP(0)) {
 333                u32 isp_irqstatus = iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1,
 334                                                 ISP5_IRQSTATUS(0));
 335                iss_reg_write(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_IRQSTATUS(0),
 336                              isp_irqstatus);
 337
 338                if (isp_irqstatus & ISP5_IRQ_OCP_ERR)
 339                        dev_dbg(iss->dev, "ISP5 OCP Error!\n");
 340
 341                if (isp_irqstatus & ipipeif_events) {
 342                        omap4iss_ipipeif_isr(&iss->ipipeif,
 343                                             isp_irqstatus & ipipeif_events);
 344                }
 345
 346                if (isp_irqstatus & resizer_events)
 347                        omap4iss_resizer_isr(&iss->resizer,
 348                                             isp_irqstatus & resizer_events);
 349
 350#ifdef ISS_ISR_DEBUG
 351                iss_isp_isr_dbg(iss, isp_irqstatus);
 352#endif
 353        }
 354
 355        omap4iss_flush(iss);
 356
 357#ifdef ISS_ISR_DEBUG
 358        iss_isr_dbg(iss, irqstatus);
 359#endif
 360
 361        return IRQ_HANDLED;
 362}
 363
 364/* -----------------------------------------------------------------------------
 365 * Pipeline power management
 366 *
 367 * Entities must be powered up when part of a pipeline that contains at least
 368 * one open video device node.
 369 *
 370 * To achieve this use the entity use_count field to track the number of users.
 371 * For entities corresponding to video device nodes the use_count field stores
 372 * the users count of the node. For entities corresponding to subdevs the
 373 * use_count field stores the total number of users of all video device nodes
 374 * in the pipeline.
 375 *
 376 * The omap4iss_pipeline_pm_use() function must be called in the open() and
 377 * close() handlers of video device nodes. It increments or decrements the use
 378 * count of all subdev entities in the pipeline.
 379 *
 380 * To react to link management on powered pipelines, the link setup notification
 381 * callback updates the use count of all entities in the source and sink sides
 382 * of the link.
 383 */
 384
 385/*
 386 * iss_pipeline_pm_use_count - Count the number of users of a pipeline
 387 * @entity: The entity
 388 *
 389 * Return the total number of users of all video device nodes in the pipeline.
 390 */
 391static int iss_pipeline_pm_use_count(struct media_entity *entity)
 392{
 393        struct media_entity_graph graph;
 394        int use = 0;
 395
 396        media_entity_graph_walk_start(&graph, entity);
 397
 398        while ((entity = media_entity_graph_walk_next(&graph))) {
 399                if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
 400                        use += entity->use_count;
 401        }
 402
 403        return use;
 404}
 405
 406/*
 407 * iss_pipeline_pm_power_one - Apply power change to an entity
 408 * @entity: The entity
 409 * @change: Use count change
 410 *
 411 * Change the entity use count by @change. If the entity is a subdev update its
 412 * power state by calling the core::s_power operation when the use count goes
 413 * from 0 to != 0 or from != 0 to 0.
 414 *
 415 * Return 0 on success or a negative error code on failure.
 416 */
 417static int iss_pipeline_pm_power_one(struct media_entity *entity, int change)
 418{
 419        struct v4l2_subdev *subdev;
 420
 421        subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
 422               ? media_entity_to_v4l2_subdev(entity) : NULL;
 423
 424        if (entity->use_count == 0 && change > 0 && subdev != NULL) {
 425                int ret;
 426
 427                ret = v4l2_subdev_call(subdev, core, s_power, 1);
 428                if (ret < 0 && ret != -ENOIOCTLCMD)
 429                        return ret;
 430        }
 431
 432        entity->use_count += change;
 433        WARN_ON(entity->use_count < 0);
 434
 435        if (entity->use_count == 0 && change < 0 && subdev != NULL)
 436                v4l2_subdev_call(subdev, core, s_power, 0);
 437
 438        return 0;
 439}
 440
 441/*
 442 * iss_pipeline_pm_power - Apply power change to all entities in a pipeline
 443 * @entity: The entity
 444 * @change: Use count change
 445 *
 446 * Walk the pipeline to update the use count and the power state of all non-node
 447 * entities.
 448 *
 449 * Return 0 on success or a negative error code on failure.
 450 */
 451static int iss_pipeline_pm_power(struct media_entity *entity, int change)
 452{
 453        struct media_entity_graph graph;
 454        struct media_entity *first = entity;
 455        int ret = 0;
 456
 457        if (!change)
 458                return 0;
 459
 460        media_entity_graph_walk_start(&graph, entity);
 461
 462        while (!ret && (entity = media_entity_graph_walk_next(&graph)))
 463                if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
 464                        ret = iss_pipeline_pm_power_one(entity, change);
 465
 466        if (!ret)
 467                return 0;
 468
 469        media_entity_graph_walk_start(&graph, first);
 470
 471        while ((first = media_entity_graph_walk_next(&graph))
 472               && first != entity)
 473                if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
 474                        iss_pipeline_pm_power_one(first, -change);
 475
 476        return ret;
 477}
 478
 479/*
 480 * omap4iss_pipeline_pm_use - Update the use count of an entity
 481 * @entity: The entity
 482 * @use: Use (1) or stop using (0) the entity
 483 *
 484 * Update the use count of all entities in the pipeline and power entities on or
 485 * off accordingly.
 486 *
 487 * Return 0 on success or a negative error code on failure. Powering entities
 488 * off is assumed to never fail. No failure can occur when the use parameter is
 489 * set to 0.
 490 */
 491int omap4iss_pipeline_pm_use(struct media_entity *entity, int use)
 492{
 493        int change = use ? 1 : -1;
 494        int ret;
 495
 496        mutex_lock(&entity->parent->graph_mutex);
 497
 498        /* Apply use count to node. */
 499        entity->use_count += change;
 500        WARN_ON(entity->use_count < 0);
 501
 502        /* Apply power change to connected non-nodes. */
 503        ret = iss_pipeline_pm_power(entity, change);
 504        if (ret < 0)
 505                entity->use_count -= change;
 506
 507        mutex_unlock(&entity->parent->graph_mutex);
 508
 509        return ret;
 510}
 511
 512/*
 513 * iss_pipeline_link_notify - Link management notification callback
 514 * @link: The link
 515 * @flags: New link flags that will be applied
 516 *
 517 * React to link management on powered pipelines by updating the use count of
 518 * all entities in the source and sink sides of the link. Entities are powered
 519 * on or off accordingly.
 520 *
 521 * Return 0 on success or a negative error code on failure. Powering entities
 522 * off is assumed to never fail. This function will not fail for disconnection
 523 * events.
 524 */
 525static int iss_pipeline_link_notify(struct media_link *link, u32 flags,
 526                                    unsigned int notification)
 527{
 528        struct media_entity *source = link->source->entity;
 529        struct media_entity *sink = link->sink->entity;
 530        int source_use = iss_pipeline_pm_use_count(source);
 531        int sink_use = iss_pipeline_pm_use_count(sink);
 532        int ret;
 533
 534        if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
 535            !(link->flags & MEDIA_LNK_FL_ENABLED)) {
 536                /* Powering off entities is assumed to never fail. */
 537                iss_pipeline_pm_power(source, -sink_use);
 538                iss_pipeline_pm_power(sink, -source_use);
 539                return 0;
 540        }
 541
 542        if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
 543                (flags & MEDIA_LNK_FL_ENABLED)) {
 544                ret = iss_pipeline_pm_power(source, sink_use);
 545                if (ret < 0)
 546                        return ret;
 547
 548                ret = iss_pipeline_pm_power(sink, source_use);
 549                if (ret < 0)
 550                        iss_pipeline_pm_power(source, -sink_use);
 551
 552                return ret;
 553        }
 554
 555        return 0;
 556}
 557
 558/* -----------------------------------------------------------------------------
 559 * Pipeline stream management
 560 */
 561
 562/*
 563 * iss_pipeline_enable - Enable streaming on a pipeline
 564 * @pipe: ISS pipeline
 565 * @mode: Stream mode (single shot or continuous)
 566 *
 567 * Walk the entities chain starting at the pipeline output video node and start
 568 * all modules in the chain in the given mode.
 569 *
 570 * Return 0 if successful, or the return value of the failed video::s_stream
 571 * operation otherwise.
 572 */
 573static int iss_pipeline_enable(struct iss_pipeline *pipe,
 574                               enum iss_pipeline_stream_state mode)
 575{
 576        struct iss_device *iss = pipe->output->iss;
 577        struct media_entity *entity;
 578        struct media_pad *pad;
 579        struct v4l2_subdev *subdev;
 580        unsigned long flags;
 581        int ret;
 582
 583        /* If one of the entities in the pipeline has crashed it will not work
 584         * properly. Refuse to start streaming in that case. This check must be
 585         * performed before the loop below to avoid starting entities if the
 586         * pipeline won't start anyway (those entities would then likely fail to
 587         * stop, making the problem worse).
 588         */
 589        if (pipe->entities & iss->crashed)
 590                return -EIO;
 591
 592        spin_lock_irqsave(&pipe->lock, flags);
 593        pipe->state &= ~(ISS_PIPELINE_IDLE_INPUT | ISS_PIPELINE_IDLE_OUTPUT);
 594        spin_unlock_irqrestore(&pipe->lock, flags);
 595
 596        pipe->do_propagation = false;
 597
 598        entity = &pipe->output->video.entity;
 599        while (1) {
 600                pad = &entity->pads[0];
 601                if (!(pad->flags & MEDIA_PAD_FL_SINK))
 602                        break;
 603
 604                pad = media_entity_remote_pad(pad);
 605                if (pad == NULL ||
 606                    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 607                        break;
 608
 609                entity = pad->entity;
 610                subdev = media_entity_to_v4l2_subdev(entity);
 611
 612                ret = v4l2_subdev_call(subdev, video, s_stream, mode);
 613                if (ret < 0 && ret != -ENOIOCTLCMD)
 614                        return ret;
 615        }
 616        iss_print_status(pipe->output->iss);
 617        return 0;
 618}
 619
 620/*
 621 * iss_pipeline_disable - Disable streaming on a pipeline
 622 * @pipe: ISS pipeline
 623 *
 624 * Walk the entities chain starting at the pipeline output video node and stop
 625 * all modules in the chain. Wait synchronously for the modules to be stopped if
 626 * necessary.
 627 */
 628static int iss_pipeline_disable(struct iss_pipeline *pipe)
 629{
 630        struct iss_device *iss = pipe->output->iss;
 631        struct media_entity *entity;
 632        struct media_pad *pad;
 633        struct v4l2_subdev *subdev;
 634        int failure = 0;
 635        int ret;
 636
 637        entity = &pipe->output->video.entity;
 638        while (1) {
 639                pad = &entity->pads[0];
 640                if (!(pad->flags & MEDIA_PAD_FL_SINK))
 641                        break;
 642
 643                pad = media_entity_remote_pad(pad);
 644                if (pad == NULL ||
 645                    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
 646                        break;
 647
 648                entity = pad->entity;
 649                subdev = media_entity_to_v4l2_subdev(entity);
 650
 651                ret = v4l2_subdev_call(subdev, video, s_stream, 0);
 652                if (ret < 0) {
 653                        dev_dbg(iss->dev, "%s: module stop timeout.\n",
 654                                subdev->name);
 655                        /* If the entity failed to stopped, assume it has
 656                         * crashed. Mark it as such, the ISS will be reset when
 657                         * applications will release it.
 658                         */
 659                        iss->crashed |= 1U << subdev->entity.id;
 660                        failure = -ETIMEDOUT;
 661                }
 662        }
 663
 664        return failure;
 665}
 666
 667/*
 668 * omap4iss_pipeline_set_stream - Enable/disable streaming on a pipeline
 669 * @pipe: ISS pipeline
 670 * @state: Stream state (stopped, single shot or continuous)
 671 *
 672 * Set the pipeline to the given stream state. Pipelines can be started in
 673 * single-shot or continuous mode.
 674 *
 675 * Return 0 if successful, or the return value of the failed video::s_stream
 676 * operation otherwise. The pipeline state is not updated when the operation
 677 * fails, except when stopping the pipeline.
 678 */
 679int omap4iss_pipeline_set_stream(struct iss_pipeline *pipe,
 680                                 enum iss_pipeline_stream_state state)
 681{
 682        int ret;
 683
 684        if (state == ISS_PIPELINE_STREAM_STOPPED)
 685                ret = iss_pipeline_disable(pipe);
 686        else
 687                ret = iss_pipeline_enable(pipe, state);
 688
 689        if (ret == 0 || state == ISS_PIPELINE_STREAM_STOPPED)
 690                pipe->stream_state = state;
 691
 692        return ret;
 693}
 694
 695/*
 696 * omap4iss_pipeline_cancel_stream - Cancel stream on a pipeline
 697 * @pipe: ISS pipeline
 698 *
 699 * Cancelling a stream mark all buffers on all video nodes in the pipeline as
 700 * erroneous and makes sure no new buffer can be queued. This function is called
 701 * when a fatal error that prevents any further operation on the pipeline
 702 * occurs.
 703 */
 704void omap4iss_pipeline_cancel_stream(struct iss_pipeline *pipe)
 705{
 706        if (pipe->input)
 707                omap4iss_video_cancel_stream(pipe->input);
 708        if (pipe->output)
 709                omap4iss_video_cancel_stream(pipe->output);
 710}
 711
 712/*
 713 * iss_pipeline_is_last - Verify if entity has an enabled link to the output
 714 *                        video node
 715 * @me: ISS module's media entity
 716 *
 717 * Returns 1 if the entity has an enabled link to the output video node or 0
 718 * otherwise. It's true only while pipeline can have no more than one output
 719 * node.
 720 */
 721static int iss_pipeline_is_last(struct media_entity *me)
 722{
 723        struct iss_pipeline *pipe;
 724        struct media_pad *pad;
 725
 726        if (!me->pipe)
 727                return 0;
 728        pipe = to_iss_pipeline(me);
 729        if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED)
 730                return 0;
 731        pad = media_entity_remote_pad(&pipe->output->pad);
 732        return pad->entity == me;
 733}
 734
 735static int iss_reset(struct iss_device *iss)
 736{
 737        unsigned int timeout;
 738
 739        iss_reg_set(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG,
 740                    ISS_HL_SYSCONFIG_SOFTRESET);
 741
 742        timeout = iss_poll_condition_timeout(
 743                !(iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_SYSCONFIG) &
 744                ISS_HL_SYSCONFIG_SOFTRESET), 1000, 10, 100);
 745        if (timeout) {
 746                dev_err(iss->dev, "ISS reset timeout\n");
 747                return -ETIMEDOUT;
 748        }
 749
 750        iss->crashed = 0;
 751        return 0;
 752}
 753
 754static int iss_isp_reset(struct iss_device *iss)
 755{
 756        unsigned int timeout;
 757
 758        /* Fist, ensure that the ISP is IDLE (no transactions happening) */
 759        iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
 760                       ISP5_SYSCONFIG_STANDBYMODE_MASK,
 761                       ISP5_SYSCONFIG_STANDBYMODE_SMART);
 762
 763        iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL, ISP5_CTRL_MSTANDBY);
 764
 765        timeout = iss_poll_condition_timeout(
 766                iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL) &
 767                ISP5_CTRL_MSTANDBY_WAIT, 1000000, 1000, 1500);
 768        if (timeout) {
 769                dev_err(iss->dev, "ISP5 standby timeout\n");
 770                return -ETIMEDOUT;
 771        }
 772
 773        /* Now finally, do the reset */
 774        iss_reg_set(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG,
 775                    ISP5_SYSCONFIG_SOFTRESET);
 776
 777        timeout = iss_poll_condition_timeout(
 778                !(iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_SYSCONFIG) &
 779                ISP5_SYSCONFIG_SOFTRESET), 1000000, 1000, 1500);
 780        if (timeout) {
 781                dev_err(iss->dev, "ISP5 reset timeout\n");
 782                return -ETIMEDOUT;
 783        }
 784
 785        return 0;
 786}
 787
 788/*
 789 * iss_module_sync_idle - Helper to sync module with its idle state
 790 * @me: ISS submodule's media entity
 791 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
 792 * @stopping: flag which tells module wants to stop
 793 *
 794 * This function checks if ISS submodule needs to wait for next interrupt. If
 795 * yes, makes the caller to sleep while waiting for such event.
 796 */
 797int omap4iss_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
 798                              atomic_t *stopping)
 799{
 800        struct iss_pipeline *pipe = to_iss_pipeline(me);
 801        struct iss_video *video = pipe->output;
 802        unsigned long flags;
 803
 804        if (pipe->stream_state == ISS_PIPELINE_STREAM_STOPPED ||
 805            (pipe->stream_state == ISS_PIPELINE_STREAM_SINGLESHOT &&
 806             !iss_pipeline_ready(pipe)))
 807                return 0;
 808
 809        /*
 810         * atomic_set() doesn't include memory barrier on ARM platform for SMP
 811         * scenario. We'll call it here to avoid race conditions.
 812         */
 813        atomic_set(stopping, 1);
 814        smp_wmb();
 815
 816        /*
 817         * If module is the last one, it's writing to memory. In this case,
 818         * it's necessary to check if the module is already paused due to
 819         * DMA queue underrun or if it has to wait for next interrupt to be
 820         * idle.
 821         * If it isn't the last one, the function won't sleep but *stopping
 822         * will still be set to warn next submodule caller's interrupt the
 823         * module wants to be idle.
 824         */
 825        if (!iss_pipeline_is_last(me))
 826                return 0;
 827
 828        spin_lock_irqsave(&video->qlock, flags);
 829        if (video->dmaqueue_flags & ISS_VIDEO_DMAQUEUE_UNDERRUN) {
 830                spin_unlock_irqrestore(&video->qlock, flags);
 831                atomic_set(stopping, 0);
 832                smp_wmb();
 833                return 0;
 834        }
 835        spin_unlock_irqrestore(&video->qlock, flags);
 836        if (!wait_event_timeout(*wait, !atomic_read(stopping),
 837                                msecs_to_jiffies(1000))) {
 838                atomic_set(stopping, 0);
 839                smp_wmb();
 840                return -ETIMEDOUT;
 841        }
 842
 843        return 0;
 844}
 845
 846/*
 847 * omap4iss_module_sync_is_stopped - Helper to verify if module was stopping
 848 * @wait: ISS submodule's wait queue for streamoff/interrupt synchronization
 849 * @stopping: flag which tells module wants to stop
 850 *
 851 * This function checks if ISS submodule was stopping. In case of yes, it
 852 * notices the caller by setting stopping to 0 and waking up the wait queue.
 853 * Returns 1 if it was stopping or 0 otherwise.
 854 */
 855int omap4iss_module_sync_is_stopping(wait_queue_head_t *wait,
 856                                     atomic_t *stopping)
 857{
 858        if (atomic_cmpxchg(stopping, 1, 0)) {
 859                wake_up(wait);
 860                return 1;
 861        }
 862
 863        return 0;
 864}
 865
 866/* --------------------------------------------------------------------------
 867 * Clock management
 868 */
 869
 870#define ISS_CLKCTRL_MASK        (ISS_CLKCTRL_CSI2_A |\
 871                                 ISS_CLKCTRL_CSI2_B |\
 872                                 ISS_CLKCTRL_ISP)
 873
 874static int __iss_subclk_update(struct iss_device *iss)
 875{
 876        u32 clk = 0;
 877        int ret = 0, timeout = 1000;
 878
 879        if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_A)
 880                clk |= ISS_CLKCTRL_CSI2_A;
 881
 882        if (iss->subclk_resources & OMAP4_ISS_SUBCLK_CSI2_B)
 883                clk |= ISS_CLKCTRL_CSI2_B;
 884
 885        if (iss->subclk_resources & OMAP4_ISS_SUBCLK_ISP)
 886                clk |= ISS_CLKCTRL_ISP;
 887
 888        iss_reg_update(iss, OMAP4_ISS_MEM_TOP, ISS_CLKCTRL,
 889                       ISS_CLKCTRL_MASK, clk);
 890
 891        /* Wait for HW assertion */
 892        while (--timeout > 0) {
 893                udelay(1);
 894                if ((iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_CLKSTAT) &
 895                    ISS_CLKCTRL_MASK) == clk)
 896                        break;
 897        }
 898
 899        if (!timeout)
 900                ret = -EBUSY;
 901
 902        return ret;
 903}
 904
 905int omap4iss_subclk_enable(struct iss_device *iss,
 906                            enum iss_subclk_resource res)
 907{
 908        iss->subclk_resources |= res;
 909
 910        return __iss_subclk_update(iss);
 911}
 912
 913int omap4iss_subclk_disable(struct iss_device *iss,
 914                             enum iss_subclk_resource res)
 915{
 916        iss->subclk_resources &= ~res;
 917
 918        return __iss_subclk_update(iss);
 919}
 920
 921#define ISS_ISP5_CLKCTRL_MASK   (ISP5_CTRL_BL_CLK_ENABLE |\
 922                                 ISP5_CTRL_ISIF_CLK_ENABLE |\
 923                                 ISP5_CTRL_H3A_CLK_ENABLE |\
 924                                 ISP5_CTRL_RSZ_CLK_ENABLE |\
 925                                 ISP5_CTRL_IPIPE_CLK_ENABLE |\
 926                                 ISP5_CTRL_IPIPEIF_CLK_ENABLE)
 927
 928static void __iss_isp_subclk_update(struct iss_device *iss)
 929{
 930        u32 clk = 0;
 931
 932        if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_ISIF)
 933                clk |= ISP5_CTRL_ISIF_CLK_ENABLE;
 934
 935        if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_H3A)
 936                clk |= ISP5_CTRL_H3A_CLK_ENABLE;
 937
 938        if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_RSZ)
 939                clk |= ISP5_CTRL_RSZ_CLK_ENABLE;
 940
 941        if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPE)
 942                clk |= ISP5_CTRL_IPIPE_CLK_ENABLE;
 943
 944        if (iss->isp_subclk_resources & OMAP4_ISS_ISP_SUBCLK_IPIPEIF)
 945                clk |= ISP5_CTRL_IPIPEIF_CLK_ENABLE;
 946
 947        if (clk)
 948                clk |= ISP5_CTRL_BL_CLK_ENABLE;
 949
 950        iss_reg_update(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_CTRL,
 951                       ISS_ISP5_CLKCTRL_MASK, clk);
 952}
 953
 954void omap4iss_isp_subclk_enable(struct iss_device *iss,
 955                                enum iss_isp_subclk_resource res)
 956{
 957        iss->isp_subclk_resources |= res;
 958
 959        __iss_isp_subclk_update(iss);
 960}
 961
 962void omap4iss_isp_subclk_disable(struct iss_device *iss,
 963                                 enum iss_isp_subclk_resource res)
 964{
 965        iss->isp_subclk_resources &= ~res;
 966
 967        __iss_isp_subclk_update(iss);
 968}
 969
 970/*
 971 * iss_enable_clocks - Enable ISS clocks
 972 * @iss: OMAP4 ISS device
 973 *
 974 * Return 0 if successful, or clk_enable return value if any of tthem fails.
 975 */
 976static int iss_enable_clocks(struct iss_device *iss)
 977{
 978        int ret;
 979
 980        ret = clk_enable(iss->iss_fck);
 981        if (ret) {
 982                dev_err(iss->dev, "clk_enable iss_fck failed\n");
 983                return ret;
 984        }
 985
 986        ret = clk_enable(iss->iss_ctrlclk);
 987        if (ret) {
 988                dev_err(iss->dev, "clk_enable iss_ctrlclk failed\n");
 989                clk_disable(iss->iss_fck);
 990                return ret;
 991        }
 992
 993        return 0;
 994}
 995
 996/*
 997 * iss_disable_clocks - Disable ISS clocks
 998 * @iss: OMAP4 ISS device
 999 */
1000static void iss_disable_clocks(struct iss_device *iss)
1001{
1002        clk_disable(iss->iss_ctrlclk);
1003        clk_disable(iss->iss_fck);
1004}
1005
1006static int iss_get_clocks(struct iss_device *iss)
1007{
1008        iss->iss_fck = devm_clk_get(iss->dev, "iss_fck");
1009        if (IS_ERR(iss->iss_fck)) {
1010                dev_err(iss->dev, "Unable to get iss_fck clock info\n");
1011                return PTR_ERR(iss->iss_fck);
1012        }
1013
1014        iss->iss_ctrlclk = devm_clk_get(iss->dev, "iss_ctrlclk");
1015        if (IS_ERR(iss->iss_ctrlclk)) {
1016                dev_err(iss->dev, "Unable to get iss_ctrlclk clock info\n");
1017                return PTR_ERR(iss->iss_ctrlclk);
1018        }
1019
1020        return 0;
1021}
1022
1023/*
1024 * omap4iss_get - Acquire the ISS resource.
1025 *
1026 * Initializes the clocks for the first acquire.
1027 *
1028 * Increment the reference count on the ISS. If the first reference is taken,
1029 * enable clocks and power-up all submodules.
1030 *
1031 * Return a pointer to the ISS device structure, or NULL if an error occurred.
1032 */
1033struct iss_device *omap4iss_get(struct iss_device *iss)
1034{
1035        struct iss_device *__iss = iss;
1036
1037        if (iss == NULL)
1038                return NULL;
1039
1040        mutex_lock(&iss->iss_mutex);
1041        if (iss->ref_count > 0)
1042                goto out;
1043
1044        if (iss_enable_clocks(iss) < 0) {
1045                __iss = NULL;
1046                goto out;
1047        }
1048
1049        iss_enable_interrupts(iss);
1050
1051out:
1052        if (__iss != NULL)
1053                iss->ref_count++;
1054        mutex_unlock(&iss->iss_mutex);
1055
1056        return __iss;
1057}
1058
1059/*
1060 * omap4iss_put - Release the ISS
1061 *
1062 * Decrement the reference count on the ISS. If the last reference is released,
1063 * power-down all submodules, disable clocks and free temporary buffers.
1064 */
1065void omap4iss_put(struct iss_device *iss)
1066{
1067        if (iss == NULL)
1068                return;
1069
1070        mutex_lock(&iss->iss_mutex);
1071        BUG_ON(iss->ref_count == 0);
1072        if (--iss->ref_count == 0) {
1073                iss_disable_interrupts(iss);
1074                /* Reset the ISS if an entity has failed to stop. This is the
1075                 * only way to recover from such conditions, although it would
1076                 * be worth investigating whether resetting the ISP only can't
1077                 * fix the problem in some cases.
1078                 */
1079                if (iss->crashed)
1080                        iss_reset(iss);
1081                iss_disable_clocks(iss);
1082        }
1083        mutex_unlock(&iss->iss_mutex);
1084}
1085
1086static int iss_map_mem_resource(struct platform_device *pdev,
1087                                struct iss_device *iss,
1088                                enum iss_mem_resources res)
1089{
1090        struct resource *mem;
1091
1092        mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
1093
1094        iss->regs[res] = devm_ioremap_resource(iss->dev, mem);
1095
1096        return PTR_ERR_OR_ZERO(iss->regs[res]);
1097}
1098
1099static void iss_unregister_entities(struct iss_device *iss)
1100{
1101        omap4iss_resizer_unregister_entities(&iss->resizer);
1102        omap4iss_ipipe_unregister_entities(&iss->ipipe);
1103        omap4iss_ipipeif_unregister_entities(&iss->ipipeif);
1104        omap4iss_csi2_unregister_entities(&iss->csi2a);
1105        omap4iss_csi2_unregister_entities(&iss->csi2b);
1106
1107        v4l2_device_unregister(&iss->v4l2_dev);
1108        media_device_unregister(&iss->media_dev);
1109}
1110
1111/*
1112 * iss_register_subdev_group - Register a group of subdevices
1113 * @iss: OMAP4 ISS device
1114 * @board_info: I2C subdevs board information array
1115 *
1116 * Register all I2C subdevices in the board_info array. The array must be
1117 * terminated by a NULL entry, and the first entry must be the sensor.
1118 *
1119 * Return a pointer to the sensor media entity if it has been successfully
1120 * registered, or NULL otherwise.
1121 */
1122static struct v4l2_subdev *
1123iss_register_subdev_group(struct iss_device *iss,
1124                     struct iss_subdev_i2c_board_info *board_info)
1125{
1126        struct v4l2_subdev *sensor = NULL;
1127        unsigned int first;
1128
1129        if (board_info->board_info == NULL)
1130                return NULL;
1131
1132        for (first = 1; board_info->board_info; ++board_info, first = 0) {
1133                struct v4l2_subdev *subdev;
1134                struct i2c_adapter *adapter;
1135
1136                adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1137                if (adapter == NULL) {
1138                        dev_err(iss->dev,
1139                                "%s: Unable to get I2C adapter %d for device %s\n",
1140                                __func__, board_info->i2c_adapter_id,
1141                                board_info->board_info->type);
1142                        continue;
1143                }
1144
1145                subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter,
1146                                board_info->board_info, NULL);
1147                if (subdev == NULL) {
1148                        dev_err(iss->dev, "%s: Unable to register subdev %s\n",
1149                                __func__, board_info->board_info->type);
1150                        continue;
1151                }
1152
1153                if (first)
1154                        sensor = subdev;
1155        }
1156
1157        return sensor;
1158}
1159
1160static int iss_register_entities(struct iss_device *iss)
1161{
1162        struct iss_platform_data *pdata = iss->pdata;
1163        struct iss_v4l2_subdevs_group *subdevs;
1164        int ret;
1165
1166        iss->media_dev.dev = iss->dev;
1167        strlcpy(iss->media_dev.model, "TI OMAP4 ISS",
1168                sizeof(iss->media_dev.model));
1169        iss->media_dev.hw_revision = iss->revision;
1170        iss->media_dev.link_notify = iss_pipeline_link_notify;
1171        ret = media_device_register(&iss->media_dev);
1172        if (ret < 0) {
1173                dev_err(iss->dev, "%s: Media device registration failed (%d)\n",
1174                        __func__, ret);
1175                return ret;
1176        }
1177
1178        iss->v4l2_dev.mdev = &iss->media_dev;
1179        ret = v4l2_device_register(iss->dev, &iss->v4l2_dev);
1180        if (ret < 0) {
1181                dev_err(iss->dev, "%s: V4L2 device registration failed (%d)\n",
1182                        __func__, ret);
1183                goto done;
1184        }
1185
1186        /* Register internal entities */
1187        ret = omap4iss_csi2_register_entities(&iss->csi2a, &iss->v4l2_dev);
1188        if (ret < 0)
1189                goto done;
1190
1191        ret = omap4iss_csi2_register_entities(&iss->csi2b, &iss->v4l2_dev);
1192        if (ret < 0)
1193                goto done;
1194
1195        ret = omap4iss_ipipeif_register_entities(&iss->ipipeif, &iss->v4l2_dev);
1196        if (ret < 0)
1197                goto done;
1198
1199        ret = omap4iss_ipipe_register_entities(&iss->ipipe, &iss->v4l2_dev);
1200        if (ret < 0)
1201                goto done;
1202
1203        ret = omap4iss_resizer_register_entities(&iss->resizer, &iss->v4l2_dev);
1204        if (ret < 0)
1205                goto done;
1206
1207        /* Register external entities */
1208        for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
1209                struct v4l2_subdev *sensor;
1210                struct media_entity *input;
1211                unsigned int flags;
1212                unsigned int pad;
1213
1214                sensor = iss_register_subdev_group(iss, subdevs->subdevs);
1215                if (sensor == NULL)
1216                        continue;
1217
1218                sensor->host_priv = subdevs;
1219
1220                /* Connect the sensor to the correct interface module.
1221                 * CSI2a receiver through CSIPHY1, or
1222                 * CSI2b receiver through CSIPHY2
1223                 */
1224                switch (subdevs->interface) {
1225                case ISS_INTERFACE_CSI2A_PHY1:
1226                        input = &iss->csi2a.subdev.entity;
1227                        pad = CSI2_PAD_SINK;
1228                        flags = MEDIA_LNK_FL_IMMUTABLE
1229                              | MEDIA_LNK_FL_ENABLED;
1230                        break;
1231
1232                case ISS_INTERFACE_CSI2B_PHY2:
1233                        input = &iss->csi2b.subdev.entity;
1234                        pad = CSI2_PAD_SINK;
1235                        flags = MEDIA_LNK_FL_IMMUTABLE
1236                              | MEDIA_LNK_FL_ENABLED;
1237                        break;
1238
1239                default:
1240                        dev_err(iss->dev, "%s: invalid interface type %u\n",
1241                                __func__, subdevs->interface);
1242                        ret = -EINVAL;
1243                        goto done;
1244                }
1245
1246                ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1247                                               flags);
1248                if (ret < 0)
1249                        goto done;
1250        }
1251
1252        ret = v4l2_device_register_subdev_nodes(&iss->v4l2_dev);
1253
1254done:
1255        if (ret < 0)
1256                iss_unregister_entities(iss);
1257
1258        return ret;
1259}
1260
1261static void iss_cleanup_modules(struct iss_device *iss)
1262{
1263        omap4iss_csi2_cleanup(iss);
1264        omap4iss_ipipeif_cleanup(iss);
1265        omap4iss_ipipe_cleanup(iss);
1266        omap4iss_resizer_cleanup(iss);
1267}
1268
1269static int iss_initialize_modules(struct iss_device *iss)
1270{
1271        int ret;
1272
1273        ret = omap4iss_csiphy_init(iss);
1274        if (ret < 0) {
1275                dev_err(iss->dev, "CSI PHY initialization failed\n");
1276                goto error_csiphy;
1277        }
1278
1279        ret = omap4iss_csi2_init(iss);
1280        if (ret < 0) {
1281                dev_err(iss->dev, "CSI2 initialization failed\n");
1282                goto error_csi2;
1283        }
1284
1285        ret = omap4iss_ipipeif_init(iss);
1286        if (ret < 0) {
1287                dev_err(iss->dev, "ISP IPIPEIF initialization failed\n");
1288                goto error_ipipeif;
1289        }
1290
1291        ret = omap4iss_ipipe_init(iss);
1292        if (ret < 0) {
1293                dev_err(iss->dev, "ISP IPIPE initialization failed\n");
1294                goto error_ipipe;
1295        }
1296
1297        ret = omap4iss_resizer_init(iss);
1298        if (ret < 0) {
1299                dev_err(iss->dev, "ISP RESIZER initialization failed\n");
1300                goto error_resizer;
1301        }
1302
1303        /* Connect the submodules. */
1304        ret = media_entity_create_link(
1305                        &iss->csi2a.subdev.entity, CSI2_PAD_SOURCE,
1306                        &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1307        if (ret < 0)
1308                goto error_link;
1309
1310        ret = media_entity_create_link(
1311                        &iss->csi2b.subdev.entity, CSI2_PAD_SOURCE,
1312                        &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SINK, 0);
1313        if (ret < 0)
1314                goto error_link;
1315
1316        ret = media_entity_create_link(
1317                        &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1318                        &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1319        if (ret < 0)
1320                goto error_link;
1321
1322        ret = media_entity_create_link(
1323                        &iss->ipipeif.subdev.entity, IPIPEIF_PAD_SOURCE_VP,
1324                        &iss->ipipe.subdev.entity, IPIPE_PAD_SINK, 0);
1325        if (ret < 0)
1326                goto error_link;
1327
1328        ret = media_entity_create_link(
1329                        &iss->ipipe.subdev.entity, IPIPE_PAD_SOURCE_VP,
1330                        &iss->resizer.subdev.entity, RESIZER_PAD_SINK, 0);
1331        if (ret < 0)
1332                goto error_link;
1333
1334        return 0;
1335
1336error_link:
1337        omap4iss_resizer_cleanup(iss);
1338error_resizer:
1339        omap4iss_ipipe_cleanup(iss);
1340error_ipipe:
1341        omap4iss_ipipeif_cleanup(iss);
1342error_ipipeif:
1343        omap4iss_csi2_cleanup(iss);
1344error_csi2:
1345error_csiphy:
1346        return ret;
1347}
1348
1349static int iss_probe(struct platform_device *pdev)
1350{
1351        struct iss_platform_data *pdata = pdev->dev.platform_data;
1352        struct iss_device *iss;
1353        unsigned int i;
1354        int ret;
1355
1356        if (pdata == NULL)
1357                return -EINVAL;
1358
1359        iss = devm_kzalloc(&pdev->dev, sizeof(*iss), GFP_KERNEL);
1360        if (!iss)
1361                return -ENOMEM;
1362
1363        mutex_init(&iss->iss_mutex);
1364
1365        iss->dev = &pdev->dev;
1366        iss->pdata = pdata;
1367
1368        iss->raw_dmamask = DMA_BIT_MASK(32);
1369        iss->dev->dma_mask = &iss->raw_dmamask;
1370        iss->dev->coherent_dma_mask = DMA_BIT_MASK(32);
1371
1372        platform_set_drvdata(pdev, iss);
1373
1374        /* Clocks */
1375        ret = iss_map_mem_resource(pdev, iss, OMAP4_ISS_MEM_TOP);
1376        if (ret < 0)
1377                goto error;
1378
1379        ret = iss_get_clocks(iss);
1380        if (ret < 0)
1381                goto error;
1382
1383        if (omap4iss_get(iss) == NULL)
1384                goto error;
1385
1386        ret = iss_reset(iss);
1387        if (ret < 0)
1388                goto error_iss;
1389
1390        iss->revision = iss_reg_read(iss, OMAP4_ISS_MEM_TOP, ISS_HL_REVISION);
1391        dev_info(iss->dev, "Revision %08x found\n", iss->revision);
1392
1393        for (i = 1; i < OMAP4_ISS_MEM_LAST; i++) {
1394                ret = iss_map_mem_resource(pdev, iss, i);
1395                if (ret)
1396                        goto error_iss;
1397        }
1398
1399        /* Configure BTE BW_LIMITER field to max recommended value (1 GB) */
1400        iss_reg_update(iss, OMAP4_ISS_MEM_BTE, BTE_CTRL,
1401                       BTE_CTRL_BW_LIMITER_MASK,
1402                       18 << BTE_CTRL_BW_LIMITER_SHIFT);
1403
1404        /* Perform ISP reset */
1405        ret = omap4iss_subclk_enable(iss, OMAP4_ISS_SUBCLK_ISP);
1406        if (ret < 0)
1407                goto error_iss;
1408
1409        ret = iss_isp_reset(iss);
1410        if (ret < 0)
1411                goto error_iss;
1412
1413        dev_info(iss->dev, "ISP Revision %08x found\n",
1414                 iss_reg_read(iss, OMAP4_ISS_MEM_ISP_SYS1, ISP5_REVISION));
1415
1416        /* Interrupt */
1417        iss->irq_num = platform_get_irq(pdev, 0);
1418        if (iss->irq_num <= 0) {
1419                dev_err(iss->dev, "No IRQ resource\n");
1420                ret = -ENODEV;
1421                goto error_iss;
1422        }
1423
1424        if (devm_request_irq(iss->dev, iss->irq_num, iss_isr, IRQF_SHARED,
1425                             "OMAP4 ISS", iss)) {
1426                dev_err(iss->dev, "Unable to request IRQ\n");
1427                ret = -EINVAL;
1428                goto error_iss;
1429        }
1430
1431        /* Entities */
1432        ret = iss_initialize_modules(iss);
1433        if (ret < 0)
1434                goto error_iss;
1435
1436        ret = iss_register_entities(iss);
1437        if (ret < 0)
1438                goto error_modules;
1439
1440        omap4iss_put(iss);
1441
1442        return 0;
1443
1444error_modules:
1445        iss_cleanup_modules(iss);
1446error_iss:
1447        omap4iss_put(iss);
1448error:
1449        platform_set_drvdata(pdev, NULL);
1450
1451        mutex_destroy(&iss->iss_mutex);
1452
1453        return ret;
1454}
1455
1456static int iss_remove(struct platform_device *pdev)
1457{
1458        struct iss_device *iss = platform_get_drvdata(pdev);
1459
1460        iss_unregister_entities(iss);
1461        iss_cleanup_modules(iss);
1462
1463        return 0;
1464}
1465
1466static struct platform_device_id omap4iss_id_table[] = {
1467        { "omap4iss", 0 },
1468        { },
1469};
1470MODULE_DEVICE_TABLE(platform, omap4iss_id_table);
1471
1472static struct platform_driver iss_driver = {
1473        .probe          = iss_probe,
1474        .remove         = iss_remove,
1475        .id_table       = omap4iss_id_table,
1476        .driver = {
1477                .name   = "omap4iss",
1478        },
1479};
1480
1481module_platform_driver(iss_driver);
1482
1483MODULE_DESCRIPTION("TI OMAP4 ISS driver");
1484MODULE_AUTHOR("Sergio Aguirre <sergio.a.aguirre@gmail.com>");
1485MODULE_LICENSE("GPL");
1486MODULE_VERSION(ISS_VIDEO_DRIVER_VERSION);
1487
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.