From: Andrew Morton <akpm@linux-foundation.org>
To: linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v6 1/2] video: support MIPI-DSI controller driver
Date: Wed, 18 Jan 2012 21:05:50 +0000 [thread overview]
Message-ID: <20120118130550.0bdb227e.akpm@linux-foundation.org> (raw)
In-Reply-To: <4F16288C.5020406@samsung.com>
On Wed, 18 Jan 2012 11:03:56 +0900
Donghwa Lee <dh09.lee@samsung.com> wrote:
> Samsung S5PC210 and EXYNOS SoC platform has MIPI-DSI controller and MIPI-DSI
> based LCD Panel could be used with it. This patch supports MIPI-DSI driver
> based Samsung SoC chip.
>
> LCD panel driver based MIPI-DSI should be registered to MIPI-DSI driver at
> machine code and LCD panel driver specific function registered to mipi_dsim_ddi
> structure at lcd panel init function called system init.
> In the MIPI-DSI driver, find lcd panel driver by using registered
> lcd panel name, and then initialize lcd panel driver.
>
The code looks nice to me. I assume that Florian will be processing
the patch?
A few minor comments:
>
> ...
>
> +#define master_to_driver(a) (a->dsim_lcd_drv)
> +#define master_to_device(a) (a->dsim_lcd_dev)
> +#define dev_to_dsim(a) platform_get_drvdata(to_platform_device(a))
These aren't very type-safe: can be called on any struct whcih has a
field called "dsim_lcd_drv". Also the "a" should be parenthesized to
prevent obscure compile problems.
Really, it's best to do away with all such problems by implementing
these helpers in C rather than in cpp!
>
> ...
>
> +int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
> +{
> + struct mipi_dsim_ddi *dsim_ddi;
> +
> + if (!lcd_dev) {
> + pr_err("mipi_dsim_lcd_device is NULL.\n");
> + return -EFAULT;
> + }
Can this happen? If not then BUG() is more appropriate. Or just
remove the code altogether and let the kernel oops.
> + if (!lcd_dev->name) {
> + pr_err("dsim_lcd_device name is NULL.\n");
> + return -EFAULT;
> + }
Ditto.
> + dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
> + if (!dsim_ddi) {
> + pr_err("failed to allocate dsim_ddi object.\n");
> + return -EFAULT;
Should be ENOMEM.
> + }
> +
> + dsim_ddi->dsim_lcd_dev = lcd_dev;
> +
> + mutex_lock(&mipi_dsim_lock);
> + list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return 0;
> +}
> +
> +struct mipi_dsim_ddi
> + *s5p_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
Strange code layout.
> +{
> + struct mipi_dsim_ddi *dsim_ddi, *next;
> + struct mipi_dsim_lcd_device *lcd_dev;
> +
> + mutex_lock(&mipi_dsim_lock);
> +
> + list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
> + if (!dsim_ddi)
> + goto out;
> +
> + lcd_dev = dsim_ddi->dsim_lcd_dev;
> + if (!lcd_dev)
> + continue;
> +
> + if ((strcmp(lcd_drv->name, lcd_dev->name)) = 0) {
hm, using strcmp() to compare devices in this way looks fishy. But I
don't know what is going on here.
> + /**
> + * bus_id would be used to identify
> + * connected bus.
> + */
> + dsim_ddi->bus_id = lcd_dev->bus_id;
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return dsim_ddi;
> + }
> +
> + list_del(&dsim_ddi->list);
> + kfree(dsim_ddi);
> + }
> +
> +out:
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return NULL;
> +}
> +
> +int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
> +{
> + struct mipi_dsim_ddi *dsim_ddi;
> +
> + if (!lcd_drv) {
> + pr_err("mipi_dsim_lcd_driver is NULL.\n");
> + return -EFAULT;
> + }
> +
> + if (!lcd_drv->name) {
> + pr_err("dsim_lcd_driver name is NULL.\n");
> + return -EFAULT;
> + }
> +
> + dsim_ddi = s5p_mipi_dsi_find_lcd_device(lcd_drv);
> + if (!dsim_ddi) {
> + pr_err("mipi_dsim_ddi object not found.\n");
> + return -EFAULT;
> + }
Boy, someone really likes EFAULT!
> + dsim_ddi->dsim_lcd_drv = lcd_drv;
> +
> + pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
> + lcd_drv->name);
> +
> + return 0;
> +
> +}
> +
> +struct mipi_dsim_ddi
> + *s5p_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
> + const char *name)
More code layout oddness.
> +{
> + struct mipi_dsim_ddi *dsim_ddi, *next;
> + struct mipi_dsim_lcd_driver *lcd_drv;
> + struct mipi_dsim_lcd_device *lcd_dev;
> + int ret;
> +
> + mutex_lock(&dsim->lock);
> +
> + list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
> + lcd_drv = dsim_ddi->dsim_lcd_drv;
> + lcd_dev = dsim_ddi->dsim_lcd_dev;
> + if (!lcd_drv || !lcd_dev ||
> + (dsim->id != dsim_ddi->bus_id))
> + continue;
> +
> + dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
> + lcd_drv->id, lcd_dev->id);
> + dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
> + lcd_dev->bus_id, dsim->id);
> +
> + if ((strcmp(lcd_drv->name, name) = 0)) {
> + lcd_dev->master = dsim;
> +
> + lcd_dev->dev.parent = dsim->dev;
> + dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
> +
> + ret = device_register(&lcd_dev->dev);
> + if (ret < 0) {
> + dev_err(dsim->dev,
> + "can't register %s, status %d\n",
> + dev_name(&lcd_dev->dev), ret);
> + mutex_unlock(&dsim->lock);
> +
> + return NULL;
> + }
> +
> + dsim->dsim_lcd_dev = lcd_dev;
> + dsim->dsim_lcd_drv = lcd_drv;
> +
> + mutex_unlock(&dsim->lock);
> +
> + return dsim_ddi;
> + }
> + }
> +
> + mutex_unlock(&dsim->lock);
> +
> + return NULL;
> +}
>
> ...
>
> +static int s5p_mipi_dsi_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct mipi_dsim_device *dsim;
> + struct mipi_dsim_config *dsim_config;
> + struct mipi_dsim_platform_data *dsim_pd;
> + struct mipi_dsim_ddi *dsim_ddi;
> + int ret = -EINVAL;
> +
> + dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
> + if (!dsim) {
> + dev_err(&pdev->dev, "failed to allocate dsim object.\n");
> + return -EFAULT;
ENOMEM!
> + }
> +
> + dsim->pd = to_dsim_plat(pdev);
> + dsim->dev = &pdev->dev;
> + dsim->id = pdev->id;
> +
> + /* get mipi_dsim_platform_data. */
> + dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
> + if (dsim_pd = NULL) {
> + dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
> + goto err_clock_get;
> + }
>
> ...
>
> +irqreturn_t s5p_mipi_dsi_interrupt_handler(int irq, void *dev_id)
> +{
> + unsigned int intsrc = 0;
> + unsigned int intmsk = 0;
> + struct mipi_dsim_device *dsim = NULL;
> +
> + dsim = (struct mipi_dsim_device *)dev_id;
unneeded and undesirable cast of void*
> + if (!dsim) {
> + dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n",
> + __func__);
> + return IRQ_HANDLED;
> + }
> +
> + intsrc = s5p_mipi_dsi_read_interrupt(dsim);
> + intmsk = s5p_mipi_dsi_read_interrupt_mask(dsim);
> +
> + intmsk = ~(intmsk) & intsrc;
> +
> + switch (intmsk) {
> + case INTMSK_RX_DONE:
> + complete(&dsim_rd_comp);
> + dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
> + break;
> + case INTMSK_FIFO_EMPTY:
> + complete(&dsim_wr_comp);
> + dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
> + break;
> + default:
> + break;
> + }
> +
> + s5p_mipi_dsi_clear_interrupt(dsim, intmsk);
> +
> + return IRQ_HANDLED;
> +}
>
> ...
>
Generally: the use of the Efoo errno codes is chaotic. Please check it
all over.
WARNING: multiple messages have this Message-ID (diff)
From: akpm@linux-foundation.org (Andrew Morton)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 1/2] video: support MIPI-DSI controller driver
Date: Wed, 18 Jan 2012 13:05:50 -0800 [thread overview]
Message-ID: <20120118130550.0bdb227e.akpm@linux-foundation.org> (raw)
In-Reply-To: <4F16288C.5020406@samsung.com>
On Wed, 18 Jan 2012 11:03:56 +0900
Donghwa Lee <dh09.lee@samsung.com> wrote:
> Samsung S5PC210 and EXYNOS SoC platform has MIPI-DSI controller and MIPI-DSI
> based LCD Panel could be used with it. This patch supports MIPI-DSI driver
> based Samsung SoC chip.
>
> LCD panel driver based MIPI-DSI should be registered to MIPI-DSI driver at
> machine code and LCD panel driver specific function registered to mipi_dsim_ddi
> structure at lcd panel init function called system init.
> In the MIPI-DSI driver, find lcd panel driver by using registered
> lcd panel name, and then initialize lcd panel driver.
>
The code looks nice to me. I assume that Florian will be processing
the patch?
A few minor comments:
>
> ...
>
> +#define master_to_driver(a) (a->dsim_lcd_drv)
> +#define master_to_device(a) (a->dsim_lcd_dev)
> +#define dev_to_dsim(a) platform_get_drvdata(to_platform_device(a))
These aren't very type-safe: can be called on any struct whcih has a
field called "dsim_lcd_drv". Also the "a" should be parenthesized to
prevent obscure compile problems.
Really, it's best to do away with all such problems by implementing
these helpers in C rather than in cpp!
>
> ...
>
> +int s5p_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
> +{
> + struct mipi_dsim_ddi *dsim_ddi;
> +
> + if (!lcd_dev) {
> + pr_err("mipi_dsim_lcd_device is NULL.\n");
> + return -EFAULT;
> + }
Can this happen? If not then BUG() is more appropriate. Or just
remove the code altogether and let the kernel oops.
> + if (!lcd_dev->name) {
> + pr_err("dsim_lcd_device name is NULL.\n");
> + return -EFAULT;
> + }
Ditto.
> + dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
> + if (!dsim_ddi) {
> + pr_err("failed to allocate dsim_ddi object.\n");
> + return -EFAULT;
Should be ENOMEM.
> + }
> +
> + dsim_ddi->dsim_lcd_dev = lcd_dev;
> +
> + mutex_lock(&mipi_dsim_lock);
> + list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return 0;
> +}
> +
> +struct mipi_dsim_ddi
> + *s5p_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
Strange code layout.
> +{
> + struct mipi_dsim_ddi *dsim_ddi, *next;
> + struct mipi_dsim_lcd_device *lcd_dev;
> +
> + mutex_lock(&mipi_dsim_lock);
> +
> + list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
> + if (!dsim_ddi)
> + goto out;
> +
> + lcd_dev = dsim_ddi->dsim_lcd_dev;
> + if (!lcd_dev)
> + continue;
> +
> + if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
hm, using strcmp() to compare devices in this way looks fishy. But I
don't know what is going on here.
> + /**
> + * bus_id would be used to identify
> + * connected bus.
> + */
> + dsim_ddi->bus_id = lcd_dev->bus_id;
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return dsim_ddi;
> + }
> +
> + list_del(&dsim_ddi->list);
> + kfree(dsim_ddi);
> + }
> +
> +out:
> + mutex_unlock(&mipi_dsim_lock);
> +
> + return NULL;
> +}
> +
> +int s5p_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
> +{
> + struct mipi_dsim_ddi *dsim_ddi;
> +
> + if (!lcd_drv) {
> + pr_err("mipi_dsim_lcd_driver is NULL.\n");
> + return -EFAULT;
> + }
> +
> + if (!lcd_drv->name) {
> + pr_err("dsim_lcd_driver name is NULL.\n");
> + return -EFAULT;
> + }
> +
> + dsim_ddi = s5p_mipi_dsi_find_lcd_device(lcd_drv);
> + if (!dsim_ddi) {
> + pr_err("mipi_dsim_ddi object not found.\n");
> + return -EFAULT;
> + }
Boy, someone really likes EFAULT!
> + dsim_ddi->dsim_lcd_drv = lcd_drv;
> +
> + pr_info("registered panel driver(%s) to mipi-dsi driver.\n",
> + lcd_drv->name);
> +
> + return 0;
> +
> +}
> +
> +struct mipi_dsim_ddi
> + *s5p_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
> + const char *name)
More code layout oddness.
> +{
> + struct mipi_dsim_ddi *dsim_ddi, *next;
> + struct mipi_dsim_lcd_driver *lcd_drv;
> + struct mipi_dsim_lcd_device *lcd_dev;
> + int ret;
> +
> + mutex_lock(&dsim->lock);
> +
> + list_for_each_entry_safe(dsim_ddi, next, &dsim_ddi_list, list) {
> + lcd_drv = dsim_ddi->dsim_lcd_drv;
> + lcd_dev = dsim_ddi->dsim_lcd_dev;
> + if (!lcd_drv || !lcd_dev ||
> + (dsim->id != dsim_ddi->bus_id))
> + continue;
> +
> + dev_dbg(dsim->dev, "lcd_drv->id = %d, lcd_dev->id = %d\n",
> + lcd_drv->id, lcd_dev->id);
> + dev_dbg(dsim->dev, "lcd_dev->bus_id = %d, dsim->id = %d\n",
> + lcd_dev->bus_id, dsim->id);
> +
> + if ((strcmp(lcd_drv->name, name) == 0)) {
> + lcd_dev->master = dsim;
> +
> + lcd_dev->dev.parent = dsim->dev;
> + dev_set_name(&lcd_dev->dev, "%s", lcd_drv->name);
> +
> + ret = device_register(&lcd_dev->dev);
> + if (ret < 0) {
> + dev_err(dsim->dev,
> + "can't register %s, status %d\n",
> + dev_name(&lcd_dev->dev), ret);
> + mutex_unlock(&dsim->lock);
> +
> + return NULL;
> + }
> +
> + dsim->dsim_lcd_dev = lcd_dev;
> + dsim->dsim_lcd_drv = lcd_drv;
> +
> + mutex_unlock(&dsim->lock);
> +
> + return dsim_ddi;
> + }
> + }
> +
> + mutex_unlock(&dsim->lock);
> +
> + return NULL;
> +}
>
> ...
>
> +static int s5p_mipi_dsi_probe(struct platform_device *pdev)
> +{
> + struct resource *res;
> + struct mipi_dsim_device *dsim;
> + struct mipi_dsim_config *dsim_config;
> + struct mipi_dsim_platform_data *dsim_pd;
> + struct mipi_dsim_ddi *dsim_ddi;
> + int ret = -EINVAL;
> +
> + dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
> + if (!dsim) {
> + dev_err(&pdev->dev, "failed to allocate dsim object.\n");
> + return -EFAULT;
ENOMEM!
> + }
> +
> + dsim->pd = to_dsim_plat(pdev);
> + dsim->dev = &pdev->dev;
> + dsim->id = pdev->id;
> +
> + /* get mipi_dsim_platform_data. */
> + dsim_pd = (struct mipi_dsim_platform_data *)dsim->pd;
> + if (dsim_pd == NULL) {
> + dev_err(&pdev->dev, "failed to get platform data for dsim.\n");
> + goto err_clock_get;
> + }
>
> ...
>
> +irqreturn_t s5p_mipi_dsi_interrupt_handler(int irq, void *dev_id)
> +{
> + unsigned int intsrc = 0;
> + unsigned int intmsk = 0;
> + struct mipi_dsim_device *dsim = NULL;
> +
> + dsim = (struct mipi_dsim_device *)dev_id;
unneeded and undesirable cast of void*
> + if (!dsim) {
> + dev_dbg(dsim->dev, KERN_ERR "%s:error: wrong parameter\n",
> + __func__);
> + return IRQ_HANDLED;
> + }
> +
> + intsrc = s5p_mipi_dsi_read_interrupt(dsim);
> + intmsk = s5p_mipi_dsi_read_interrupt_mask(dsim);
> +
> + intmsk = ~(intmsk) & intsrc;
> +
> + switch (intmsk) {
> + case INTMSK_RX_DONE:
> + complete(&dsim_rd_comp);
> + dev_dbg(dsim->dev, "MIPI INTMSK_RX_DONE\n");
> + break;
> + case INTMSK_FIFO_EMPTY:
> + complete(&dsim_wr_comp);
> + dev_dbg(dsim->dev, "MIPI INTMSK_FIFO_EMPTY\n");
> + break;
> + default:
> + break;
> + }
> +
> + s5p_mipi_dsi_clear_interrupt(dsim, intmsk);
> +
> + return IRQ_HANDLED;
> +}
>
> ...
>
Generally: the use of the Efoo errno codes is chaotic. Please check it
all over.
next prev parent reply other threads:[~2012-01-18 21:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-18 2:03 [PATCH v6 1/2] video: support MIPI-DSI controller driver Donghwa Lee
2012-01-18 2:03 ` Donghwa Lee
2012-01-18 9:33 ` Archit
2012-01-18 9:45 ` Archit
2012-01-18 21:05 ` Andrew Morton [this message]
2012-01-18 21:05 ` Andrew Morton
2012-01-19 0:15 ` Kyungmin Park
2012-01-19 0:15 ` Kyungmin Park
2012-01-19 1:59 ` Donghwa Lee
2012-01-19 1:59 ` Donghwa Lee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120118130550.0bdb227e.akpm@linux-foundation.org \
--to=akpm@linux-foundation.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.