static int mipi_display_on(struct sh_mobile_lcdc_entity *entity) { struct sh_mipi *mipi = to_sh_mipi(entity); struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; int ret; pm_runtime_get_sync(&mipi->pdev->dev); ret = pdata->set_dot_clock(mipi->pdev, mipi->base, 1); if (ret < 0) goto mipi_display_on_fail1; ret = sh_mipi_setup(mipi, &entity->def_mode); if (ret < 0) goto mipi_display_on_fail2; sh_mipi_dsi_enable(mipi, true); return SH_MOBILE_LCDC_DISPLAY_CONNECTED; mipi_display_on_fail1: pm_runtime_put_sync(&mipi->pdev->dev); mipi_display_on_fail2: pdata->set_dot_clock(mipi->pdev, mipi->base, 0); return ret; }
static int __init sh_mipi_probe(struct platform_device *pdev) { struct sh_mipi *mipi; struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data; struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); unsigned long rate, f_current; int idx = pdev->id, ret; char dsip_clk[] = "dsi.p_clk"; if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata) return -ENODEV; mutex_lock(&array_lock); if (idx < 0) for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++) ; if (idx == ARRAY_SIZE(mipi_dsi)) { ret = -EBUSY; goto efindslot; } mipi = kzalloc(sizeof(*mipi), GFP_KERNEL); if (!mipi) { ret = -ENOMEM; goto ealloc; } if (!request_mem_region(res->start, resource_size(res), pdev->name)) { dev_err(&pdev->dev, "MIPI register region already claimed\n"); ret = -EBUSY; goto ereqreg; } mipi->base = ioremap(res->start, resource_size(res)); if (!mipi->base) { ret = -ENOMEM; goto emap; } mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk"); if (IS_ERR(mipi->dsit_clk)) { ret = PTR_ERR(mipi->dsit_clk); goto eclktget; } f_current = clk_get_rate(mipi->dsit_clk); /* 80MHz required by the datasheet */ rate = clk_round_rate(mipi->dsit_clk, 80000000); if (rate > 0 && rate != f_current) ret = clk_set_rate(mipi->dsit_clk, rate); else ret = rate; if (ret < 0) goto esettrate; dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate); sprintf(dsip_clk, "dsi%1.1dp_clk", idx); mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk); if (IS_ERR(mipi->dsip_clk)) { ret = PTR_ERR(mipi->dsip_clk); goto eclkpget; } f_current = clk_get_rate(mipi->dsip_clk); /* Between 10 and 50MHz */ rate = clk_round_rate(mipi->dsip_clk, 24000000); if (rate > 0 && rate != f_current) ret = clk_set_rate(mipi->dsip_clk, rate); else ret = rate; if (ret < 0) goto esetprate; dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate); msleep(10); ret = clk_enable(mipi->dsit_clk); if (ret < 0) goto eclkton; ret = clk_enable(mipi->dsip_clk); if (ret < 0) goto eclkpon; mipi_dsi[idx] = mipi; ret = sh_mipi_setup(mipi, pdata); if (ret < 0) goto emipisetup; mutex_unlock(&array_lock); platform_set_drvdata(pdev, mipi); /* Set up LCDC callbacks */ pdata->lcd_chan->board_cfg.board_data = mipi; pdata->lcd_chan->board_cfg.display_on = mipi_display_on; pdata->lcd_chan->board_cfg.display_off = mipi_display_off; return 0; emipisetup: mipi_dsi[idx] = NULL; clk_disable(mipi->dsip_clk); eclkpon: clk_disable(mipi->dsit_clk); eclkton: esetprate: clk_put(mipi->dsip_clk); eclkpget: esettrate: clk_put(mipi->dsit_clk); eclktget: iounmap(mipi->base); emap: release_mem_region(res->start, resource_size(res)); ereqreg: kfree(mipi); ealloc: efindslot: mutex_unlock(&array_lock); return ret; }