Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 5/5] mmc: sdhci-esdhc: enable esdhc on imx53
From: Zhu Richard-R65037 @ 2011-02-28  2:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110225203849.GC2192@pengutronix.de>

Hi WolfSang:
This phenomena is caused by the IC modifications on imx53 refer to imx51.
The details about this patch used for are listed below:
In order to generate the TC INT correctly, the CMD type of CMD12 should be set in the CMD register for
 mass storage Multi-BLK IO(CMD18/CMD25), and the bit1 of the Vendor Spec register should be set/clear
 at the begin/end of the Multi-BLK read.
Otherwise, there wouldn't TC INT generation in the mass storage Multi-BLK IO(CMD18/CMD25) and
 SDIO Multi-BLK read operations.

That's all. How about add these description into the commit?

Best Regards
Richard Zhu

> -----Original Message-----
> From: Wolfram Sang [mailto:w.sang at pengutronix.de]
> Sent: Saturday, February 26, 2011 4:39 AM
> To: Zhu Richard-R65037
> Cc: linux-arm-kernel at lists.infradead.org; kernel at pengutronix.de; linux-
> mmc at vger.kernel.org; cjb at laptop.org; avorontsov at ru.mvista.com;
> eric at eukrea.com; linuxzsc at gmail.com; Zhao Richard-B20223
> Subject: Re: [PATCH v2 5/5] mmc: sdhci-esdhc: enable esdhc on imx53
>
> On Tue, Feb 22, 2011 at 06:13:26PM +0800, Richard Zhu wrote:
>
> > Fix the NO INT in the Multi-BLK IO in SD/MMC, and Multi-BLK read in
> > SDIO
>
> This description is too short. Why does it not work before, and why does
> this patch help?
>
> >
> > Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
> > ---
> >  drivers/mmc/host/sdhci-esdhc-imx.c |   41
> +++++++++++++++++++++++++++++++++++-
> >  drivers/mmc/host/sdhci-esdhc.h     |    5 ++++
> >  2 files changed, 45 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c
> > b/drivers/mmc/host/sdhci-esdhc-imx.c
> > index 9b82910..a09f786 100644
> > --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> > +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> > @@ -17,6 +17,8 @@
> >  #include <linux/clk.h>
> >  #include <linux/mmc/host.h>
> >  #include <linux/mmc/sdhci-pltfm.h>
> > +#include <linux/mmc/mmc.h>
> > +#include <linux/mmc/sdio.h>
> >  #include <mach/hardware.h>
> >  #include "sdhci.h"
> >  #include "sdhci-pltfm.h"
> > @@ -38,6 +40,27 @@ static u16 esdhc_readw_le(struct sdhci_host *host,
> int reg)
> >     return readw(host->ioaddr + reg);
> >  }
> >
> > +static void esdhc_writel_le(struct sdhci_host *host, u32 val, int
> > +reg) {
> > +   switch (reg) {
> > +   case SDHCI_INT_STATUS:
> > +           /*
> > +            * Fix no INT bug in SDIO MULTI-BLK read
> > +            * clear bit1 of Vendor Spec registor after TC
> > +            */
>
> Same for this comment. Make it more descriptive, please
>
> > +           if (val & SDHCI_INT_DATA_END) {
> > +                   u32 v;
> > +                   v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
> > +                   if (v & 0x2) {
> > +                           v &= (~0x2);
>
> Braces not needed.
>
> > +                           writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
> > +                   }
>
> Can't you clear it unconditionally?
>
> > +           }
> > +           break;
> > +   }
> > +   writel(val, host->ioaddr + reg);
> > +}
> > +
> >  static void esdhc_writew_le(struct sdhci_host *host, u16 val, int
> > reg)  {
> >     struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -45,12
> > +68,27 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val,
> int reg)
> >     switch (reg) {
> >     case SDHCI_TRANSFER_MODE:
> >             /*
> > +            * Fix no INT bug in SDIO MULTI-BLK read
> > +            * set bit1 of Vendor Spec registor
> > +            */
> > +           if ((host->cmd->opcode == SD_IO_RW_EXTENDED)
> > +                           && (host->cmd->data->blocks > 1)
> > +                           && (host->cmd->data->flags & MMC_DATA_READ)) {
> > +                   u32 v;
> > +                   v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
> > +                   v |= 0x2;
> > +                   writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
> > +           }
> > +           /*
> >              * Postpone this write, we must do it together with a
> >              * command write that is down below.
> >              */
> >             pltfm_host->scratchpad = val;
> >             return;
> >     case SDHCI_COMMAND:
> > +           /*Set the CMD_TYPE of the CMD12, fix no INT in MULTI_BLK IO
> */
> > +           if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
> > +                   val |= SDHCI_CMD_ABORTCMD;
>
> Can't we handle it the same way than the SDIO case? I have to admit, even
> after reading the docs, I don't fully get what this bit1 is about.
>
> >             writel(val << 16 | pltfm_host->scratchpad,
> >                     host->ioaddr + SDHCI_TRANSFER_MODE);
> >             return;
> > @@ -113,7 +151,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host,
> struct sdhci_pltfm_data *pd
> >     clk_enable(clk);
> >     pltfm_host->clk = clk;
> >
> > -   if (cpu_is_mx35() || cpu_is_mx51())
> > +   if (!cpu_is_mx25())
> >             host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
> >
> >     /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
> @@
> > -133,6 +171,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
> >
> >  static struct sdhci_ops sdhci_esdhc_ops = {
> >     .read_w = esdhc_readw_le,
> > +   .write_l = esdhc_writel_le,
>
> You are applying it for all imx-versions?
>
> >     .write_w = esdhc_writew_le,
> >     .write_b = esdhc_writeb_le,
> >     .set_clock = esdhc_set_clock,
> > diff --git a/drivers/mmc/host/sdhci-esdhc.h
> > b/drivers/mmc/host/sdhci-esdhc.h index 303cde0..c93168c 100644
> > --- a/drivers/mmc/host/sdhci-esdhc.h
> > +++ b/drivers/mmc/host/sdhci-esdhc.h
> > @@ -43,6 +43,11 @@
> >
> >  #define ESDHC_HOST_CONTROL_RES     0x05
> >
> > +/* Abort type definition in the command register  */
> > +#define  SDHCI_CMD_ABORTCMD        0xC0
>
> So, this is vendor-specific, too?
>
> > +/* VENDOR SPEC register */
> > +#define SDHCI_VENDOR_SPEC  0xC0
> > +
> >  static inline void esdhc_set_clock(struct sdhci_host *host, unsigned
> > int clock)  {
> >     int pre_div = 2;
>
> Regards,
>
>    Wolfram
>
> --
> Pengutronix e.K.                           | Wolfram Sang
> |
> Industrial Linux Solutions                 | http://www.pengutronix.de/
> |

^ permalink raw reply

* [PATCH 0/8] OMAP2+: hwmod/clockevent: allow late-init of individual hwmods
From: Paul Walmsley @ 2011-02-28  2:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D651998.3040002@ti.com>

Salut Beno?t,

On Wed, 23 Feb 2011, Cousson, Benoit wrote:

> On 2/23/2011 8:11 AM, Paul Walmsley wrote:
> > This series adds the ability to late-initialize individual
> > hwmods.  The goal here is for clockevent (and eventually
> > clocksource) hwmods to be late-initialized individually, and
> > right before they are needed, in the timer init code.  Then
> > omap_hwmod_late_init(), which late-inits the rest of the hwmods,
> > is intended to run as an initcall -- much later in the boot
> > process.
> > 
> > This series includes the OMAP2/3 hwmod data for the GPTIMERs that
> > Tarun posted earlier.  This data is necessary for this new code
> > to avoid warnings during boot.
> > 
> > Boot-tested on N800, OMAP34xx Beagleboard and OMAP4430ES2 Panda.
> 
> I'm testing it on 4430sdp, and I have the following warning:
> 
> [    0.000000] omap_hwmod: dpll_mpu_m2_ck: missing clockdomain for dpll_mpu_m2_ck.
> [    0.000000] ------------[ cut here ]------------
> [    0.000000] WARNING: at arch/arm/mach-omap2/timer-gp.c:157 omap2_gp_timer_init+0x80/0x190()
> [    0.000000] timer-gp: omap_dm_timer_set_source() failed
> [    0.000000] Modules linked in:
> [    0.000000] [<c0062a6c>] (unwind_backtrace+0x0/0xec) from [<c009422c>] (warn_slowpath_common+0x4c/0x64)
> [    0.000000] [<c009422c>] (warn_slowpath_common+0x4c/0x64) from [<c00942c4>] (warn_slowpath_fmt+0x2c/0x3c)
> [    0.000000] [<c00942c4>] (warn_slowpath_fmt+0x2c/0x3c) from [<c0010e30>] (omap2_gp_timer_init+0x80/0x190)
> [    0.000000] [<c0010e30>] (omap2_gp_timer_init+0x80/0x190) from [<c000c0dc>] (time_init+0x20/0x30)
> [    0.000000] [<c000c0dc>] (time_init+0x20/0x30) from [<c0008cbc>] (start_kernel+0x1a4/0x30c)
> [    0.000000] [<c0008cbc>] (start_kernel+0x1a4/0x30c) from [<80008038>] (0x80008038)
> [    0.000000] ---[ end trace 1b75b31a2719ed1c ]---
> [    0.000000] OMAP clockevent source: GPTIMER1 at 32768 Hz

This is due to commit 3b03b58dab847883e6b9a431558c7d8e43fa94c6 ("OMAP4: 
hwmod data: Prevent timer1 to be reset and idle during init").  Could you 
please try reverting this and see if the warning disappears?

Tony, I guess the omap-for-linus branch will probably need to get rebuilt 
to drop that patch, once this series is merged...

- Paul

^ permalink raw reply

* [PATCH 0/6] pxa3xx_nand update series set version 5
From: Lei Wen @ 2011-02-28  2:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298019428-7809-1-git-send-email-leiwen@marvell.com>

V4:
rework the patch set accroding to Eric's suggestion.
Move the recode judgement to the after command execution.

V5:
clean code style issue.

Lei Wen (6):
  pxa3xx_nand: make scan procedure more clear
  pxa3xx_nand: rework irq logic
  pxa3xx_nand: discard wait_for_event,write_cmd,__readid function
  pxa3xx_nand: unify prepare command
  pxa3xx_nand: mtd scan id process could be defined by driver itself
  pxa3xx_nand: clean the keep configure code

 arch/arm/plat-pxa/include/plat/pxa3xx_nand.h |    2 +-
 drivers/mtd/nand/pxa3xx_nand.c               |  977 ++++++++++++--------------
 2 files changed, 458 insertions(+), 521 deletions(-)

^ permalink raw reply

* [PATCH V5 1/6] pxa3xx_nand: make scan procedure more clear
From: Lei Wen @ 2011-02-28  2:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298019428-7809-1-git-send-email-leiwen@marvell.com>

Signed-off-by: Lei Wen <leiwen@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
 drivers/mtd/nand/pxa3xx_nand.c |   99 ++++++++++++++++++++++------------------
 1 files changed, 55 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index ea2c288..f440443 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -126,6 +126,7 @@ struct pxa3xx_nand_info {
 	unsigned int 		buf_start;
 	unsigned int		buf_count;
 
+	struct mtd_info         *mtd;
 	/* DMA information */
 	int			drcmr_dat;
 	int			drcmr_cmd;
@@ -1044,34 +1045,27 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd,
 	this->chip_delay = 25;
 }
 
-static int pxa3xx_nand_probe(struct platform_device *pdev)
+static
+struct pxa3xx_nand_info *alloc_nand_resource(struct platform_device *pdev)
 {
-	struct pxa3xx_nand_platform_data *pdata;
+	struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
 	struct pxa3xx_nand_info *info;
-	struct nand_chip *this;
 	struct mtd_info *mtd;
 	struct resource *r;
-	int ret = 0, irq;
-
-	pdata = pdev->dev.platform_data;
-
-	if (!pdata) {
-		dev_err(&pdev->dev, "no platform data defined\n");
-		return -ENODEV;
-	}
+	int ret, irq;
 
 	mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct pxa3xx_nand_info),
 			GFP_KERNEL);
 	if (!mtd) {
 		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return -ENOMEM;
+		return NULL;
 	}
 
 	info = (struct pxa3xx_nand_info *)(&mtd[1]);
 	info->pdev = pdev;
 
-	this = &info->nand_chip;
 	mtd->priv = info;
+	info->mtd = mtd;
 	mtd->owner = THIS_MODULE;
 
 	info->clk = clk_get(&pdev->dev, NULL);
@@ -1149,31 +1143,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 	}
 
 	pxa3xx_nand_init_mtd(mtd, info);
+	platform_set_drvdata(pdev, info);
 
-	platform_set_drvdata(pdev, mtd);
-
-	if (nand_scan(mtd, 1)) {
-		dev_err(&pdev->dev, "failed to scan nand\n");
-		ret = -ENXIO;
-		goto fail_free_irq;
-	}
-
-#ifdef CONFIG_MTD_PARTITIONS
-	if (mtd_has_cmdlinepart()) {
-		static const char *probes[] = { "cmdlinepart", NULL };
-		struct mtd_partition *parts;
-		int nr_parts;
-
-		nr_parts = parse_mtd_partitions(mtd, probes, &parts, 0);
-
-		if (nr_parts)
-			return add_mtd_partitions(mtd, parts, nr_parts);
-	}
-
-	return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
-#else
-	return 0;
-#endif
+	return info;
 
 fail_free_irq:
 	free_irq(irq, info);
@@ -1193,13 +1165,13 @@ fail_put_clk:
 	clk_put(info->clk);
 fail_free_mtd:
 	kfree(mtd);
-	return ret;
+	return NULL;
 }
 
 static int pxa3xx_nand_remove(struct platform_device *pdev)
 {
-	struct mtd_info *mtd = platform_get_drvdata(pdev);
-	struct pxa3xx_nand_info *info = mtd->priv;
+	struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = info->mtd;
 	struct resource *r;
 	int irq;
 
@@ -1230,11 +1202,50 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int pxa3xx_nand_probe(struct platform_device *pdev)
+{
+	struct pxa3xx_nand_platform_data *pdata;
+	struct pxa3xx_nand_info *info;
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data defined\n");
+		return -ENODEV;
+	}
+
+	info = alloc_nand_resource(pdev);
+	if (info == NULL)
+		return -ENOMEM;
+
+	if (nand_scan(info->mtd, 1)) {
+		dev_err(&pdev->dev, "failed to scan nand\n");
+		pxa3xx_nand_remove(pdev);
+		return -ENODEV;
+	}
+
+#ifdef CONFIG_MTD_PARTITIONS
+	if (mtd_has_cmdlinepart()) {
+		const char *probes[] = { "cmdlinepart", NULL };
+		struct mtd_partition *parts;
+		int nr_parts;
+
+		nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0);
+
+		if (nr_parts)
+			return add_mtd_partitions(mtd, parts, nr_parts);
+	}
+
+	return add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
+#else
+	return 0;
+#endif
+}
+
 #ifdef CONFIG_PM
 static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev);
-	struct pxa3xx_nand_info *info = mtd->priv;
+	struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = info->mtd;
 
 	if (info->state != STATE_READY) {
 		dev_err(&pdev->dev, "driver busy, state = %d\n", info->state);
@@ -1246,8 +1257,8 @@ static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state)
 
 static int pxa3xx_nand_resume(struct platform_device *pdev)
 {
-	struct mtd_info *mtd = (struct mtd_info *)platform_get_drvdata(pdev);
-	struct pxa3xx_nand_info *info = mtd->priv;
+	struct pxa3xx_nand_info *info = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = info->mtd;
 
 	nand_writel(info, NDTR0CS0, info->ndtr0cs0);
 	nand_writel(info, NDTR1CS0, info->ndtr1cs0);
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V5 3/6] pxa3xx_nand: discard wait_for_event, write_cmd, __readid function
From: Lei Wen @ 2011-02-28  2:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298019428-7809-1-git-send-email-leiwen@marvell.com>

Since we have rework the irq process, we don't need additional
delay in wait_for_event. Also write_cmd and __readid is also
discarded for the same reason.

Signed-off-by: Lei Wen <leiwen@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Acked-by: Eric Miao <eric.y.miao@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
 drivers/mtd/nand/pxa3xx_nand.c |   77 +---------------------------------------
 1 files changed, 1 insertions(+), 76 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 3264b1d..be0aa44 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -258,25 +258,6 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
 	nand_writel(info, NDTR1CS0, ndtr1);
 }
 
-#define WAIT_EVENT_TIMEOUT	10
-
-static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event)
-{
-	int timeout = WAIT_EVENT_TIMEOUT;
-	uint32_t ndsr;
-
-	while (timeout--) {
-		ndsr = nand_readl(info, NDSR) & NDSR_MASK;
-		if (ndsr & event) {
-			nand_writel(info, NDSR, ndsr);
-			return 0;
-		}
-		udelay(10);
-	}
-
-	return -ETIMEDOUT;
-}
-
 static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
@@ -414,35 +395,6 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
 	nand_writel(info, NDCR, ndcr | int_mask);
 }
 
-/* NOTE: it is a must to set ND_RUN firstly, then write command buffer
- * otherwise, it does not work
- */
-static int write_cmd(struct pxa3xx_nand_info *info)
-{
-	uint32_t ndcr;
-
-	/* clear status bits and run */
-	nand_writel(info, NDSR, NDSR_MASK);
-
-	ndcr = info->reg_ndcr;
-
-	ndcr |= info->use_ecc ? NDCR_ECC_EN : 0;
-	ndcr |= info->use_dma ? NDCR_DMA_EN : 0;
-	ndcr |= NDCR_ND_RUN;
-
-	nand_writel(info, NDCR, ndcr);
-
-	if (wait_for_event(info, NDSR_WRCMDREQ)) {
-		printk(KERN_ERR "timed out writing command\n");
-		return -ETIMEDOUT;
-	}
-
-	nand_writel(info, NDCB0, info->ndcb0);
-	nand_writel(info, NDCB0, info->ndcb1);
-	nand_writel(info, NDCB0, info->ndcb2);
-	return 0;
-}
-
 static void handle_data_pio(struct pxa3xx_nand_info *info)
 {
 	switch (info->state) {
@@ -778,33 +730,6 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
 	return 0;
 }
 
-static int __readid(struct pxa3xx_nand_info *info, uint32_t *id)
-{
-	const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
-	uint32_t ndcr;
-	uint8_t  id_buff[8];
-
-	prepare_other_cmd(info, cmdset->read_id);
-
-	/* Send command */
-	if (write_cmd(info))
-		goto fail_timeout;
-
-	/* Wait for CMDDM(command done successfully) */
-	if (wait_for_event(info, NDSR_RDDREQ))
-		goto fail_timeout;
-
-	__raw_readsl(info->mmio_base + NDDB, id_buff, 2);
-	*id = id_buff[0] | (id_buff[1] << 8);
-	return 0;
-
-fail_timeout:
-	ndcr = nand_readl(info, NDCR);
-	nand_writel(info, NDCR, ndcr & ~NDCR_ND_RUN);
-	udelay(10);
-	return -ETIMEDOUT;
-}
-
 static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 				    const struct pxa3xx_nand_flash *f)
 {
@@ -857,7 +782,7 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 
 	page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
 	info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
-	/* set info fields needed to __readid */
+	/* set info fields needed to read id */
 	info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
 	info->reg_ndcr = ndcr;
 	info->cmdset = &default_cmdset;
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V5 4/6] pxa3xx_nand: unify prepare command
From: Lei Wen @ 2011-02-28  2:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298019428-7809-1-git-send-email-leiwen@marvell.com>

Make the interface simpler which could make both debug
and enhancement easier.

Signed-off-by: Lei Wen <leiwen@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
 drivers/mtd/nand/pxa3xx_nand.c |  249 ++++++++++++++++++++++------------------
 1 files changed, 139 insertions(+), 110 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index be0aa44..de0a2a2 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -28,6 +28,7 @@
 
 #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
 #define NAND_STOP_DELAY		(2 * HZ/50)
+#define PAGE_CHUNK_SIZE		(2048)
 
 /* registers and bit definitions */
 #define NDCR		(0x00) /* Control register */
@@ -77,6 +78,7 @@
 #define NDSR_RDDREQ		(0x1 << 1)
 #define NDSR_WRCMDREQ		(0x1)
 
+#define NDCB0_ST_ROW_EN         (0x1 << 26)
 #define NDCB0_AUTO_RS		(0x1 << 25)
 #define NDCB0_CSEL		(0x1 << 24)
 #define NDCB0_CMD_TYPE_MASK	(0x7 << 21)
@@ -319,66 +321,6 @@ static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info)
 	nand_writel(info, NDSR, NDSR_MASK);
 }
 
-static void prepare_read_prog_cmd(struct pxa3xx_nand_info *info,
-		uint16_t cmd, int column, int page_addr)
-{
-	const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
-	pxa3xx_set_datasize(info);
-
-	/* generate values for NDCBx registers */
-	info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
-	info->ndcb1 = 0;
-	info->ndcb2 = 0;
-	info->ndcb0 |= NDCB0_ADDR_CYC(info->row_addr_cycles + info->col_addr_cycles);
-
-	if (info->col_addr_cycles == 2) {
-		/* large block, 2 cycles for column address
-		 * row address starts from 3rd cycle
-		 */
-		info->ndcb1 |= page_addr << 16;
-		if (info->row_addr_cycles == 3)
-			info->ndcb2 = (page_addr >> 16) & 0xff;
-	} else
-		/* small block, 1 cycles for column address
-		 * row address starts from 2nd cycle
-		 */
-		info->ndcb1 = page_addr << 8;
-
-	if (cmd == cmdset->program)
-		info->ndcb0 |= NDCB0_CMD_TYPE(1) | NDCB0_AUTO_RS;
-}
-
-static void prepare_erase_cmd(struct pxa3xx_nand_info *info,
-			uint16_t cmd, int page_addr)
-{
-	info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
-	info->ndcb0 |= NDCB0_CMD_TYPE(2) | NDCB0_AUTO_RS | NDCB0_ADDR_CYC(3);
-	info->ndcb1 = page_addr;
-	info->ndcb2 = 0;
-}
-
-static void prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd)
-{
-	const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
-
-	info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
-	info->ndcb1 = 0;
-	info->ndcb2 = 0;
-
-	info->oob_size = 0;
-	if (cmd == cmdset->read_id) {
-		info->ndcb0 |= NDCB0_CMD_TYPE(3) | NDCB0_ADDR_CYC(1);
-		info->data_size = 8;
-	} else if (cmd == cmdset->read_status) {
-		info->ndcb0 |= NDCB0_CMD_TYPE(4);
-		info->data_size = 8;
-	} else if (cmd == cmdset->reset || cmd == cmdset->lock ||
-		   cmd == cmdset->unlock) {
-		info->ndcb0 |= NDCB0_CMD_TYPE(5);
-	} else
-		BUG();
-}
-
 static void enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
 {
 	uint32_t ndcr;
@@ -529,81 +471,167 @@ static inline int is_buf_blank(uint8_t *buf, size_t len)
 	return 1;
 }
 
-static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
-				int column, int page_addr)
+static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
+		uint16_t column, int page_addr)
 {
-	struct pxa3xx_nand_info *info = mtd->priv;
-	const struct pxa3xx_nand_cmdset *cmdset = info->cmdset;
-	int ret, exec_cmd = 0;
+	uint16_t cmd;
+	int addr_cycle, exec_cmd, ndcb0;
+	struct mtd_info *mtd = info->mtd;
+
+	ndcb0 = 0;
+	addr_cycle = 0;
+	exec_cmd = 1;
 
-	info->use_dma = (use_dma) ? 1 : 0;
-	info->use_ecc = 0;
-	info->data_size = 0;
-	info->state = 0;
-	info->retcode = ERR_NONE;
+	/* reset data and oob column point to handle data */
+	info->buf_start	= 0;
+	info->buf_count	= 0;
+	info->oob_size		= 0;
+	info->use_ecc		= 0;
+	info->retcode		= ERR_NONE;
 
 	switch (command) {
+	case NAND_CMD_READ0:
+	case NAND_CMD_PAGEPROG:
+		info->use_ecc = 1;
 	case NAND_CMD_READOOB:
-		/* disable HW ECC to get all the OOB data */
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		info->buf_start = mtd->writesize + column;
-		memset(info->data_buff, 0xFF, info->buf_count);
-
-		prepare_read_prog_cmd(info, cmdset->read1, column, page_addr);
-		exec_cmd = 1;
+		pxa3xx_set_datasize(info);
+		break;
+	case NAND_CMD_SEQIN:
+		exec_cmd = 0;
+		break;
+	default:
+		info->ndcb1 = 0;
+		info->ndcb2 = 0;
 		break;
+	}
+
+	info->ndcb0 = ndcb0;
+	addr_cycle = NDCB0_ADDR_CYC(info->row_addr_cycles
+				    + info->col_addr_cycles);
 
+	switch (command) {
+	case NAND_CMD_READOOB:
 	case NAND_CMD_READ0:
-		info->use_ecc = 1;
-		info->buf_start = column;
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xFF, info->buf_count);
+		cmd = info->cmdset->read1;
+		if (command == NAND_CMD_READOOB)
+			info->buf_start = mtd->writesize + column;
+		else
+			info->buf_start = column;
+
+		if (unlikely(info->page_size < PAGE_CHUNK_SIZE))
+			info->ndcb0 |= NDCB0_CMD_TYPE(0)
+					| addr_cycle
+					| (cmd & NDCB0_CMD1_MASK);
+		else
+			info->ndcb0 |= NDCB0_CMD_TYPE(0)
+					| NDCB0_DBC
+					| addr_cycle
+					| cmd;
 
-		prepare_read_prog_cmd(info, cmdset->read1, column, page_addr);
-		exec_cmd = 1;
-		break;
 	case NAND_CMD_SEQIN:
-		info->buf_start = column;
+		/* small page addr setting */
+		if (unlikely(info->page_size < PAGE_CHUNK_SIZE)) {
+			info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
+					| (column & 0xFF);
+
+			info->ndcb2 = 0;
+		} else {
+			info->ndcb1 = ((page_addr & 0xFFFF) << 16)
+					| (column & 0xFFFF);
+
+			if (page_addr & 0xFF0000)
+				info->ndcb2 = (page_addr & 0xFF0000) >> 16;
+			else
+				info->ndcb2 = 0;
+		}
+
 		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xff, info->buf_count);
+		memset(info->data_buff, 0xFF, info->buf_count);
 
-		/* save column/page_addr for next CMD_PAGEPROG */
-		info->seqin_column = column;
-		info->seqin_page_addr = page_addr;
 		break;
+
 	case NAND_CMD_PAGEPROG:
-		info->use_ecc = (info->seqin_column >= mtd->writesize) ? 0 : 1;
+		if (is_buf_blank(info->data_buff,
+					(mtd->writesize + mtd->oobsize))) {
+			exec_cmd = 0;
+			break;
+		}
 
-		prepare_read_prog_cmd(info, cmdset->program,
-				info->seqin_column, info->seqin_page_addr);
-		exec_cmd = 1;
-		break;
-	case NAND_CMD_ERASE1:
-		prepare_erase_cmd(info, cmdset->erase, page_addr);
-		exec_cmd = 1;
-		break;
-	case NAND_CMD_ERASE2:
+		cmd = info->cmdset->program;
+		info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+				| NDCB0_AUTO_RS
+				| NDCB0_ST_ROW_EN
+				| NDCB0_DBC
+				| cmd
+				| addr_cycle;
 		break;
+
 	case NAND_CMD_READID:
+		cmd = info->cmdset->read_id;
+		info->buf_count = info->read_id_bytes;
+		info->ndcb0 |= NDCB0_CMD_TYPE(3)
+				| NDCB0_ADDR_CYC(1)
+				| cmd;
+
+		info->data_size = 8;
+		break;
 	case NAND_CMD_STATUS:
-		info->use_dma = 0;	/* force PIO read */
-		info->buf_start = 0;
-		info->buf_count = (command == NAND_CMD_READID) ?
-				info->read_id_bytes : 1;
-
-		prepare_other_cmd(info, (command == NAND_CMD_READID) ?
-				cmdset->read_id : cmdset->read_status);
-		exec_cmd = 1;
+		cmd = info->cmdset->read_status;
+		info->buf_count = 1;
+		info->ndcb0 |= NDCB0_CMD_TYPE(4)
+				| NDCB0_ADDR_CYC(1)
+				| cmd;
+
+		info->data_size = 8;
+		break;
+
+	case NAND_CMD_ERASE1:
+		cmd = info->cmdset->erase;
+		info->ndcb0 |= NDCB0_CMD_TYPE(2)
+				| NDCB0_AUTO_RS
+				| NDCB0_ADDR_CYC(3)
+				| NDCB0_DBC
+				| cmd;
+		info->ndcb1 = page_addr;
+		info->ndcb2 = 0;
+
 		break;
 	case NAND_CMD_RESET:
-		prepare_other_cmd(info, cmdset->reset);
-		exec_cmd = 1;
+		cmd = info->cmdset->reset;
+		info->ndcb0 |= NDCB0_CMD_TYPE(5)
+				| cmd;
+
+		break;
+
+	case NAND_CMD_ERASE2:
+		exec_cmd = 0;
 		break;
+
 	default:
-		printk(KERN_ERR "non-supported command.\n");
+		exec_cmd = 0;
+		printk(KERN_ERR "pxa3xx-nand: non-supported"
+			" command %x\n", command);
 		break;
 	}
 
+	return exec_cmd;
+}
+
+static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
+				int column, int page_addr)
+{
+	struct pxa3xx_nand_info *info = mtd->priv;
+	int ret, exec_cmd;
+
+	/*
+	 * if this is a x16 device ,then convert the input
+	 * "byte" address into a "word" address appropriate
+	 * for indexing a word-oriented device
+	 */
+	if (info->reg_ndcr & NDCR_DWIDTH_M)
+		column /= 2;
+
+	exec_cmd = prepare_command_pool(info, command, column, page_addr);
 	if (exec_cmd) {
 		init_completion(&info->cmd_complete);
 		pxa3xx_nand_start(info);
@@ -919,6 +947,7 @@ static void pxa3xx_nand_init_mtd(struct mtd_info *mtd,
 	struct nand_chip *this = &info->nand_chip;
 
 	this->options = (info->reg_ndcr & NDCR_DWIDTH_C) ? NAND_BUSWIDTH_16: 0;
+	this->options |= NAND_NO_AUTOINCR;
 
 	this->waitfunc		= pxa3xx_nand_waitfunc;
 	this->select_chip	= pxa3xx_nand_select_chip;
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH V5 6/6] pxa3xx_nand: clean the keep configure code
From: Lei Wen @ 2011-02-28  2:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298019428-7809-1-git-send-email-leiwen@marvell.com>

Signed-off-by: Lei Wen <leiwen@marvell.com>
Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Cc: Eric Miao <eric.y.miao@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
 arch/arm/plat-pxa/include/plat/pxa3xx_nand.h |    2 +-
 drivers/mtd/nand/pxa3xx_nand.c               |  103 +++++++++-----------------
 2 files changed, 36 insertions(+), 69 deletions(-)

diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
index 01a8448..442301f 100644
--- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
+++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h
@@ -30,6 +30,7 @@ struct pxa3xx_nand_cmdset {
 };
 
 struct pxa3xx_nand_flash {
+	char		*name;
 	uint32_t	chip_id;
 	unsigned int	page_per_block; /* Pages per block (PG_PER_BLK) */
 	unsigned int	page_size;	/* Page size in bytes (PAGE_SZ) */
@@ -37,7 +38,6 @@ struct pxa3xx_nand_flash {
 	unsigned int	dfc_width;	/* Width of flash controller(DWIDTH_C) */
 	unsigned int	num_blocks;	/* Number of physical blocks in Flash */
 
-	struct pxa3xx_nand_cmdset *cmdset;	/* NAND command set */
 	struct pxa3xx_nand_timing *timing;	/* NAND Flash timing */
 };
 
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index bb50cf2..ab7f4c3 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -211,15 +211,15 @@ static struct pxa3xx_nand_timing timing[] = {
 };
 
 static struct pxa3xx_nand_flash builtin_flash_types[] = {
-	{      0,   0, 2048,  8,  8,    0, &default_cmdset, &timing[0] },
-	{ 0x46ec,  32,  512, 16, 16, 4096, &default_cmdset, &timing[1] },
-	{ 0xdaec,  64, 2048,  8,  8, 2048, &default_cmdset, &timing[1] },
-	{ 0xd7ec, 128, 4096,  8,  8, 8192, &default_cmdset, &timing[1] },
-	{ 0xa12c,  64, 2048,  8,  8, 1024, &default_cmdset, &timing[2] },
-	{ 0xb12c,  64, 2048, 16, 16, 1024, &default_cmdset, &timing[2] },
-	{ 0xdc2c,  64, 2048,  8,  8, 4096, &default_cmdset, &timing[2] },
-	{ 0xcc2c,  64, 2048, 16, 16, 4096, &default_cmdset, &timing[2] },
-	{ 0xba20,  64, 2048, 16, 16, 2048, &default_cmdset, &timing[3] },
+{ "DEFAULT FLASH",      0,   0, 2048,  8,  8,    0, &timing[0] },
+{ "64MiB 16-bit",  0x46ec,  32,  512, 16, 16, 4096, &timing[1] },
+{ "256MiB 8-bit",  0xdaec,  64, 2048,  8,  8, 2048, &timing[1] },
+{ "4GiB 8-bit",    0xd7ec, 128, 4096,  8,  8, 8192, &timing[1] },
+{ "128MiB 8-bit",  0xa12c,  64, 2048,  8,  8, 1024, &timing[2] },
+{ "128MiB 16-bit", 0xb12c,  64, 2048, 16, 16, 1024, &timing[2] },
+{ "512MiB 8-bit",  0xdc2c,  64, 2048,  8,  8, 4096, &timing[2] },
+{ "512MiB 16-bit", 0xcc2c,  64, 2048, 16, 16, 4096, &timing[2] },
+{ "256MiB 16-bit", 0xba20,  64, 2048, 16, 16, 2048, &timing[3] },
 };
 
 /* Define a default flash type setting serve as flash detecting only */
@@ -779,9 +779,8 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 		return -EINVAL;
 
 	/* calculate flash information */
-	info->cmdset = f->cmdset;
+	info->cmdset = &default_cmdset;
 	info->page_size = f->page_size;
-	info->oob_buff = info->data_buff + f->page_size;
 	info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
 	/* calculate addressing information */
@@ -811,45 +810,12 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 {
 	uint32_t ndcr = nand_readl(info, NDCR);
-	struct nand_flash_dev *type = NULL;
-	uint32_t id = -1, page_per_block, num_blocks;
-	int i;
-
-	page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
 	info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
 	/* set info fields needed to read id */
 	info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
 	info->reg_ndcr = ndcr;
 	info->cmdset = &default_cmdset;
 
-	pxa3xx_nand_cmdfunc(info->mtd, NAND_CMD_READID, 0, 0);
-	id = *((uint16_t *)(info->data_buff));
-	if (id == 0)
-		return -ENODEV;
-
-	/* Lookup the flash id */
-	for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-		if (id == nand_flash_ids[i].id) {
-			type =  &nand_flash_ids[i];
-			break;
-		}
-	}
-
-	if (!type)
-		return -ENODEV;
-
-	/* fill the missing flash information */
-	i = __ffs(page_per_block * info->page_size);
-	num_blocks = type->chipsize << (20 - i);
-
-	/* calculate addressing information */
-	info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1;
-
-	if (num_blocks * page_per_block > 65536)
-		info->row_addr_cycles = 3;
-	else
-		info->row_addr_cycles = 2;
-
 	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
 	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
 
@@ -916,13 +882,15 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
 	struct pxa3xx_nand_info *info = mtd->priv;
 	struct platform_device *pdev = info->pdev;
 	struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
+	struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} };
 	const struct pxa3xx_nand_flash *f = NULL;
 	struct nand_chip *chip = mtd->priv;
 	uint32_t id = -1;
+	uint64_t chipsize;
 	int i, ret, num;
 
 	if (pdata->keep_config && !pxa3xx_nand_detect_config(info))
-		return 0;
+		goto KEEP_CONFIG;
 
 	ret = pxa3xx_nand_sensing(info);
 	if (!ret) {
@@ -953,22 +921,11 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
 			f = &builtin_flash_types[i - pdata->num_flash + 1];
 
 		/* find the chip in default list */
-		if (f->chip_id == id) {
-			pxa3xx_nand_config_flash(info, f);
-			mtd->writesize = f->page_size;
-			mtd->writesize_shift = ffs(mtd->writesize) - 1;
-			mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
-			mtd->oobsize = mtd->writesize / 32;
-			mtd->erasesize = f->page_size * f->page_per_block;
-			mtd->erasesize_shift = ffs(mtd->erasesize) - 1;
-			mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
-
-			mtd->name = mtd_names[0];
+		if (f->chip_id == id)
 			break;
-		}
 	}
 
-	if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash)) {
+	if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) {
 		kfree(mtd);
 		info->mtd = NULL;
 		printk(KERN_ERR "ERROR!! flash not defined!!!\n");
@@ -976,18 +933,28 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
 		return -EINVAL;
 	}
 
+	pxa3xx_nand_config_flash(info, f);
+	pxa3xx_flash_ids[0].name = f->name;
+	pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff;
+	pxa3xx_flash_ids[0].pagesize = f->page_size;
+	chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size;
+	pxa3xx_flash_ids[0].chipsize = chipsize >> 20;
+	pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block;
+	if (f->flash_width == 16)
+		pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16;
+KEEP_CONFIG:
+	if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids))
+		return -ENODEV;
+	/* calculate addressing information */
+	info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1;
+	info->oob_buff = info->data_buff + mtd->writesize;
+	if ((mtd->size >> chip->page_shift) > 65536)
+		info->row_addr_cycles = 3;
+	else
+		info->row_addr_cycles = 2;
+	mtd->name = mtd_names[0];
 	chip->ecc.mode = NAND_ECC_HW;
 	chip->ecc.size = f->page_size;
-	chip->chipsize = (uint64_t)f->num_blocks * f->page_per_block
-				    * f->page_size;
-	mtd->size = chip->chipsize;
-
-	/* Calculate the address shift from the page size */
-	chip->page_shift = ffs(mtd->writesize) - 1;
-	chip->pagemask = mtd_div_by_ws(chip->chipsize, mtd) - 1;
-	chip->numchips = 1;
-	chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
-	chip->bbt_erase_shift = chip->phys_erase_shift;
 
 	chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0;
 	chip->options |= NAND_NO_AUTOINCR;
-- 
1.7.0.4

^ permalink raw reply related

* [PATCH 1/2] ARM: l2x0: Errata fix for flush by Way operationcan cause data corruption
From: Santosh Shilimkar @ 2011-02-28  3:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110227120021.GA15314@n2100.arm.linux.org.uk>

> -----Original Message-----
> From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> Sent: Sunday, February 27, 2011 5:30 PM
> To: Santosh Shilimkar
> Cc: linux-arm-kernel at lists.infradead.org; tony at atomide.com;
> catalin.marinas at arm.com; linux-omap at vger.kernel.org
> Subject: Re: [PATCH 1/2] ARM: l2x0: Errata fix for flush by Way
> operationcan cause data corruption
>
> On Fri, Feb 18, 2011 at 06:05:24PM +0530, Santosh Shilimkar wrote:

[...]

>
> > @@ -329,6 +330,7 @@ void __init l2x0_init(void __iomem *base,
> __u32 aux_val, __u32 aux_mask)
> >  	outer_cache.flush_all = l2x0_flush_all;
> >  	outer_cache.inv_all = l2x0_inv_all;
> >  	outer_cache.disable = l2x0_disable;
> > +	outer_cache.set_debug = NULL;
>
> 	outer_cache.set_debug = l2x0_set_debug;
>
> may result in more efficient code as we're avoiding having to test
> the value of outer_cache.set_debug each time we want to call it and
> branch appropriately.

Ok. Will do the necessary change and submit it to patch System

Regards,
Santosh

^ permalink raw reply

* [PATCH v5 1/2] PRUSS UIO driver support
From: TK, Pratheesh Gangadhar @ 2011-02-28  4:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1102251049090.2701@localhost6.localdomain6>

Hi,

> -----Original Message-----
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: Friday, February 25, 2011 3:24 PM
> To: TK, Pratheesh Gangadhar
> Cc: davinci-linux-open-source at linux.davincidsp.com; hjk at hansjkoch.de;
> gregkh at suse.de; sshtylyov at mvista.com; arnd at arndb.de; Chatterjee, Amit;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v5 1/2] PRUSS UIO driver support
> 
> On Fri, 25 Feb 2011, Pratheesh Gangadhar wrote:
> > +static irqreturn_t pruss_handler(int irq, struct uio_info *dev_info)
> > +{
> > +	void __iomem *base = dev_info->mem[0].internal_addr;
> > +	void __iomem *intren_reg = base + PINTC_HIER;
> > +	void __iomem *intrstat_reg = base + PINTC_HIPIR + ((irq - 1) << 2);
> > +	int val = ioread32(intren_reg), intr_mask = (1 << (irq - 1));
> > +
> > +	/* Is interrupt enabled and active ? */
> > +	if (!(val & intr_mask) && (ioread32(intrstat_reg) & HIPIR_NOPEND))
> > +		return IRQ_NONE;
> > +
> > +	/* Disable interrupt */
> > +	iowrite32((val & ~intr_mask), intren_reg);
> > +	return IRQ_HANDLED;
> > +}
> 
> Hmm, just noticed, that you fiddle with the interrupt enable register
> here totally unprotected. So on a SMP system you might haandle two
> different interrupts at the same time. That wants locking.
> 
> And even on UP, you have a problem as you reenable that thing from
> user space which requires a read modify write. Racy as hell.
> 
> Please look at the other UIO drivers which have the same problem.
> Sorry for not noticing earlier!

Thanks for pointing this out. Yes - this is a problem especially since we have more than one interrupt for PRUSS which is enabled/disabled in this register. I will fix this and resubmit along with fixes addressing Sergei's comments on platform specific portion.

Thanks,
Pratheesh

^ permalink raw reply

* [PATCH 6/6] ARM: S5PV210: Add PWM backlight support on SMDKV210
From: Kyungmin Park @ 2011-02-28  4:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298694546-16816-7-git-send-email-banajit.g@samsung.com>

Hi,

On Sat, Feb 26, 2011 at 1:29 PM, Banajit Goswami <banajit.g@samsung.com> wrote:
> This patch adds support for LCD backlight control using PWM timer
> for Samsung's SMDKV210 board.
>
> Signed-off-by: Banajit Goswami <banajit.g@samsung.com>
> ---
> ?arch/arm/mach-s5pv210/Kconfig ? ? ? ? | ? ?1 +
> ?arch/arm/mach-s5pv210/mach-smdkv210.c | ? 46 +++++++++++++++++++++++++++++++++
> ?2 files changed, 47 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
> index 53aabef..d7fd031 100644
> --- a/arch/arm/mach-s5pv210/Kconfig
> +++ b/arch/arm/mach-s5pv210/Kconfig
> @@ -130,6 +130,7 @@ config MACH_SMDKV210
> ? ? ? ?select SAMSUNG_DEV_ADC
> ? ? ? ?select SAMSUNG_DEV_IDE
> ? ? ? ?select SAMSUNG_DEV_KEYPAD
> + ? ? ? select SAMSUNG_DEV_PWM
> ? ? ? ?select SAMSUNG_DEV_TS
> ? ? ? ?select S5PV210_SETUP_FB_24BPP
> ? ? ? ?select S5PV210_SETUP_I2C1
> diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
> index bc9fdb5..8833e7b 100644
> --- a/arch/arm/mach-s5pv210/mach-smdkv210.c
> +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
> @@ -18,6 +18,7 @@
> ?#include <linux/fb.h>
> ?#include <linux/gpio.h>
> ?#include <linux/delay.h>
> +#include <linux/pwm_backlight.h>
>
> ?#include <asm/mach/arch.h>
> ?#include <asm/mach/map.h>
> @@ -43,6 +44,7 @@
> ?#include <plat/keypad.h>
> ?#include <plat/pm.h>
> ?#include <plat/fb.h>
> +#include <plat/gpio-cfg.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define SMDKV210_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -208,6 +210,45 @@ static struct s3c_fb_platdata smdkv210_lcd0_pdata __initdata = {
> ? ? ? ?.setup_gpio ? ? = s5pv210_fb_gpio_setup_24bpp,
> ?};
>
> +static int smdkv210_backlight_init(struct device *dev)
> +{
> + ? ? ? int ret;
> +
> + ? ? ? ret = gpio_request(S5PV210_GPD0(3), "Backlight");
> + ? ? ? if (ret) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "failed to request GPD for PWM-OUT 3\n");
> + ? ? ? ? ? ? ? return ret;
> + ? ? ? }
> +
> + ? ? ? /* Configure GPIO pin with S5PV210_GPD_0_3_TOUT_3 */
> + ? ? ? s3c_gpio_cfgpin(S5PV210_GPD0(3), (0x2 << 12));

what's (0x2 << 12)? Do you mean S3C_GPIO_SFN(2)?
please use the macro and other patches are same usage.

> +
> + ? ? ? return 0;
> +}
> +
> +static void smdkv210_backlight_exit(struct device *dev)
> +{
> + ? ? ? s3c_gpio_cfgpin(S5PV210_GPD0(3), S3C_GPIO_OUTPUT);
> + ? ? ? gpio_free(S5PV210_GPD0(3));
> +}
> +
> +static struct platform_pwm_backlight_data smdkv210_backlight_data = {
> + ? ? ? .pwm_id ? ? ? ? = 3,
> + ? ? ? .max_brightness = 255,
> + ? ? ? .dft_brightness = 255,
> + ? ? ? .pwm_period_ns ?= 78770,
> + ? ? ? .init ? ? ? ? ? = smdkv210_backlight_init,
> + ? ? ? .exit ? ? ? ? ? = smdkv210_backlight_exit,
> +};
> +
> +static struct platform_device smdkv210_backlight_device = {
> + ? ? ? .name ? ? ? ? ? = "pwm-backlight",
> + ? ? ? .dev ? ? ? ? ? ?= {
> + ? ? ? ? ? ? ? .parent ? ? ? ? = &s3c_device_timer[3].dev,
> + ? ? ? ? ? ? ? .platform_data ?= &smdkv210_backlight_data,
> + ? ? ? },
> +};
> +
> ?static struct platform_device *smdkv210_devices[] __initdata = {
> ? ? ? ?&s3c_device_adc,
> ? ? ? ?&s3c_device_cfcon,
> @@ -229,6 +270,11 @@ static struct platform_device *smdkv210_devices[] __initdata = {
> ? ? ? ?&samsung_device_keypad,
> ? ? ? ?&smdkv210_dm9000,
> ? ? ? ?&smdkv210_lcd_lte480wv,
> + ? ? ? &s3c_device_timer[0],
> + ? ? ? &s3c_device_timer[1],
> + ? ? ? &s3c_device_timer[2],
> + ? ? ? &s3c_device_timer[3],

Why do you register timer[0...2] at here? it's only use the timer[3]
at this patch.
Other patches are same usage.

Thank you,
Kyungmin Park

> + ? ? ? &smdkv210_backlight_device,
> ?};
>
> ?static void __init smdkv210_dm9000_init(void)
> --
> 1.6.5.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH v4 2/2] Defines DA850/AM18xx/OMAPL1-38 SOC resources used by PRUSS UIO driver
From: TK, Pratheesh Gangadhar @ 2011-02-28  4:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4D6796D6.5050008@mvista.com>

Hi,

> -----Original Message-----
> From: Sergei Shtylyov [mailto:sshtylyov at mvista.com]
> Sent: Friday, February 25, 2011 5:18 PM
> To: TK, Pratheesh Gangadhar
> Cc: davinci-linux-open-source at linux.davincidsp.com; hjk at hansjkoch.de;
> gregkh at suse.de; tglx at linutronix.de; arnd at arndb.de; Chatterjee, Amit;
> linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v4 2/2] Defines DA850/AM18xx/OMAPL1-38 SOC resources
> used by PRUSS UIO driver
> 
> On 24-02-2011 17:06, Pratheesh Gangadhar wrote:
> 
> > This patch defines PRUSS, ECAP clocks, memory and IRQ resources
> > used by PRUSS UIO driver in DA850/AM18xx/OMAPL1-38 devices. UIO
> 
>     It's OMAP-L138.
Ok.
> 
> > driver exports 64K I/O region of PRUSS, 128KB L3 RAM and 256KB
> > DDR buffer to user space. PRUSS has 8 host event interrupt lines
> > mapped to IRQ_DA8XX_EVTOUT0..7 of ARM9 INTC.These in conjunction
> > with shared memory can be used to implement IPC between ARM9 and
> > PRUSS.
> 
> > Signed-off-by: Pratheesh Gangadhar<pratheesh@ti.com>
> [...]
> 
> > diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-
> davinci/board-da850-evm.c
> > index 11f986b..bd85aa3 100644
> > --- a/arch/arm/mach-davinci/board-da850-evm.c
> > +++ b/arch/arm/mach-davinci/board-da850-evm.c
> > @@ -1077,6 +1077,10 @@ static __init void da850_evm_init(void)
> >   		pr_warning("da850_evm_init: i2c0 registration failed: %d\n",
> >   				ret);
> >
> > +	ret = da8xx_register_pruss();
> > +	if (ret)
> > +		pr_warning("da850_evm_init: pruss registration failed: %d\n",
> > +				ret);
> 
>     Use __func__ to print the function name.
> 
> >
> >   	ret = da8xx_register_watchdog();
> >   	if (ret)
> 
>     As I said, please put this into serpate patch.
> 
Ok, will do.
> > diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-
> davinci/da850.c
> > index 3443d97..0096d4f 100644
> > --- a/arch/arm/mach-davinci/da850.c
> > +++ b/arch/arm/mach-davinci/da850.c
> > @@ -238,6 +238,13 @@ static struct clk tptc2_clk = {
> >   	.flags		= ALWAYS_ENABLED,
> >   };
> >
> > +static struct clk pruss_clk = {
> > +	.name		= "pruss",
> > +	.parent		= &pll0_sysclk2,
> > +	.lpsc		= DA8XX_LPSC0_DMAX,
> > +	.flags		= ALWAYS_ENABLED,
> > +};
> > +
> 
>     This conflicts with previously posted patch.
> 
Ok, shall I rename to align with previous patch from Mistral or drop this from my patchset ?
> >   static struct clk uart0_clk = {
> >   	.name		= "uart0",
> >   	.parent		=&pll0_sysclk2,
> > @@ -359,6 +366,30 @@ static struct clk usb20_clk = {
> >   	.gpsc		= 1,
> >   };
> >
> > +static struct clk ecap0_clk = {
> > +	.name		= "ecap0",
> > +	.parent		= &pll0_sysclk2,
> > +	.lpsc		= DA8XX_LPSC1_ECAP,
> > +	.flags		= DA850_CLK_ASYNC3,
> > +	.gpsc		= 1,
> > +};
> > +
> > +static struct clk ecap1_clk = {
> > +	.name		= "ecap1",
> > +	.parent		= &pll0_sysclk2,
> > +	.lpsc		= DA8XX_LPSC1_ECAP,
> > +	.flags		= DA850_CLK_ASYNC3,
> > +	.gpsc		= 1,
> > +};
> > +
> > +static struct clk ecap2_clk = {
> > +	.name		= "ecap2",
> > +	.parent		= &pll0_sysclk2,
> > +	.lpsc		= DA8XX_LPSC1_ECAP,
> > +	.flags		= DA850_CLK_ASYNC3,
> > +	.gpsc		= 1,
> > +};
> > +
> 
>     This is worth separate patch too...
> 
Ok.
> > diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-
> davinci/devices-da8xx.c
> > index beda8a4..4ea3d1f 100644
> > --- a/arch/arm/mach-davinci/devices-da8xx.c
> > +++ b/arch/arm/mach-davinci/devices-da8xx.c
> > @@ -725,3 +725,76 @@ int __init da8xx_register_cpuidle(void)
> >
> >   	return platform_device_register(&da8xx_cpuidle_device);
> >   }
> > +static struct resource pruss_resources[] = {
> > +	[0] = {
> > +		.start  = DA8XX_PRUSS_BASE,
> > +		.end    = DA8XX_PRUSS_BASE + SZ_64K - 1,
> > +		.flags  = IORESOURCE_MEM,
> > +	},
> > +	[1] = {
> > +		.start  = DA8XX_L3RAM_BASE,
> > +		.end    = DA8XX_L3RAM_BASE + SZ_128K - 1,
> > +		.flags  = IORESOURCE_MEM,
> > +	},
> > +	[2] = {
> > +		.start  = 0,
> > +		.end    = SZ_256K - 1,
> 
>     Huh? I don't see where it's filled...
> 
The current use is only to indicate memory block size to the PRUSS UIO driver when we allocate DDR memory using dma_alloc_coherent. sram_alloc is changed to use L3_RAM (128KB) instead of ARM RAM (8KB) in Mistral patch set - I need to follow the same convention for L3 RAM as well if I need to align with that patch. Is there a better way to do this?
> > +		.flags  = IORESOURCE_MEM,
> > +	},
> > +
> [...]
> > +int __init da8xx_register_pruss()
> > +{
> > +	return platform_device_register(&pruss_device);
> > +}
> > diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-
> davinci/include/mach/da8xx.h
> > index cfcb223..3ed6ee0 100644
> > --- a/arch/arm/mach-davinci/include/mach/da8xx.h
> > +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
> > @@ -60,6 +60,7 @@ extern unsigned int da850_max_speed;
> >   #define DA8XX_PLL0_BASE		0x01c11000
> >   #define DA8XX_TIMER64P0_BASE	0x01c20000
> >   #define DA8XX_TIMER64P1_BASE	0x01c21000
> > +#define DA8XX_PRUSS_BASE	0x01c30000
> >   #define DA8XX_GPIO_BASE		0x01e26000
> >   #define DA8XX_PSC1_BASE		0x01e27000
> >   #define DA8XX_LCD_CNTRL_BASE	0x01e13000
> > @@ -68,6 +69,7 @@ extern unsigned int da850_max_speed;
> >   #define DA8XX_AEMIF_CS2_BASE	0x60000000
> >   #define DA8XX_AEMIF_CS3_BASE	0x62000000
> >   #define DA8XX_AEMIF_CTL_BASE	0x68000000
> > +#define DA8XX_L3RAM_BASE	0x80000000
> 
>     There were already patches defining macros for these base addresses...
>
Ok - will align with this.

Thanks,
Pratheesh

^ permalink raw reply

* [PATCH 1/3] ARM: EXYNOS4: Add SYSTIMER IO Address mapping for MCT
From: Kukjin Kim @ 2011-02-28  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Changhwan Youn <chaos.youn@samsung.com>

The MCT(Multi-Core Timer) is used for implementing kernel timers for
EXYNOS4210.

Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/cpu.c              |    5 +++++
 arch/arm/mach-exynos4/include/mach/map.h |    1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c
index b0ec6d3..479dfa1 100644
--- a/arch/arm/mach-exynos4/cpu.c
+++ b/arch/arm/mach-exynos4/cpu.c
@@ -31,6 +31,11 @@ extern void combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq);
 /* Initial IO mappings */
 static struct map_desc exynos4_iodesc[] __initdata = {
 	{
+		.virtual	= (unsigned long)S5P_VA_SYSTIMER,
+		.pfn		= __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
+		.length		= SZ_4K,
+		.type	 	= MT_DEVICE,
+	}, {
 		.virtual	= (unsigned long)S5P_VA_SYSRAM,
 		.pfn		= __phys_to_pfn(EXYNOS4_PA_SYSRAM),
 		.length		= SZ_4K,
diff --git a/arch/arm/mach-exynos4/include/mach/map.h b/arch/arm/mach-exynos4/include/mach/map.h
index 80a41e0..d678f08 100644
--- a/arch/arm/mach-exynos4/include/mach/map.h
+++ b/arch/arm/mach-exynos4/include/mach/map.h
@@ -44,6 +44,7 @@
 #define EXYNOS4_PA_PMU			0x10020000
 #define EXYNOS4_PA_CMU			0x10030000
 
+#define EXYNOS4_PA_SYSTIMER		0x10050000
 #define EXYNOS4_PA_WATCHDOG		0x10060000
 #define EXYNOS4_PA_RTC			0x10070000
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH 2/3] ARM: EXYNOS4: Add irq definition for kernel global timer
From: Kukjin Kim @ 2011-02-28  5:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298870207-1850-1-git-send-email-kgene.kim@samsung.com>

From: Changhwan Youn <chaos.youn@samsung.com>

This patch adds IRQ_MCT_G0 to irq map. IRQ_MCT_G0 is an interrupt of MCT
comparator and used for kernel global timer.

Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
 arch/arm/mach-exynos4/include/mach/irqs.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-exynos4/include/mach/irqs.h b/arch/arm/mach-exynos4/include/mach/irqs.h
index 2dc5900..e3556d4 100644
--- a/arch/arm/mach-exynos4/include/mach/irqs.h
+++ b/arch/arm/mach-exynos4/include/mach/irqs.h
@@ -131,6 +131,7 @@
 #define IRQ_MCT_L0		COMBINER_IRQ(51, 0)
 
 #define IRQ_WDT			COMBINER_IRQ(53, 0)
+#define IRQ_MCT_G0		COMBINER_IRQ(53, 4)
 
 #define MAX_COMBINER_NR		54
 
-- 
1.7.1

^ permalink raw reply related

* [PATCH V4] ARM: EXYNOS4: Implement kernel timers using MCT
From: Kukjin Kim @ 2011-02-28  5:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298870207-1850-1-git-send-email-kgene.kim@samsung.com>

From: Changhwan Youn <chaos.youn@samsung.com>

The Multi-Core Timer(MCT) of EXYNOS4 is designed for implementing
clock source timer and clock event timers. This patch implements
1 clock source timer with 64 bit free running counter of MCT and
2 clock event timers with two of 31-bit tick counters.

Signed-off-by: Changhwan Youn <chaos.youn@samsung.com>
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
---
Changes since v3:
- Re-worked based on exynos4
- Changed member of clock_evetn_device like following
  struct mct_clock_event_device {
	struct clock_event_device *evt;
  ...
- Address comments from Russell King
  Added static into "irqreturn_t exynos4_mct_comp_isr()"
  Added .dev_id member into "struct irqaction mct_comp_event_irq"

Changes since v2:
- Addressed comments from Russell King
  Added mct_clock_event_device structure
- Removed suspend()/resume() which are not used now

Changes since v1:
- Addressed comments from Russell King
  (implemented global timer, used local timer and so on)
- Fixed small things

 arch/arm/Kconfig                              |    2 +-
 arch/arm/mach-exynos4/Kconfig                 |    5 +
 arch/arm/mach-exynos4/Makefile                |   11 +-
 arch/arm/mach-exynos4/include/mach/regs-mct.h |   52 +++
 arch/arm/mach-exynos4/mct.c                   |  421 +++++++++++++++++++++++++
 5 files changed, 488 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/mach-exynos4/include/mach/regs-mct.h
 create mode 100644 arch/arm/mach-exynos4/mct.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ec3bf98..b4db99b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1366,7 +1366,7 @@ config LOCAL_TIMERS
 	bool "Use local timer interrupts"
 	depends on SMP
 	default y
-	select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP
+	select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index ad03840..77b5d93 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -15,6 +15,11 @@ config CPU_EXYNOS4210
 	help
 	  Enable EXYNOS4210 CPU support
 
+config EXYNOS4_MCT
+	bool "Kernel timer support by MCT"
+	help
+	  Use MCT (Multi Core Timer) as kernel timers
+
 config EXYNOS4_DEV_PD
 	bool
 	help
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 0558235..de20b91 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -13,11 +13,18 @@ obj-				:=
 # Core support for EXYNOS4 system
 
 obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o gpiolib.o irq-eint.o dma.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq.o
 
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
-obj-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
+
+ifeq ($(CONFIG_EXYNOS4_MCT),y)
+obj-y				+= mct.o
+else
+obj-y				+= time.o
+obj-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
+endif
+
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
 
 # machine support
diff --git a/arch/arm/mach-exynos4/include/mach/regs-mct.h b/arch/arm/mach-exynos4/include/mach/regs-mct.h
new file mode 100644
index 0000000..ca9c843
--- /dev/null
+++ b/arch/arm/mach-exynos4/include/mach/regs-mct.h
@@ -0,0 +1,52 @@
+/* arch/arm/mach-exynos4/include/mach/regs-mct.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * EXYNOS4 MCT configutation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_ARCH_REGS_MCT_H
+#define __ASM_ARCH_REGS_MCT_H __FILE__
+
+#include <mach/map.h>
+
+#define EXYNOS4_MCTREG(x)		(S5P_VA_SYSTIMER + (x))
+
+#define EXYNOS4_MCT_G_CNT_L		EXYNOS4_MCTREG(0x100)
+#define EXYNOS4_MCT_G_CNT_U		EXYNOS4_MCTREG(0x104)
+#define EXYNOS4_MCT_G_CNT_WSTAT		EXYNOS4_MCTREG(0x110)
+
+#define EXYNOS4_MCT_G_COMP0_L		EXYNOS4_MCTREG(0x200)
+#define EXYNOS4_MCT_G_COMP0_U		EXYNOS4_MCTREG(0x204)
+#define EXYNOS4_MCT_G_COMP0_ADD_INCR	EXYNOS4_MCTREG(0x208)
+
+#define EXYNOS4_MCT_G_TCON		EXYNOS4_MCTREG(0x240)
+
+#define EXYNOS4_MCT_G_INT_CSTAT		EXYNOS4_MCTREG(0x244)
+#define EXYNOS4_MCT_G_INT_ENB		EXYNOS4_MCTREG(0x248)
+#define EXYNOS4_MCT_G_WSTAT		EXYNOS4_MCTREG(0x24C)
+
+#define EXYNOS4_MCT_L0_BASE		EXYNOS4_MCTREG(0x300)
+#define EXYNOS4_MCT_L1_BASE		EXYNOS4_MCTREG(0x400)
+
+#define MCT_L_TCNTB_OFFSET		(0x00)
+#define MCT_L_ICNTB_OFFSET		(0x08)
+#define MCT_L_TCON_OFFSET		(0x20)
+#define MCT_L_INT_CSTAT_OFFSET		(0x30)
+#define MCT_L_INT_ENB_OFFSET		(0x34)
+#define MCT_L_WSTAT_OFFSET		(0x40)
+
+#define MCT_G_TCON_START		(1 << 8)
+#define MCT_G_TCON_COMP0_AUTO_INC	(1 << 1)
+#define MCT_G_TCON_COMP0_ENABLE		(1 << 0)
+
+#define MCT_L_TCON_INTERVAL_MODE	(1 << 2)
+#define MCT_L_TCON_INT_START		(1 << 1)
+#define MCT_L_TCON_TIMER_START		(1 << 0)
+
+#endif /* __ASM_ARCH_REGS_MCT_H */
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
new file mode 100644
index 0000000..6bb4b50
--- /dev/null
+++ b/arch/arm/mach-exynos4/mct.c
@@ -0,0 +1,421 @@
+/* linux/arch/arm/mach-exynos4/mct.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * EXYNOS4 MCT(Multi-Core Timer) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/percpu.h>
+
+#include <mach/map.h>
+#include <mach/regs-mct.h>
+#include <asm/mach/time.h>
+
+static unsigned long clk_cnt_per_tick;
+static unsigned long clk_rate;
+
+struct mct_clock_event_device {
+	struct clock_event_device *evt;
+	void __iomem *base;
+};
+
+struct mct_clock_event_device mct_tick[2];
+
+static void exynos4_mct_write(unsigned int value, void *addr)
+{
+	void __iomem *stat_addr;
+	u32 mask;
+	u32 i;
+
+	__raw_writel(value, addr);
+
+	switch ((u32) addr) {
+	case (u32) EXYNOS4_MCT_G_TCON:
+		stat_addr = EXYNOS4_MCT_G_WSTAT;
+		mask = 1 << 16;		/* G_TCON write status */
+		break;
+	case (u32) EXYNOS4_MCT_G_COMP0_L:
+		stat_addr = EXYNOS4_MCT_G_WSTAT;
+		mask = 1 << 0;		/* G_COMP0_L write status */
+		break;
+	case (u32) EXYNOS4_MCT_G_COMP0_U:
+		stat_addr = EXYNOS4_MCT_G_WSTAT;
+		mask = 1 << 1;		/* G_COMP0_U write status */
+		break;
+	case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
+		stat_addr = EXYNOS4_MCT_G_WSTAT;
+		mask = 1 << 2;		/* G_COMP0_ADD_INCR write status */
+		break;
+	case (u32) EXYNOS4_MCT_G_CNT_L:
+		stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+		mask = 1 << 0;		/* G_CNT_L write status */
+		break;
+	case (u32) EXYNOS4_MCT_G_CNT_U:
+		stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+		mask = 1 << 1;		/* G_CNT_U write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCON_OFFSET):
+		stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 3;		/* L0_TCON write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCON_OFFSET):
+		stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 3;		/* L1_TCON write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_TCNTB_OFFSET):
+		stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 0;		/* L0_TCNTB write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_TCNTB_OFFSET):
+		stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 0;		/* L1_TCNTB write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L0_BASE + MCT_L_ICNTB_OFFSET):
+		stat_addr = EXYNOS4_MCT_L0_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 1;		/* L0_ICNTB write status */
+		break;
+	case (u32)(EXYNOS4_MCT_L1_BASE + MCT_L_ICNTB_OFFSET):
+		stat_addr = EXYNOS4_MCT_L1_BASE + MCT_L_WSTAT_OFFSET;
+		mask = 1 << 1;		/* L1_ICNTB write status */
+		break;
+	default:
+		return;
+	}
+
+	/* Wait maximum 1 ms until written values are applied */
+	for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
+		if (__raw_readl(stat_addr) & mask) {
+			__raw_writel(mask, stat_addr);
+			return;
+		}
+
+	panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
+}
+
+/* Clocksource handling */
+static void exynos4_mct_frc_start(u32 hi, u32 lo)
+{
+	u32 reg;
+
+	exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
+	exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
+
+	reg = __raw_readl(EXYNOS4_MCT_G_TCON);
+	reg |= MCT_G_TCON_START;
+	exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
+}
+
+static cycle_t exynos4_frc_read(struct clocksource *cs)
+{
+	unsigned int lo, hi;
+	u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+
+	do {
+		hi = hi2;
+		lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
+		hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
+	} while (hi != hi2);
+
+	return ((cycle_t)hi << 32) | lo;
+}
+
+struct clocksource mct_frc = {
+	.name		= "mct-frc",
+	.rating		= 400,
+	.read		= exynos4_frc_read,
+	.mask		= CLOCKSOURCE_MASK(64),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void __init exynos4_clocksource_init(void)
+{
+	exynos4_mct_frc_start(0, 0);
+
+	if (clocksource_register_hz(&mct_frc, clk_rate))
+		panic("%s: can't register clocksource\n", mct_frc.name);
+}
+
+static void exynos4_mct_comp0_stop(void)
+{
+	unsigned int tcon;
+
+	tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+	tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
+
+	exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
+	exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
+}
+
+static void exynos4_mct_comp0_start(enum clock_event_mode mode,
+				    unsigned long cycles)
+{
+	unsigned int tcon;
+	cycle_t comp_cycle;
+
+	tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
+
+	if (mode == CLOCK_EVT_MODE_PERIODIC) {
+		tcon |= MCT_G_TCON_COMP0_AUTO_INC;
+		exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
+	}
+
+	comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
+	exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
+	exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
+
+	exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
+
+	tcon |= MCT_G_TCON_COMP0_ENABLE;
+	exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
+}
+
+static int exynos4_comp_set_next_event(unsigned long cycles,
+				       struct clock_event_device *evt)
+{
+	exynos4_mct_comp0_start(evt->mode, cycles);
+
+	return 0;
+}
+
+static void exynos4_comp_set_mode(enum clock_event_mode mode,
+				  struct clock_event_device *evt)
+{
+	exynos4_mct_comp0_stop();
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		exynos4_mct_comp0_start(mode, clk_cnt_per_tick);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static struct clock_event_device mct_comp_device = {
+	.name		= "mct-comp",
+	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 250,
+	.set_next_event	= exynos4_comp_set_next_event,
+	.set_mode	= exynos4_comp_set_mode,
+};
+
+static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mct_comp_event_irq = {
+	.name		= "mct_comp_irq",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= exynos4_mct_comp_isr,
+	.dev_id		= &mct_comp_device,
+};
+
+static void exynos4_clockevent_init(void)
+{
+	clk_cnt_per_tick = clk_rate / 2	/ HZ;
+
+	clockevents_calc_mult_shift(&mct_comp_device, clk_rate / 2, 5);
+	mct_comp_device.max_delta_ns =
+		clockevent_delta2ns(0xffffffff, &mct_comp_device);
+	mct_comp_device.min_delta_ns =
+		clockevent_delta2ns(0xf, &mct_comp_device);
+	mct_comp_device.cpumask = cpumask_of(0);
+	clockevents_register_device(&mct_comp_device);
+
+	setup_irq(IRQ_MCT_G0, &mct_comp_event_irq);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+/* Clock event handling */
+static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
+{
+	unsigned long tmp;
+	unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
+	void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
+
+	tmp = __raw_readl(addr);
+	if (tmp & mask) {
+		tmp &= ~mask;
+		exynos4_mct_write(tmp, addr);
+	}
+}
+
+static void exynos4_mct_tick_start(unsigned long cycles,
+				   struct mct_clock_event_device *mevt)
+{
+	unsigned long tmp;
+
+	exynos4_mct_tick_stop(mevt);
+
+	tmp = (1 << 31) | cycles;	/* MCT_L_UPDATE_ICNTB */
+
+	/* update interrupt count buffer */
+	exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
+
+	/* enable MCT tick interupt */
+	exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
+
+	tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
+	tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
+	       MCT_L_TCON_INTERVAL_MODE;
+	exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
+}
+
+static int exynos4_tick_set_next_event(unsigned long cycles,
+				       struct clock_event_device *evt)
+{
+	struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
+
+	exynos4_mct_tick_start(cycles, mevt);
+
+	return 0;
+}
+
+static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
+					 struct clock_event_device *evt)
+{
+	struct mct_clock_event_device *mevt = &mct_tick[smp_processor_id()];
+
+	exynos4_mct_tick_stop(mevt);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		exynos4_mct_tick_start(clk_cnt_per_tick, mevt);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+		break;
+	}
+}
+
+static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
+{
+	struct mct_clock_event_device *mevt = dev_id;
+	struct clock_event_device *evt = mevt->evt;
+
+	/*
+	 * This is for supporting oneshot mode.
+	 * Mct would generate interrupt periodically
+	 * without explicit stopping.
+	 */
+	if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
+		exynos4_mct_tick_stop(mevt);
+
+	/* Clear the MCT tick interrupt */
+	exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mct_tick0_event_irq = {
+	.name		= "mct_tick0_irq",
+	.flags		= IRQF_TIMER | IRQF_NOBALANCING,
+	.handler	= exynos4_mct_tick_isr,
+};
+
+static struct irqaction mct_tick1_event_irq = {
+	.name		= "mct_tick1_irq",
+	.flags		= IRQF_TIMER | IRQF_NOBALANCING,
+	.handler	= exynos4_mct_tick_isr,
+};
+
+static void exynos4_mct_tick_init(struct clock_event_device *evt)
+{
+	unsigned int cpu = smp_processor_id();
+
+	mct_tick[cpu].evt = evt;
+
+	if (cpu == 0) {
+		mct_tick[cpu].base = EXYNOS4_MCT_L0_BASE;
+		evt->name = "mct_tick0";
+	} else {
+		mct_tick[cpu].base = EXYNOS4_MCT_L1_BASE;
+		evt->name = "mct_tick1";
+	}
+
+	evt->cpumask = cpumask_of(cpu);
+	evt->set_next_event = exynos4_tick_set_next_event;
+	evt->set_mode = exynos4_tick_set_mode;
+	evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	evt->rating = 450;
+
+	clockevents_calc_mult_shift(evt, clk_rate / 2, 5);
+	evt->max_delta_ns =
+		clockevent_delta2ns(0x7fffffff, evt);
+	evt->min_delta_ns =
+		clockevent_delta2ns(0xf, evt);
+
+	clockevents_register_device(evt);
+
+	exynos4_mct_write(0x1, mct_tick[cpu].base + MCT_L_TCNTB_OFFSET);
+
+	if (cpu == 0) {
+		mct_tick0_event_irq.dev_id = &mct_tick[cpu];
+		setup_irq(IRQ_MCT_L0, &mct_tick0_event_irq);
+	} else {
+		mct_tick1_event_irq.dev_id = &mct_tick[cpu];
+		irq_set_affinity(IRQ_MCT1, cpumask_of(1));
+		setup_irq(IRQ_MCT_L1, &mct_tick1_event_irq);
+	}
+}
+
+/* Setup the local clock events for a CPU */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+	exynos4_mct_tick_init(evt);
+}
+
+int local_timer_ack(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_LOCAL_TIMERS */
+
+static void __init exynos4_timer_resources(void)
+{
+	struct clk *mct_clk;
+	mct_clk = clk_get(NULL, "xtal");
+
+	clk_rate = clk_get_rate(mct_clk);
+}
+
+static void __init exynos4_timer_init(void)
+{
+	exynos4_timer_resources();
+	exynos4_clocksource_init();
+	exynos4_clockevent_init();
+}
+
+struct sys_timer exynos4_timer = {
+	.init		= exynos4_timer_init,
+};
-- 
1.7.1

^ permalink raw reply related

* [PATCH 09/09] ARM: s3c2440: gta02: Add touchscreen support
From: Kukjin Kim @ 2011-02-28  6:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-9-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> This patch registers the s3c touchscreen and adc devices to add
touchscreen
> support for the gta02.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |   12 ++++++++++++
>  1 files changed, 12 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index 94456fa..2300ec5 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -79,6 +79,8 @@
>  #include <mach/regs-mem.h>
>  #include <mach/hardware.h>
> 
> +#include <plat/ts.h>
> +

Please group same/similar inclusion together like following.
<linux/...> <asm/...> then <mach/...> or <plat/...>

In other words, please add your <plat/ts.h> inclusion after other <plat/...>

>  #include <mach/gta02.h>
> 
>  #include <plat/regs-serial.h>
> @@ -480,6 +482,13 @@ static struct s3c2410_hcd_info gta02_usb_info
__initdata
> = {
>  	},
>  };
> 
> +/* Touchscreen */
> +static struct s3c2410_ts_mach_info gta02_ts_info = {
> +	.delay = 10000,
> +	.presc = 0xff, /* slow as we can go */
> +	.oversampling_shift = 2,
> +};

How about to use tab between member and = like following?

static struct s3c2410_ts_mach_info gta02_ts_info = {
	.delay			= 10000,
	.presc			= 0xff, /* slow as we can go */
	.oversampling_shift	= 2,
};

> +
>  /* Buttons */
>  static struct gpio_keys_button gta02_buttons[] = {
>  	{
> @@ -533,6 +542,8 @@ static struct platform_device *gta02_devices[]
__initdata
> = {
>  	&samsung_asoc_dma,
>  	&s3c_device_i2c0,
>  	&gta02_buttons_device,
> +	&s3c_device_adc,

No need to build plat-samsung/dev-adc.c for this?
If you want to add '&s3c_deivce_adc', should add 'select SAMSUNG_DEV_ADC'
into "config MACH_NEO1973_GTA02".

> +	&s3c_device_ts,

'select SAMSUNG_DEV_TS'

>  };
> 
>  /* These guys DO need to be children of PMU. */
> @@ -597,6 +608,7 @@ static void __init gta02_machine_init(void)
>  #endif
> 
>  	s3c24xx_udc_set_platdata(&gta02_udc_cfg);
> +	s3c24xx_ts_set_platdata(&gta02_ts_info);

Same as above. 'select SAMSUNG_DEV_TS' should be added for
plat-samsung/dev-ts.c.

>  	s3c_ohci_set_platdata(&gta02_usb_info);
>  	s3c_nand_set_platdata(&gta02_nand_info);
>  	s3c_i2c0_set_platdata(NULL);
> --
> 1.7.2.3


Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH] backlight/platform_lcd: change set power function parameter in plat_lcd_data
From: Donghwa Lee @ 2011-02-28  6:14 UTC (permalink / raw)
  To: linux-arm-kernel

In drivers/video/backlight/platform_lcd.c driver, to use lcd power
control function in platdata, it is used
set_power(struct plat_lcd_data *, unsigned int power) callback function.
set_power() function is consists of two parameters,
(struct plat_lcd_data *, unsigned int power).

But actually, there is no one to use (struct plat_lcd_data *), only use
second (unsigned int power) value to control lcd power on/off.

I don't know why (struct plat_lcd_data*) parameter is used in set_power()
callback function. Maybe I think it is unessesntial or changeable to another
meaningful variable. For example, struct lcd_device *, it can be used to
control regulator_get() function.

In mach-nuri.c, it has been patching by Minku Kang, (struct lcd_device*) can be
used to regulator lcd power on/off, and many other machines uses regulator
control to on/off lcd power.

So I think more meaningful variable that (struct lcd_device* ) can be
substituted for unessential variable that (struct plat_lcd_data *).

Thank you,
Donghwa Lee


Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

---
 drivers/video/backlight/platform_lcd.c |    2 +-
 include/video/platform_lcd.h           |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index 302330a..cf23a3f 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -49,7 +49,7 @@ static int platform_lcd_set_power(struct lcd_device *lcd, int power)
 	if (power == FB_BLANK_POWERDOWN || plcd->suspended)
 		lcd_power = 0;
 
-	plcd->pdata->set_power(plcd->pdata, lcd_power);
+	plcd->pdata->set_power(lcd, lcd_power);
 	plcd->power = power;
 
 	return 0;
diff --git a/include/video/platform_lcd.h b/include/video/platform_lcd.h
index ad3bdfe..e92a039 100644
--- a/include/video/platform_lcd.h
+++ b/include/video/platform_lcd.h
@@ -15,7 +15,7 @@ struct plat_lcd_data;
 struct fb_info;
 
 struct plat_lcd_data {
-	void	(*set_power)(struct plat_lcd_data *, unsigned int power);
+	void	(*set_power)(struct lcd_device *, unsigned int power);
 	int	(*match_fb)(struct plat_lcd_data *, struct fb_info *);
 };
 
-- 
1.6.0.4

^ permalink raw reply related

* [PATCH 08/09] ARM: s3c2440: gta02: Request usb pullup pin before using it
From: Kukjin Kim @ 2011-02-28  6:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-8-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> Request the gpio pin used to control the usb pullup before using it to
avoid
> a
> runtime warning about an auto-requested gpio.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |   17 +++++++++++++++--
>  1 files changed, 15 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index 1396639..94456fa 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -451,11 +451,11 @@ static void gta02_udc_command(enum s3c2410_udc_cmd_e
> cmd)
>  	switch (cmd) {
>  	case S3C2410_UDC_P_ENABLE:
>  		pr_debug("%s S3C2410_UDC_P_ENABLE\n", __func__);
> -		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
> +		gpio_set_value(GTA02_GPIO_USB_PULLUP, 1);

How about following instead?
	gpio_request(GTA02_GPIO_USB_PULLUP, "USB_PULLUP");
	gpio_direction_output(GTA02_GPIO_USB_PULLUP, 1);
	gpio_free(GTA02_GPIO_USB_PULLUP);

>  		break;
>  	case S3C2410_UDC_P_DISABLE:
>  		pr_debug("%s S3C2410_UDC_P_DISABLE\n", __func__);
> -		gpio_direction_output(GTA02_GPIO_USB_PULLUP, 0);
> +		gpio_set_value(GTA02_GPIO_USB_PULLUP, 0);
>  		break;
>  	case S3C2410_UDC_P_RESET:
>  		pr_debug("%s S3C2410_UDC_P_RESET\n", __func__);
> @@ -572,11 +572,24 @@ static void gta02_poweroff(void)
>  	pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1);
>  }
> 
> +static void gta02_request_gpios(void)
> +{
> +	int ret;
> +	ret = gpio_request_one(GTA02_GPIO_USB_PULLUP, GPIOF_OUT_INIT_LOW,
> +				"USB pullup");
> +	if (ret) {
> +		printk(KERN_ERR "Failed to request USB pullup gpio pin:
%d\n",
> +			ret);
> +	}
> +}
> +
>  static void __init gta02_machine_init(void)
>  {
>  	/* Set the panic callback to turn AUX LED on or off. */
>  	panic_blink = gta02_panic_blink;
> 
> +	gta02_request_gpios();
> +
>  	s3c_pm_init();
> 
>  #ifdef CONFIG_CHARGER_PCF50633
> --



Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 06/09] ARM: s3c2440: gta02: Remove state_mem constraints for the pcf50633 regulators
From: Kukjin Kim @ 2011-02-28  6:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-6-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> The pcf50633 regulator driver does not use the state_mem constraints, so
> there
> is no use in setting them.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |   15 ---------------
>  1 files changed, 0 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index e57c4d8..01e0930 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -283,9 +283,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
>  				.always_on = 1,
>  				.apply_uV = 1,
> -				.state_mem = {
> -					.enabled = 1,
> -				},
>  			},
>  		},
>  		[PCF50633_REGULATOR_DOWN1] = {
> @@ -304,9 +301,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
>  				.apply_uV = 1,
>  				.always_on = 1,
> -				.state_mem = {
> -					.enabled = 1,
> -				},
>  			},
>  		},
>  		[PCF50633_REGULATOR_HCLDO] = {
> @@ -325,9 +319,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
>  				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
>  				.apply_uV = 1,
> -				.state_mem = {
> -					.enabled = 0,
> -				},
>  			},
>  		},
>  		[PCF50633_REGULATOR_LDO2] = {
> @@ -362,9 +353,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
>  				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
>  				.apply_uV = 1,
> -				.state_mem = {
> -					.enabled = 1,
> -				},
>  			},
>  		},
>  		[PCF50633_REGULATOR_LDO6] = {
> @@ -379,9 +367,6 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.min_uV = 1800000,
>  				.max_uV = 1800000,
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
> -				.state_mem = {
> -					.enabled = 1,
> -				},
>  			},
>  		},
> 
> --

Don't we need regulator_suspend_mem_state_show() on PCF50633?


Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 04/09] ARM: s3c2440: gta02: Select missing S3C_DEV_USB_HOST
From: Kukjin Kim @ 2011-02-28  6:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-4-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> The gta02 mach file references the ohci device.
> So we need to select S3C_DEV_USB_HOST to have the device available.
> 
> This fixes the following linker errors:
> 	arch/arm/mach-s3c2440/built-in.o: In function `gta02_machine_init':
> 	mach-gta02.c:(.init.text+0x370): undefined reference to
> `s3c_ohci_set_platdata'
> 	arch/arm/mach-s3c2440/built-in.o:(.init.data+0xac): undefined
> reference to `s3c_device_ohci'
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/Kconfig |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
> index a0cb258..50825a3 100644
> --- a/arch/arm/mach-s3c2440/Kconfig
> +++ b/arch/arm/mach-s3c2440/Kconfig
> @@ -99,6 +99,7 @@ config MACH_NEO1973_GTA02
>  	select POWER_SUPPLY
>  	select MACH_NEO1973
>  	select S3C2410_PWM
> +	select S3C_DEV_USB_HOST
>  	help
>  	   Say Y here if you are using the Openmoko GTA02 / Freerunner GSM
> Phone
> 
> --
> 1.7.2.3

Ok, applied.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 03/09] ARM: s3c2440: gta02: Add button support
From: Kukjin Kim @ 2011-02-28  6:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-3-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> This patch adds support for the two buttons found on the gta02 device,
which
> are
> connectd to gpio pins, using the gpio-keys driver.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |   34
++++++++++++++++++++++++++++++++++
>  1 files changed, 34 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index e83062b..6629998 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -58,6 +58,9 @@
>  #include <linux/mfd/pcf50633/pmic.h>
>  #include <linux/mfd/pcf50633/backlight.h>
> 
> +#include <linux/input.h>
> +#include <linux/gpio_keys.h>
> +
>  #include <asm/mach/arch.h>
>  #include <asm/mach/map.h>
>  #include <asm/mach/irq.h>
> @@ -489,6 +492,36 @@ static struct s3c2410_hcd_info gta02_usb_info
__initdata
> = {
>  	},
>  };
> 
> +/* Buttons */
> +static struct gpio_keys_button gta02_buttons[] = {
> +	{
> +		.gpio = GTA02_GPIO_AUX_KEY,
> +		.code = KEY_PHONE,
> +		.desc = "Aux",
> +		.type = EV_KEY,
> +		.debounce_interval = 100,
> +	},
> +	{
> +		.gpio = GTA02_GPIO_HOLD_KEY,
> +		.code = KEY_PAUSE,
> +		.desc = "Hold",
> +		.type = EV_KEY,
> +		.debounce_interval = 100,
> +	},
> +};
> +
> +static struct gpio_keys_platform_data gta02_buttons_pdata = {
> +	.buttons = gta02_buttons,
> +	.nbuttons = ARRAY_SIZE(gta02_buttons),
> +};
> +
> +static struct platform_device gta02_buttons_device = {
> +	.name = "gpio-keys",
> +	.id = -1,
> +	.dev = {
> +		.platform_data = &gta02_buttons_pdata,
> +	},
> +};
> 
>  static void __init gta02_map_io(void)
>  {
> @@ -511,6 +544,7 @@ static struct platform_device *gta02_devices[]
__initdata
> = {
>  	&s3c_device_iis,
>  	&samsung_asoc_dma,
>  	&s3c_device_i2c0,
> +	&gta02_buttons_device,
>  };
> 
>  /* These guys DO need to be children of PMU. */
> --

Ok, will apply.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 02/09] ARM: s3c2440: gta02: Register PCM device
From: Kukjin Kim @ 2011-02-28  6:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-2-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> The ASoC multi-component patch introduced a new pcm platform device, which
> needs
> to be registered by board files in order for sound to work.
> This patch does this for the gta02 board.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index 9f2c14e..e83062b 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -509,6 +509,7 @@ static struct platform_device *gta02_devices[]
__initdata
> = {
>  	&gta02_nor_flash,
>  	&s3c24xx_pwm_device,
>  	&s3c_device_iis,
> +	&samsung_asoc_dma,
>  	&s3c_device_i2c0,
>  };
> 
> --

Ok, will apply.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 01/09] ARM: s3c2442: gta02: Fix usage gpio bank j pin definitions
From: Kukjin Kim @ 2011-02-28  6:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-1-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> The gta02 header file still uses the old S3C2410_GPJx defines instead of
the
> S3C2410_GPJ(x) macro. Since the S3C2410_GPJx defines have already been
> removed
> this causes the following build failure:
> 
> 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_set_spk':
> 	sound/soc/samsung/neo1973_wm8753.c:259: error: 'S3C2440_GPJ2'
> undeclared (first use in this function)
> 	sound/soc/samsung/neo1973_wm8753.c:259: error: (Each undeclared
> identifier is reported only once
> 	sound/soc/samsung/neo1973_wm8753.c:259: error: for each function it
> appears in.)
> 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_get_spk':
> 	sound/soc/samsung/neo1973_wm8753.c:267: error: 'S3C2440_GPJ2'
> undeclared (first use in this function)
> 	sound/soc/samsung/neo1973_wm8753.c: In function 'lm4853_event':
> 	sound/soc/samsung/neo1973_wm8753.c:276: error: 'S3C2440_GPJ1'
> undeclared (first use in this function)
> 	sound/soc/samsung/neo1973_wm8753.c: At top level:
> 	sound/soc/samsung/neo1973_wm8753.c:439: error: 'S3C2440_GPJ2'
> undeclared here (not in a function)
> 	sound/soc/samsung/neo1973_wm8753.c:440: error: 'S3C2440_GPJ1'
> undeclared here (not in a function)
> 
> This patches fixes the issue by doing a
> s,S3C2410_GPJ([\d]+),S3C2410_GPJ(\1),g

Maybe, "s,S3C2440_GPJ([\d]+),S3C2410_GPJ(\1),g" instead ?

> on the file.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/include/mach/gta02.h |   26
+++++++++++++-------------
>  1 files changed, 13 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/include/mach/gta02.h b/arch/arm/mach-
> s3c2440/include/mach/gta02.h
> index 953331d..3a56a22 100644
> --- a/arch/arm/mach-s3c2440/include/mach/gta02.h
> +++ b/arch/arm/mach-s3c2440/include/mach/gta02.h
> @@ -44,19 +44,19 @@
>  #define GTA02v3_GPIO_nUSB_FLT	S3C2410_GPG(10)	/* v3 + v4 only */
>  #define GTA02v3_GPIO_nGSM_OC	S3C2410_GPG(11)	/* v3 + v4 only */
> 
> -#define GTA02_GPIO_AMP_SHUT	S3C2440_GPJ1	/* v2 + v3 + v4 only */
> -#define GTA02v1_GPIO_WLAN_GPIO10	S3C2440_GPJ2
> -#define GTA02_GPIO_HP_IN	S3C2440_GPJ2	/* v2 + v3 + v4 only */
> -#define GTA02_GPIO_INT0		S3C2440_GPJ3	/* v2 + v3 + v4 only
*/
> -#define GTA02_GPIO_nGSM_EN	S3C2440_GPJ4
> -#define GTA02_GPIO_3D_RESET	S3C2440_GPJ5
> -#define GTA02_GPIO_nDL_GSM	S3C2440_GPJ6	/* v4 + v5 only */
> -#define GTA02_GPIO_WLAN_GPIO0	S3C2440_GPJ7
> -#define GTA02v1_GPIO_BAT_ID	S3C2440_GPJ8
> -#define GTA02_GPIO_KEEPACT	S3C2440_GPJ8
> -#define GTA02v1_GPIO_HP_IN	S3C2440_GPJ10
> -#define GTA02_CHIP_PWD		S3C2440_GPJ11	/* v2 + v3 + v4 only
*/
> -#define GTA02_GPIO_nWLAN_RESET	S3C2440_GPJ12	/* v2 + v3 + v4 only
*/
> +#define GTA02_GPIO_AMP_SHUT	S3C2410_GPJ(1)	/* v2 + v3 + v4 only */
> +#define GTA02v1_GPIO_WLAN_GPIO10	S3C2410_GPJ(2)
> +#define GTA02_GPIO_HP_IN	S3C2410_GPJ(2)	/* v2 + v3 + v4 only */
> +#define GTA02_GPIO_INT0		S3C2410_GPJ(3)	/* v2 + v3 + v4 only
*/
> +#define GTA02_GPIO_nGSM_EN	S3C2410_GPJ(4)
> +#define GTA02_GPIO_3D_RESET	S3C2410_GPJ(5)
> +#define GTA02_GPIO_nDL_GSM	S3C2410_GPJ(6)	/* v4 + v5 only */
> +#define GTA02_GPIO_WLAN_GPIO0	S3C2410_GPJ(7)
> +#define GTA02v1_GPIO_BAT_ID	S3C2410_GPJ(8)
> +#define GTA02_GPIO_KEEPACT	S3C2410_GPJ(8)
> +#define GTA02v1_GPIO_HP_IN	S3C2410_GPJ(10)
> +#define GTA02_CHIP_PWD		S3C2410_GPJ(11)	/* v2 + v3 + v4
> only */
> +#define GTA02_GPIO_nWLAN_RESET	S3C2410_GPJ(12)	/* v2 + v3 + v4
> only */
> 
>  #define GTA02_IRQ_GSENSOR_1	IRQ_EINT0
>  #define GTA02_IRQ_MODEM		IRQ_EINT1
> --
> 1.7.2.3

Yeah, old S3C2440_GPJx has removed.
Is the S3C2410_GPJ(1) right instead of S3C2440_GPJ1?

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH v2 07/09] ARM: s3c2440: gta02: Call regulator_has_full_constraints
From: Kukjin Kim @ 2011-02-28  6:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297133720-18178-1-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> This allows the regulator core to disable all regulators which are not in
use
> at the end of the kernel init phase.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index 01e0930..2682592 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -590,6 +590,8 @@ static void __init gta02_machine_init(void)
> 
>  	platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));
>  	pm_power_off = gta02_poweroff;
> +
> +	regulator_has_full_constraints();
>  }
> 
> 
> --

Ok, will apply.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH 05/09] ARM: s3c2440: gta02: Fix regulator valid_modes_ops
From: Kukjin Kim @ 2011-02-28  6:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1297043521-21903-5-git-send-email-lars@metafoo.de>

Lars-Peter Clausen wrote:
> 
> The REGULATOR_CHANGE_STATUS flag needs to be set on valid_ops_mask,
otherwise
> it
> a driver wont be able to turn the regulator on or off.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> ---
>  arch/arm/mach-s3c2440/mach-gta02.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/mach-s3c2440/mach-gta02.c
b/arch/arm/mach-s3c2440/mach-
> gta02.c
> index 6629998..e57c4d8 100644
> --- a/arch/arm/mach-s3c2440/mach-gta02.c
> +++ b/arch/arm/mach-s3c2440/mach-gta02.c
> @@ -314,8 +314,8 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.min_uV = 2000000,
>  				.max_uV = 3300000,
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
> -				.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
> -				.always_on = 1,
> +				.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
> +						REGULATOR_CHANGE_STATUS,
>  			},
>  		},
>  		[PCF50633_REGULATOR_LDO1] = {
> @@ -323,6 +323,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.min_uV = 3300000,
>  				.max_uV = 3300000,
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
> +				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
>  				.apply_uV = 1,
>  				.state_mem = {
>  					.enabled = 0,
> @@ -350,6 +351,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.min_uV = 3200000,
>  				.max_uV = 3200000,
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
> +				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
>  				.apply_uV = 1,
>  			},
>  		},
> @@ -358,6 +360,7 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
>  				.min_uV = 3000000,
>  				.max_uV = 3000000,
>  				.valid_modes_mask = REGULATOR_MODE_NORMAL,
> +				.valid_ops_mask = REGULATOR_CHANGE_STATUS,
>  				.apply_uV = 1,
>  				.state_mem = {
>  					.enabled = 1,
> --

Ok, will apply.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.

^ permalink raw reply

* [PATCH v10 05/18] OMAP2,3 DSS2 Change driver name to omap_display
From: Tomi Valkeinen @ 2011-02-28  6:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1298539643.16119.54.camel@deskari>

On Thu, 2011-02-24 at 03:27 -0600, Tomi Valkeinen wrote:
> Hi,
> 
> On Mon, 2011-01-24 at 11:51 +0530, ext Sumit Semwal wrote:
> > From: Senthilvadivu Guruswamy <svadivu@ti.com>
> > 
> > Change the driver name from omapdss to omap_display as the driver takes care of
> > the display devices ie number of panels, type of panels available in the
> > platform.  Change the device name in the board files and 2420,2430,3xxx clock
> > files from omapdss to omap_display to match the driver name.
> 
> I just realized that changing the driver name will break all scripts and
> applications using omapdss sysfs files.
> 
> How does this sound:
> 
> Let's leave the omapdss device name as it is. It represents a "super"
> device, containing the dss sysfs files and upper level dss management.
> 
> Name the HW module platform drivers as: omapdss_dss, omapdss_venc,
> omapdss_dispc, etc. This would indicate them to be clearly parts of DSS,
> and would also prevent any possible name conflict if there would happen
> to be a, say, "dsi" block in some other HW component.

Any comments on this?

 Tomi

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox