* [PATCH 1/5] ARM: smp: Select local timers vs dummy timersupport runtime
From: Russell King - ARM Linux @ 2011-02-23 16:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e3674a4c299e3cc0fad3e15a3cc03db4@mail.gmail.com>
On Sun, Feb 20, 2011 at 04:37:36PM +0530, Santosh Shilimkar wrote:
> > -----Original Message-----
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > Sent: Sunday, February 20, 2011 4:34 PM
> > To: Santosh Shilimkar
> > Cc: linux-omap at vger.kernel.org; khilman at ti.com; linux-arm-
> > kernel at lists.infradead.org; tony at atomide.com; David Brown; Daniel
> > Walker; Bryan Huntsman; Kukjin Kim; Paul Mundt; Magnus Damm; Colin
> > Cross; Erik Gilling; Srinidhi Kasagar; Linus Walleij
> > Subject: Re: [PATCH 1/5] ARM: smp: Select local timers vs dummy
> > timersupport runtime
> >
> > On Sat, Feb 12, 2011 at 04:59:43PM +0530, Santosh Shilimkar wrote:
> > > -#ifndef CONFIG_LOCAL_TIMERS
> > > static void broadcast_timer_set_mode(enum clock_event_mode mode,
> > > struct clock_event_device *evt)
> > > {
> > > }
> > >
> > > -static void local_timer_setup(struct clock_event_device *evt)
> > > +static void dummy_timer_setup(struct clock_event_device *evt)
> >
> > Please call this broadcast_timer_setup().
>
> Right. Will fix this.
Grr. This conflicts horribly with the Versatile stuff. Can you recreate
against what currently appears in devel rather than mainline please?
^ permalink raw reply
* MMC quirks relating to performance/lifetime.
From: Arnd Bergmann @ 2011-02-23 16:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTinfWiRaGruP8cM44c62T8svVOKsFhi4Dmg8yzEa@mail.gmail.com>
On Wednesday 23 February 2011, Andrei Warkentin wrote:
> That sounds good! In fact, for any quirks enabled for a particular
> card, I'll expose the tuneables through sysfs attributes, something
> like /sys/block/mmcblk0/device/quirks/quirk-name/attr-names.
>
> Quirks will have block intervals and access size intervals over which
> they are valid, along with any other quirk-specific parameter.
> Interval overlap will not be allowed for quirks in the same operation
> type (r/w/e). The goal here is to make the changes to issue_*_rq as
> small as possible, and not to pollute block.c at all with the quirks
> stuff. Quirks are looked up inside issue_*_rq based on req type and
> [start,end) interval. The resulting found quirks structure will
> contain a callback used inside issue_*_rq to modify mmc block request
> structures prior to generating actual MMC commands.
>
> Quirks consist of a callback called inside of mmc issue_*_rq,
> configurable attributes, and the sysfs interface. Quirk groups are
> defined per-card. At card insertion time, a matching quirk group is
> found, and is enabled. The quirk group enable function then enables
> the relevant quirks with the right parameters (adds them to per
> mmc_blk_data quirk interval tree). Some sane defaults for the tunables
> are used. If the tunables are modified through sysfs, care is taken
> that an interval overlap never happens, otherwise the tunable is not
> modified and a kernel error message is logged.
>
> I hope I explained the tentative idea clearly... Thoughts?
I would hope that the quirks can be simpler than this still, without
the need to call any function pointers while using the device, or
quirk specific sysfs directories.
What I meant is to have a single function pointer that can get
called when detecting a specific known card. All this function
does is to set values and flags that we can export either through
common attributes of block devices (e.g. preferred erase size),
or attributes specific to mmc devices (e.g. the toshiba hack, as
a bool attribute).
An obvious attribute would be the minimum size of an atomic
page update. By default this could be 32KB, because any device
should support that (FAT32 cannot have larger clusters). A
card specific quirk can set it to another value, like 8KB, 16KB
or 64KB, and file systems or other tools like mkfs can optimize
for this value.
I would like the flags like "don't submit requests spanning
this boundary" and "make all writes below this size" to be defined
in terms of the regular sizes we already know about, like the
page size or the erase size.
Arnd
^ permalink raw reply
* [PATCH 4/5] ARM: s5pv310: update IRQ combiner to use EOI in parent chip
From: Will Deacon @ 2011-02-23 15:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimiPEsb_S3tv+yPOr=p8UageK_-er9HkjM10ro5@mail.gmail.com>
Hi Kyungmin,
> Tested-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> It's boot and working at mainline.
Thanks for testing this.
> It's just for record.
> Current mainline codes doesn't have full features of s5pv310 (aka
> s5pc210 or exynos4210).
> So I back-ported the same codes to 2.6.36. it's booted and working at
> boot time, but some times later it's hang.
> no serial. I think as irq cores at arm changed, it requires the more
> patched than just this patch.
Interesting. I backported to v2.6.36 and stress-tested it for a few
hours on my versatile express without any problems. If you diagnose
this further, please let me know.
Will
^ permalink raw reply
* [PATCH v3 1/2] ARM: IMX5: cpuidle driver
From: Yong Shen @ 2011-02-23 15:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=VkaCY5u-ibEKWU6=AiRkB5aZwPevY6A3bmk0T@mail.gmail.com>
Hi Sascha,
I noticed there were no comments for v3, but you had comments for v2 which
was posted after v3. See below:
>>I see. Maybe we should make this a platform driver then like for example
>>davinci does.
>I had sent out v3 patch before the your last comments.
>I noticed how davinci is doing, but some SOCs like omap, they also do it in
another way like my code.
>However, if you prefer the way davinci is doing, I will redo it. Please
confirm
Shall we still follow davinci's code?
Thanks
Yong
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110223/510859b3/attachment-0001.html>
^ permalink raw reply
* [PATCH 1/1] davinci: changed SRAM allocator to shared ram.
From: Nori, Sekhar @ 2011-02-23 15:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297434088-27995-1-git-send-email-subhasish@mistralsolutions.com>
Hi Subhasish,
On Fri, Feb 11, 2011 at 19:51:28, Subhasish Ghosh wrote:
> This patch modifies the sram allocator to allocate memory
> from the DA8XX shared RAM.
It will be nice to know if you tried suspend-to-RAM
after this change and found it to be working.
Thanks,
Sekhar
>
> Signed-off-by: Subhasish Ghosh <subhasish@mistralsolutions.com>
> ---
> arch/arm/mach-davinci/da850.c | 6 +++---
> arch/arm/mach-davinci/include/mach/da8xx.h | 1 +
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
> index 3443d97..8a4de97 100644
> --- a/arch/arm/mach-davinci/da850.c
> +++ b/arch/arm/mach-davinci/da850.c
> @@ -711,7 +711,7 @@ static struct map_desc da850_io_desc[] = {
> },
> {
> .virtual = SRAM_VIRT,
> - .pfn = __phys_to_pfn(DA8XX_ARM_RAM_BASE),
> + .pfn = __phys_to_pfn(DA8XX_SHARED_RAM_BASE),
> .length = SZ_8K,
> .type = MT_DEVICE
> },
> @@ -1083,8 +1083,8 @@ static struct davinci_soc_info davinci_soc_info_da850 = {
> .gpio_irq = IRQ_DA8XX_GPIO0,
> .serial_dev = &da8xx_serial_device,
> .emac_pdata = &da8xx_emac_pdata,
> - .sram_dma = DA8XX_ARM_RAM_BASE,
> - .sram_len = SZ_8K,
> + .sram_dma = DA8XX_SHARED_RAM_BASE,
> + .sram_len = SZ_128K,
> .reset_device = &da8xx_wdt_device,
> };
>
> diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
> index cfcb223..c3c3339 100644
> --- a/arch/arm/mach-davinci/include/mach/da8xx.h
> +++ b/arch/arm/mach-davinci/include/mach/da8xx.h
> @@ -70,6 +70,7 @@ extern unsigned int da850_max_speed;
> #define DA8XX_AEMIF_CTL_BASE 0x68000000
> #define DA8XX_DDR2_CTL_BASE 0xb0000000
> #define DA8XX_ARM_RAM_BASE 0xffff0000
> +#define DA8XX_SHARED_RAM_BASE 0x80000000
>
> void __init da830_init(void);
> void __init da850_init(void);
> --
> 1.7.2.3
>
>
^ permalink raw reply
* [PATCH 1/1] da830: macro rename DA8XX_LPSC0_DMAX to DA8XX_LPSC0_PRUSS.
From: Nori, Sekhar @ 2011-02-23 15:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297433905-27925-1-git-send-email-subhasish@mistralsolutions.com>
Hi Subhasish,
Please add a "davinci: " prefix to the subject line of
mach-davinci patches. The patch is not really specific
to DA830.
On Fri, Feb 11, 2011 at 19:48:25, Subhasish Ghosh wrote:
> The PRUSS was named as DMAX on da830 platform.
> This patch resolves the naming conflict by replacing the macro
> DA8XX_LPSC0_DMAX with DA8XX_LPSC0_PRUSS.
This description is inaccurate. Firstly, there is no naming
conflict. DMAX is an internal name for the module which is
known as PRUSS in TI public documentation. This patch just
gets the code in sync with TI documentation.
Can you please update the subject and re-spin this patch?
Thanks,
Sekhar
>
> Signed-off-by: Subhasish Ghosh <subhasish@mistralsolutions.com>
> ---
> arch/arm/mach-davinci/da830.c | 2 +-
> arch/arm/mach-davinci/include/mach/psc.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
> index ec23ab4..0577a5d 100644
> --- a/arch/arm/mach-davinci/da830.c
> +++ b/arch/arm/mach-davinci/da830.c
> @@ -148,7 +148,7 @@ static struct clk scr2_ss_clk = {
> static struct clk dmax_clk = {
> .name = "dmax",
> .parent = &pll0_sysclk2,
> - .lpsc = DA8XX_LPSC0_DMAX,
> + .lpsc = DA8XX_LPSC0_PRUSS,
> .flags = ALWAYS_ENABLED,
> };
>
> diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h
> index 62b0858..a47e6f2 100644
> --- a/arch/arm/mach-davinci/include/mach/psc.h
> +++ b/arch/arm/mach-davinci/include/mach/psc.h
> @@ -150,7 +150,7 @@
> #define DA8XX_LPSC0_SCR0_SS 10
> #define DA8XX_LPSC0_SCR1_SS 11
> #define DA8XX_LPSC0_SCR2_SS 12
> -#define DA8XX_LPSC0_DMAX 13
> +#define DA8XX_LPSC0_PRUSS 13
> #define DA8XX_LPSC0_ARM 14
> #define DA8XX_LPSC0_GEM 15
>
> --
> 1.7.2.3
>
>
^ permalink raw reply
* [PATCH] nmk-gpio: use request_irq instead of chained handler
From: Rabin Vincent @ 2011-02-23 15:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223131805.GK29559@n2100.arm.linux.org.uk>
On Wed, Feb 23, 2011 at 18:48, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 23, 2011 at 06:24:50PM +0530, Rabin Vincent wrote:
>> __nmk_gpio_irq_handler doesn't do anything more that what a normal handler
>> does, so it can become one. ?This is also needed for changing the GIC
>> implementation to a different flow handler.
>
> So you want to allow other people to request the GPIO interrupt?
No, but we request it without IRQF_SHARED so why would other people be
able to do so? If they had done it before, there will be an error here.
> You also want to have the IRQ tracing code called once for entry into
> this handler and once for each GPIO interrupt which is pending?
Because the GPIO interrupts come via a different parent interrupt (the
secondary handler stuff) when in certain low power states, it may be
useful to see which parent the interrupt comes from. Not a deal breaker
though.
> You want to have the overhead of dealing with the inprogress stuff, etc?
>
> I really don't like the idea of getting rid of the interrupt chaining
> and reverting back to the proven-to-be-broken 2.2 kernel way of handing
> this kind of thing - which is exactly what you're doing here.
I thought it was the recommendation in the other thread to have chained
interrupts that do nothing but the normal irq handling to just use that.
With the GIC fasteoi change we will anyway not have the interrupt being
masked. The secondary irq handler chip uses handle_simple_irq so that
should be OK too.
Anyway, I guess there's no strong reason to drop the chained handler,
and we can do without any unnecessary overheads so I will just preserve
the chained handler and do only the eoi here (along with the GIC
conversion).
^ permalink raw reply
* CPU_V6K build failure in next-20110223
From: Russell King - ARM Linux @ 2011-02-23 15:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223144020.GE2796@pulham.picochip.com>
On Wed, Feb 23, 2011 at 02:40:20PM +0000, Jamie Iles wrote:
> Hi Russell,
>
> Building todays next tree for my board (CPU_V6K) results in the
> following build error:
>
> CC arch/arm/kernel/asm-offsets.s
> In file included from /home/jamiei/src/linux-2.6/arch/arm/include/asm/cacheflush.h:15,
> from arch/arm/kernel/asm-offsets.c:16:
> /home/jamiei/src/linux-2.6/arch/arm/include/asm/glue-cache.h:129:2: error: #error Unknown cache maintainence model
> make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
> make: *** [prepare0] Error 2
>
> Building dove_defconfig also results in the same error. The patch below
> appears to fix the issue.
Welcome to the wonderful world of git conflicts with fixes needed in
non-conflicting files...
^ permalink raw reply
* [PATCH v3 7/9] davinci: add spi devices support for MityDSP-L138/MityARM-1808 platform
From: Michael Williamson @ 2011-02-23 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB593024BE4914B@dbde02.ent.ti.com>
On 2/23/2011 9:50 AM, Nori, Sekhar wrote:
> Hi Mike,
>
> On Tue, Feb 22, 2011 at 19:07:02, Michael Williamson wrote:
>
>> +static void __init mityomapl138_init_spi1(struct spi_board_info *info,
>> + unsigned len)
>> +{
>> + int ret;
>> +
>> + ret = spi_register_board_info(info, len);
>> + if (ret)
>> + pr_warning("%s: failed to register board info : %d\n",
>> + __func__, ret);
>> +
>> + da8xx_spi_pdata[1].num_chipselect = len;
>> +
>> + ret = da8xx_register_spi(1);
>> + if (ret)
>> + pr_warning("%s: failed to register spi 1 device : %d\n",
>> + __func__, ret);
>> +}
>
> I missed this previously. We seem to be adding this boilerplate
> evm init function for every board. It will be worthwhile to
> modify the da8xx_register_spi() function to take in the info and
> num_chipselect too. The same function can then be called by each
> evm.
>
> Sorry about trickling in the comments - this should be the last
> one ;) I have added the first five patches of the series to the
> branch here:
>
> http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/next-for-kevin
>
> You can rebase to this branch so you will have to spin only the
> modified patches again.
>
My arm's getting a bit tired from the polishing... I'll resend against
your branch the merged routine.
> Thanks,
> Sekhar
>
^ permalink raw reply
* [PATCH v3 7/9] davinci: add spi devices support for MityDSP-L138/MityARM-1808 platform
From: Nori, Sekhar @ 2011-02-23 14:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298381824-7723-8-git-send-email-michael.williamson@criticallink.com>
Hi Mike,
On Tue, Feb 22, 2011 at 19:07:02, Michael Williamson wrote:
> +static void __init mityomapl138_init_spi1(struct spi_board_info *info,
> + unsigned len)
> +{
> + int ret;
> +
> + ret = spi_register_board_info(info, len);
> + if (ret)
> + pr_warning("%s: failed to register board info : %d\n",
> + __func__, ret);
> +
> + da8xx_spi_pdata[1].num_chipselect = len;
> +
> + ret = da8xx_register_spi(1);
> + if (ret)
> + pr_warning("%s: failed to register spi 1 device : %d\n",
> + __func__, ret);
> +}
I missed this previously. We seem to be adding this boilerplate
evm init function for every board. It will be worthwhile to
modify the da8xx_register_spi() function to take in the info and
num_chipselect too. The same function can then be called by each
evm.
Sorry about trickling in the comments - this should be the last
one ;) I have added the first five patches of the series to the
branch here:
http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/next-for-kevin
You can rebase to this branch so you will have to spin only the
modified patches again.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH 5/8] OMAP2+: hwmod: allow multiple calls to omap_hwmod_init()
From: Cousson, Benoit @ 2011-02-23 14:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223071150.5874.58996.stgit@twilight.localdomain>
On 2/23/2011 8:11 AM, Paul Walmsley wrote:
> There's no longer any reason why we should prevent multiple
> calls to omap_hwmod_init(). It is now simply used to register an
> array of hwmods.
>
> This should allow a subset of hwmods (e.g., hwmods
> handling the system clocksource and clockevents) to be registered
> earlier than the remaining mass of hwmods.
Cool... that one was needed anyway.
It will allow potentially to split the original omapxxx_hwmod list in
severals parts and thus handle the features or the infrastructure hwmods
we need to init early od based on the chip capabilities.
I was considering that during the discussion with Sanjeev
(http://www.spinics.net/lists/linux-omap/msg46716.html).
Benoit
>
> Signed-off-by: Paul Walmsley<paul@pwsan.com>
> Cc: Beno?t Cousson<b-cousson@ti.com>
> Cc: Kevin Hilman<khilman@ti.com>
> ---
> arch/arm/mach-omap2/omap_hwmod.c | 29 ++++++++++-------------------
> 1 files changed, 10 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 41f548e..86eacaf 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -162,9 +162,6 @@ static LIST_HEAD(omap_hwmod_list);
> /* mpu_oh: used to add/remove MPU initiator from sleepdep list */
> static struct omap_hwmod *mpu_oh;
>
> -/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */
> -static u8 inited;
> -
>
> /* Private functions */
>
> @@ -1600,26 +1597,20 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
> */
> int __init omap_hwmod_init(struct omap_hwmod **ohs)
> {
> - struct omap_hwmod *oh;
> - int r;
> -
> - if (inited)
> - return -EINVAL;
> -
> - inited = 1;
> + int r, i;
>
> if (!ohs)
> return 0;
>
> - oh = *ohs;
> - while (oh) {
> - if (omap_chip_is(oh->omap_chip)) {
> - r = _register(oh);
> - WARN(r, "omap_hwmod: %s: _register returned "
> - "%d\n", oh->name, r);
> - }
> - oh = *++ohs;
> - }
> + i = 0;
> + do {
> + if (!omap_chip_is(ohs[i]->omap_chip))
> + continue;
> +
> + r = _register(ohs[i]);
> + WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name,
> + r);
> + } while (ohs[++i]);
>
> return 0;
> }
>
>
^ permalink raw reply
* [PATCH v2 2/5] ARM: imx51/53: add sdhc3/4 clock
From: Richard Zhao @ 2011-02-23 14:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223075036.GE7381@pengutronix.de>
Hi Sascha,
On Wed, Feb 23, 2011 at 08:50:36AM +0100, Sascha Hauer wrote:
> On Tue, Feb 22, 2011 at 06:13:23PM +0800, Richard Zhu wrote:
> > Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
> > ---
> > arch/arm/mach-mx5/clock-mx51-mx53.c | 100 ++++++++++++++++++++++++++++++++++-
> > arch/arm/mach-mx5/crm_regs.h | 7 +++
> > 2 files changed, 106 insertions(+), 1 deletions(-)
> >
> > diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
> > index 8164b1d..2ca97de 100644
> > --- a/arch/arm/mach-mx5/clock-mx51-mx53.c
> > +++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
> > @@ -42,6 +42,9 @@ static struct clk usboh3_clk;
> > static struct clk emi_fast_clk;
> > static struct clk ipu_clk;
> > static struct clk mipi_hsc1_clk;
> > +static struct clk esdhc1_clk;
> > +static struct clk esdhc2_clk;
> > +static struct clk esdhc3_mx53_clk;
> >
> > #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
> >
> > @@ -1138,15 +1141,45 @@ static struct clk ecspi_main_clk = {
> > .set_parent = clk_ecspi_set_parent,
> > };
> >
> > +#define SDHC_SET_PARENT_SHORT(name, parent2, bitsname) \
> > +static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
> > +{ \
> > + u32 reg; \
> > + \
> > + reg = __raw_readl(MXC_CCM_CSCMR1); \
> > + if (parent == &esdhc1_clk) \
> > + reg &= ~MXC_CCM_CSCMR1_##bitsname##_CLK_SEL; \
> > + else if (parent == &parent2) \
> > + reg |= MXC_CCM_CSCMR1_##bitsname##_CLK_SEL; \
> > + else \
> > + return -EINVAL; \
> > + __raw_writel(reg, MXC_CCM_CSCMR1); \
> > + \
> > + return 0; \
> > +}
>
> Please don't do this. I should have rejected this kind of stuff for the
> i.MX23/28. This ## stuff looks short in the source code but expands to
> duplicated binary code.
The macro way is widely used in this file. Happy that it'll get re-structure.
> Also it's hard to make changes in such code.
Yes, and not that readable.
>
> To answer your question about cleaning up the i.MX clock code you asked
> few days ago: Yes, I definitely want to proceed on this once Jeremys
> patches are ready. Then this can become a clock multiplexer consuming
> not much space in both binary and source code.
Looking for that.
>
> For now I suggest that you just duplicate the code in real functions
> without macro voodoo.
ok. I'll re-send the patch.
Thanks
Richard
>
> Sascha
>
> > +
> > /* eSDHC */
> > CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
> > CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
> > CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
> >
> > +/* mx51 specific */
> > CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
> > CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
> > CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
> >
> > +SDHC_SET_PARENT_SHORT(esdhc3, esdhc2_clk, ESDHC3)
> > +SDHC_SET_PARENT_SHORT(esdhc4, esdhc2_clk, ESDHC4)
> > +
> > +/* mx53 specific */
> > +SDHC_SET_PARENT_SHORT(esdhc2_mx53, esdhc3_mx53_clk, ESDHC2_MSHC2_MX53)
> > +
> > +CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
> > +CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
> > +CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
> > +
> > +SDHC_SET_PARENT_SHORT(esdhc4_mx53, esdhc3_mx53_clk, ESDHC4)
> > +
> > #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
> > static struct clk name = { \
> > .id = i, \
> > @@ -1251,9 +1284,62 @@ DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
> > clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
> > DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
> > NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
> > +DEFINE_CLOCK_FULL(esdhc3_ipg_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG4_OFFSET,
> > + NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
> > +DEFINE_CLOCK_FULL(esdhc4_ipg_clk, 3, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG6_OFFSET,
> > + NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
> > +
> > +/* mx51 specific */
> > DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
> > clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
> >
> > +static struct clk esdhc3_clk = {
> > + .id = 2,
> > + .parent = &esdhc1_clk,
> > + .set_parent = clk_esdhc3_set_parent,
> > + .enable_reg = MXC_CCM_CCGR3,
> > + .enable_shift = MXC_CCM_CCGRx_CG5_OFFSET,
> > + .enable = _clk_max_enable,
> > + .disable = _clk_max_disable,
> > + .secondary = &esdhc3_ipg_clk,
> > +};
> > +static struct clk esdhc4_clk = {
> > + .id = 3,
> > + .parent = &esdhc1_clk,
> > + .set_parent = clk_esdhc4_set_parent,
> > + .enable_reg = MXC_CCM_CCGR3,
> > + .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
> > + .enable = _clk_max_enable,
> > + .disable = _clk_max_disable,
> > + .secondary = &esdhc4_ipg_clk,
> > +};
> > +
> > +/* mx53 specific */
> > +static struct clk esdhc2_mx53_clk = {
> > + .id = 2,
> > + .parent = &esdhc1_clk,
> > + .set_parent = clk_esdhc2_mx53_set_parent,
> > + .enable_reg = MXC_CCM_CCGR3,
> > + .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
> > + .enable = _clk_max_enable,
> > + .disable = _clk_max_disable,
> > + .secondary = &esdhc3_ipg_clk,
> > +};
> > +
> > +DEFINE_CLOCK_MAX(esdhc3_mx53_clk, 2, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG5_OFFSET,
> > + clk_esdhc3_mx53, &pll2_sw_clk, &esdhc2_ipg_clk);
> > +
> > +static struct clk esdhc4_mx53_clk = {
> > + .id = 3,
> > + .parent = &esdhc1_clk,
> > + .set_parent = clk_esdhc4_mx53_set_parent,
> > + .enable_reg = MXC_CCM_CCGR3,
> > + .enable_shift = MXC_CCM_CCGRx_CG7_OFFSET,
> > + .enable = _clk_max_enable,
> > + .disable = _clk_max_disable,
> > + .secondary = &esdhc4_ipg_clk,
> > +};
> > +
> > DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
> > DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
> > DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
> > @@ -1312,6 +1398,8 @@ static struct clk_lookup mx51_lookups[] = {
> > _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
> > _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
> > _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
> > + _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
> > + _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_clk)
> > _REGISTER_CLOCK(NULL, "cpu_clk", cpu_clk)
> > _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
> > _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
> > @@ -1332,7 +1420,9 @@ static struct clk_lookup mx53_lookups[] = {
> > _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
> > _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
> > _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
> > - _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
> > + _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_mx53_clk)
> > + _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_mx53_clk)
> > + _REGISTER_CLOCK("sdhci-esdhc-imx.3", NULL, esdhc4_mx53_clk)
> > _REGISTER_CLOCK("imx53-ecspi.0", NULL, ecspi1_clk)
> > _REGISTER_CLOCK("imx53-ecspi.1", NULL, ecspi2_clk)
> > _REGISTER_CLOCK("imx53-cspi.0", NULL, cspi_clk)
> > @@ -1425,6 +1515,14 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
> > mx53_revision();
> > clk_disable(&iim_clk);
> >
> > + /* Set SDHC parents to be PLL2 */
> > + clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
> > + clk_set_parent(&esdhc3_mx53_clk, &pll2_sw_clk);
> > +
> > + /* set SDHC root clock as 200MHZ*/
> > + clk_set_rate(&esdhc1_clk, 200000000);
> > + clk_set_rate(&esdhc3_mx53_clk, 200000000);
> > +
> > /* System timer */
> > mxc_timer_init(&gpt_clk, MX53_IO_ADDRESS(MX53_GPT1_BASE_ADDR),
> > MX53_INT_GPT);
> > diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
> > index b462c22..87c0c58 100644
> > --- a/arch/arm/mach-mx5/crm_regs.h
> > +++ b/arch/arm/mach-mx5/crm_regs.h
> > @@ -217,9 +217,12 @@
> > #define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20)
> > #define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20)
> > #define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19)
> > +#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL (0x1 << 19)
> > #define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18)
> > #define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16)
> > #define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16)
> > +#define MXC_CCM_CSCMR1_ESDHC3_MX53_CLK_SEL_OFFSET (16)
> > +#define MXC_CCM_CSCMR1_ESDHC3_MX53_CLK_SEL_MASK (0x3 << 16)
> > #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
> > #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
> > #define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
> > @@ -271,6 +274,10 @@
> > #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
> > #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
> > #define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
> > +#define MXC_CCM_CSCDR1_ESDHC3_MX53_CLK_PRED_OFFSET (22)
> > +#define MXC_CCM_CSCDR1_ESDHC3_MX53_CLK_PRED_MASK (0x7 << 22)
> > +#define MXC_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_OFFSET (19)
> > +#define MXC_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_MASK (0x7 << 19)
> > #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16)
> > #define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16)
> > #define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
> > --
> > 1.7.1
> >
> >
> >
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* CPU_V6K build failure in next-20110223
From: Jamie Iles @ 2011-02-23 14:40 UTC (permalink / raw)
To: linux-arm-kernel
Hi Russell,
Building todays next tree for my board (CPU_V6K) results in the
following build error:
CC arch/arm/kernel/asm-offsets.s
In file included from /home/jamiei/src/linux-2.6/arch/arm/include/asm/cacheflush.h:15,
from arch/arm/kernel/asm-offsets.c:16:
/home/jamiei/src/linux-2.6/arch/arm/include/asm/glue-cache.h:129:2: error: #error Unknown cache maintainence model
make[1]: *** [arch/arm/kernel/asm-offsets.s] Error 1
make: *** [prepare0] Error 2
Building dove_defconfig also results in the same error. The patch below
appears to fix the issue.
Jamie
8<----
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 0591d35..c7afbc5 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -109,7 +109,7 @@
# define MULTI_CACHE 1
#endif
-#if defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
//# ifdef _CACHE
# define MULTI_CACHE 1
//# else
//
---->8
^ permalink raw reply related
* [PATCH 4/8] OMAP2+: hwmod: find MPU initiator hwmod during in _register()
From: Cousson, Benoit @ 2011-02-23 14:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223071146.5874.15334.stgit@twilight.localdomain>
On 2/23/2011 8:11 AM, Paul Walmsley wrote:
> Move the code that looks for the MPU initiator hwmod to run during
> the individual hwmod _register() function. (Previously, it ran after
> all hwmods were registered in the omap_hwmod_late_init() function.)
>
> This is done so code can late-initialize a few individual hwmods --
> for example, for the system timer -- before the entire set of hwmods is
> initialized later in boot via omap_hwmod_late_init().
>
> Signed-off-by: Paul Walmsley<paul@pwsan.com>
> Cc: Beno?t Cousson<b-cousson@ti.com>
> Cc: Kevin Hilman<khilman@ti.com>
> ---
> arch/arm/mach-omap2/omap_hwmod.c | 23 +++++++++++++++--------
> 1 files changed, 15 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index 9e89a58..41f548e 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -1455,7 +1455,7 @@ static int _setup(struct omap_hwmod *oh, void *data)
> */
> static int __init _register(struct omap_hwmod *oh)
> {
> - int ret, ms_id;
> + int ms_id;
>
> if (!oh || !oh->name || !oh->class || !oh->class->name ||
> (oh->_state != _HWMOD_STATE_UNKNOWN))
> @@ -1478,9 +1478,14 @@ static int __init _register(struct omap_hwmod *oh)
>
> oh->_state = _HWMOD_STATE_REGISTERED;
>
> - ret = 0;
> + /*
> + * XXX Rather than doing a strcmp(), this should test a flag
> + * set in the hwmod data, inserted by the autogenerator code.
What do you mean exactly? Something like a "is_mpu" field set to true
for the mpu?
Since we are enforcing a consistent naming for every hwmods, that looks
like a duplication of the name.
We will always named this hwmod "mpu", so the strcmp() should be enough.
But, maybe I'm missing your point.
Benoit
> + */
> + if (!strcmp(oh->name, MPU_INITIATOR_NAME))
> + mpu_oh = oh;
>
> - return ret;
> + return 0;
> }
>
^ permalink raw reply
* [PATCH 0/8] OMAP2+: hwmod/clockevent: allow late-init of individual hwmods
From: Cousson, Benoit @ 2011-02-23 14:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110223070455.5874.51326.stgit@twilight.localdomain>
Hi Paul,
On 2/23/2011 8:11 AM, Paul Walmsley wrote:
> Hello,
>
> 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
Regards,
Benoit
^ permalink raw reply
* [PATCH v3 2/2] Defines DA850/AM18xx/OMAPL1-38 SOC resources used by PRUSS UIO driver
From: Pratheesh Gangadhar @ 2011-02-23 13:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469161-7644-2-git-send-email-pratheesh@ti.com>
This patch defines PRUSS, ECAP clocks, memory and IRQ resources
used by PRUSS UIO driver in DA850/AM18xx/OMAPL1-38 devices. UIO
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>
---
arch/arm/mach-davinci/board-da850-evm.c | 4 ++
arch/arm/mach-davinci/da850.c | 35 +++++++++++++
arch/arm/mach-davinci/devices-da8xx.c | 73 ++++++++++++++++++++++++++++
arch/arm/mach-davinci/include/mach/da8xx.h | 3 +
4 files changed, 115 insertions(+), 0 deletions(-)
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);
ret = da8xx_register_watchdog();
if (ret)
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,
+};
+
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,
+};
+
static struct clk_lookup da850_clks[] = {
CLK(NULL, "ref", &ref_clk),
CLK(NULL, "pll0", &pll0_clk),
@@ -386,6 +417,7 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "tptc1", &tptc1_clk),
CLK(NULL, "tpcc1", &tpcc1_clk),
CLK(NULL, "tptc2", &tptc2_clk),
+ CLK(NULL, "pruss", &pruss_clk),
CLK(NULL, "uart0", &uart0_clk),
CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk),
@@ -403,6 +435,9 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "aemif", &aemif_clk),
CLK(NULL, "usb11", &usb11_clk),
CLK(NULL, "usb20", &usb20_clk),
+ CLK(NULL, "ecap0", &ecap0_clk),
+ CLK(NULL, "ecap1", &ecap1_clk),
+ CLK(NULL, "ecap2", &ecap2_clk),
CLK(NULL, NULL, NULL),
};
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,
+ .flags = IORESOURCE_MEM,
+ },
+
+ [3] = {
+ .start = IRQ_DA8XX_EVTOUT0,
+ .end = IRQ_DA8XX_EVTOUT0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [4] = {
+ .start = IRQ_DA8XX_EVTOUT1,
+ .end = IRQ_DA8XX_EVTOUT1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [5] = {
+ .start = IRQ_DA8XX_EVTOUT2,
+ .end = IRQ_DA8XX_EVTOUT2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [6] = {
+ .start = IRQ_DA8XX_EVTOUT3,
+ .end = IRQ_DA8XX_EVTOUT3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [7] = {
+ .start = IRQ_DA8XX_EVTOUT4,
+ .end = IRQ_DA8XX_EVTOUT4,
+ .flags = IORESOURCE_IRQ,
+ },
+ [8] = {
+ .start = IRQ_DA8XX_EVTOUT5,
+ .end = IRQ_DA8XX_EVTOUT5,
+ .flags = IORESOURCE_IRQ,
+ },
+ [9] = {
+ .start = IRQ_DA8XX_EVTOUT6,
+ .end = IRQ_DA8XX_EVTOUT6,
+ .flags = IORESOURCE_IRQ,
+ },
+ [10] = {
+ .start = IRQ_DA8XX_EVTOUT7,
+ .end = IRQ_DA8XX_EVTOUT7,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pruss_device = {
+ .name = "pruss",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(pruss_resources),
+ .resource = pruss_resources,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ }
+};
+
+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
#define DA8XX_DDR2_CTL_BASE 0xb0000000
#define DA8XX_ARM_RAM_BASE 0xffff0000
@@ -90,6 +92,7 @@ int da850_register_cpufreq(char *async_clk);
int da8xx_register_cpuidle(void);
void __iomem * __init da8xx_get_mem_ctlr(void);
int da850_register_pm(struct platform_device *pdev);
+int da8xx_register_pruss(void);
extern struct platform_device da8xx_serial_device;
extern struct emac_platform_data da8xx_emac_pdata;
--
1.6.0.6
^ permalink raw reply related
* [PATCH v3 1/2] PRUSS UIO driver support
From: Pratheesh Gangadhar @ 2011-02-23 13:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469161-7644-1-git-send-email-pratheesh@ti.com>
This patch implements PRUSS (Programmable Real-time Unit Sub System)
UIO driver which exports SOC resources associated with PRUSS like
I/O, memories and IRQs to user space. PRUSS is dual 32-bit RISC
processors which is efficient in performing embedded tasks that
require manipulation of packed memory mapped data structures and
efficient in handling system events that have tight real time
constraints. This driver is currently supported on Texas Instruments
DA850, AM18xx and OMAPL1-38 devices.
For example, PRUSS runs firmware for real-time critical industrial
communication data link layer and communicates with application stack
running in user space via shared memory and IRQs.
Signed-off-by: Pratheesh Gangadhar <pratheesh@ti.com>
---
drivers/uio/Kconfig | 17 ++++
drivers/uio/Makefile | 1 +
drivers/uio/uio_pruss.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 241 insertions(+), 0 deletions(-)
create mode 100644 drivers/uio/uio_pruss.c
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index bb44079..6f3ea9b 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -94,4 +94,21 @@ config UIO_NETX
To compile this driver as a module, choose M here; the module
will be called uio_netx.
+config UIO_PRUSS
+ tristate "Texas Instruments PRUSS driver"
+ depends on ARCH_DAVINCI_DA850
+ help
+ PRUSS driver for OMAPL138/DA850/AM18XX devices
+ PRUSS driver requires user space components, examples and user space
+ driver is available from below SVN repo - you may use anonymous login
+
+ https://gforge.ti.com/gf/project/pru_sw/
+
+ More info on API is available at below wiki
+
+ http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader
+
+ To compile this driver as a module, choose M here: the module
+ will be called uio_pruss.
+
endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 18fd818..d4dd9a5 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
obj-$(CONFIG_UIO_NETX) += uio_netx.o
+obj-$(CONFIG_UIO_PRUSS) += uio_pruss.o
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
new file mode 100644
index 0000000..f2b2f4b
--- /dev/null
+++ b/drivers/uio/uio_pruss.c
@@ -0,0 +1,223 @@
+/*
+ * Programmable Real-Time Unit Sub System (PRUSS) UIO driver (uio_pruss)
+ *
+ * This driver exports PRUSS host event out interrupts and PRUSS, L3 RAM,
+ * and DDR RAM to user space for applications interacting with PRUSS firmware
+ *
+ * Copyright (C) 2010-11 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+#define DRV_NAME "pruss"
+#define DRV_VERSION "0.50"
+
+/*
+ * Host event IRQ numbers from PRUSS - PRUSS can generate upto 8 interrupt
+ * events to AINTC of ARM host processor - which can be used for IPC b/w PRUSS
+ * firmware and user space application, async notification from PRU firmware
+ * to user space application
+ * 3 PRU_EVTOUT0
+ * 4 PRU_EVTOUT1
+ * 5 PRU_EVTOUT2
+ * 6 PRU_EVTOUT3
+ * 7 PRU_EVTOUT4
+ * 8 PRU_EVTOUT5
+ * 9 PRU_EVTOUT6
+ * 10 PRU_EVTOUT7
+*/
+
+#define MAX_PRUSS_EVTOUT_INSTANCE 8
+
+#define PINTC_HIPIR 0x4900
+#define PINTC_HIPIR_NO_PEND_MASK 0x80000000
+#define PINTC_HIER 0x5500
+
+struct clk *pruss_clk;
+struct uio_info *info;
+void *ddr_virt_addr = NULL, *prussio_virt_addr = NULL;
+dma_addr_t ddr_phy_addr;
+
+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 intren_regval = ioread32(intren_reg), intr_mask = (1 << (irq - 1));
+
+ /* Is interrupt enabled and active ? */
+ if (!(intren_regval & intr_mask)
+ && (ioread32(intrstat_reg) & PINTC_HIPIR_NO_PEND_MASK))
+ return IRQ_NONE;
+
+ /* Disable interrupt */
+ iowrite32((intren_regval & ~intr_mask), intren_reg);
+ return IRQ_HANDLED;
+}
+
+static void pruss_cleanup(struct platform_device *dev, struct uio_info *info)
+{
+ int count;
+ struct uio_info *p;
+
+ for (count = 0, p = info; count < MAX_PRUSS_EVTOUT_INSTANCE;
+ count++, p++) {
+ uio_unregister_device(p);
+ kfree(p->name);
+ }
+ iounmap(prussio_virt_addr);
+ dma_free_coherent(&dev->dev, info[0].mem[2].size,
+ info[0].mem[2].internal_addr, info[0].mem[2].addr);
+
+ kfree(info);
+ clk_put(pruss_clk);
+}
+
+static int __devinit pruss_probe(struct platform_device *dev)
+{
+ int ret = -ENODEV, count = 0;
+ struct resource *regs_prussio, *regs_l3ram, *regs_ddr;
+ struct uio_info *p;
+
+ info = kzalloc(sizeof(struct uio_info) * MAX_PRUSS_EVTOUT_INSTANCE,
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ /* Power on PRU in case its not done as part of boot-loader */
+ pruss_clk = clk_get(&dev->dev, "pruss");
+ if (IS_ERR(pruss_clk)) {
+ dev_err(&dev->dev, "Failed to get clock\n");
+ ret = PTR_ERR(pruss_clk);
+ return ret;
+ } else {
+ clk_enable(pruss_clk);
+ }
+
+ regs_prussio = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!regs_prussio) {
+ dev_err(&dev->dev, "No PRUSS I/O resource specified\n");
+ goto out_free;
+ }
+
+ regs_l3ram = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ if (!regs_l3ram) {
+ dev_err(&dev->dev, "No L3 RAM resource specified\n");
+ goto out_free;
+ }
+
+ regs_ddr = platform_get_resource(dev, IORESOURCE_MEM, 2);
+ if (!regs_ddr) {
+ dev_err(&dev->dev, "No External RAM resource specified\n");
+ goto out_free;
+ }
+
+ if (!regs_prussio->start || !regs_l3ram->start) {
+ dev_err(&dev->dev, "Invalid memory resource\n");
+ goto out_free;
+ }
+
+ ddr_virt_addr =
+ dma_alloc_coherent(&dev->dev, regs_ddr->end - regs_ddr->start + 1,
+ &ddr_phy_addr, GFP_KERNEL | GFP_DMA);
+ if (!ddr_virt_addr) {
+ dev_err(&dev->dev, "Could not allocate external memory\n");
+ goto out_free;
+ }
+
+ prussio_virt_addr =
+ ioremap(regs_prussio->start,
+ regs_prussio->end - regs_prussio->start + 1);
+ if (prussio_virt_addr) {
+ dev_err(&dev->dev, "Can't remap PRUSS I/O address range\n");
+ goto out_free;
+ }
+
+ for (count = 0, p = info; count < MAX_PRUSS_EVTOUT_INSTANCE;
+ count++, p++) {
+ p->mem[0].internal_addr = prussio_virt_addr;
+ p->mem[0].addr = regs_prussio->start;
+ p->mem[0].size = regs_prussio->end - regs_prussio->start + 1;
+ p->mem[0].memtype = UIO_MEM_PHYS;
+
+ p->mem[1].addr = regs_l3ram->start;
+ p->mem[1].size = regs_l3ram->end - regs_l3ram->start + 1;
+ p->mem[1].memtype = UIO_MEM_PHYS;
+
+ p->mem[2].internal_addr = ddr_virt_addr;
+ p->mem[2].addr = ddr_phy_addr;
+ p->mem[2].size = regs_ddr->end - regs_ddr->start + 1;
+ p->mem[2].memtype = UIO_MEM_PHYS;
+
+ p->name = kasprintf(GFP_KERNEL, "pruss_evt%d", count);
+ p->version = "0.50";
+
+ /* Register PRUSS IRQ lines */
+ p->irq = IRQ_DA8XX_EVTOUT0 + count;
+ p->handler = pruss_handler;
+
+ ret = uio_register_device(&dev->dev, p);
+
+ if (ret < 0)
+ goto out_free;
+ }
+
+ platform_set_drvdata(dev, info);
+ return 0;
+
+out_free:
+ pruss_cleanup(dev, info);
+ return ret;
+}
+
+static int __devexit pruss_remove(struct platform_device *dev)
+{
+ struct uio_info *info = platform_get_drvdata(dev);
+
+ pruss_cleanup(dev, info);
+ platform_set_drvdata(dev, NULL);
+ return 0;
+}
+
+static struct platform_driver pruss_driver = {
+ .probe = pruss_probe,
+ .remove = __devexit_p(pruss_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init pruss_init_module(void)
+{
+ return platform_driver_register(&pruss_driver);
+}
+
+module_init(pruss_init_module);
+
+static void __exit pruss_exit_module(void)
+{
+ platform_driver_unregister(&pruss_driver);
+}
+
+module_exit(pruss_exit_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR("Amit Chatterjee <amit.chatterjee@ti.com>");
+MODULE_AUTHOR("Pratheesh Gangadhar <pratheesh@ti.com>");
--
1.6.0.6
^ permalink raw reply related
* [PATCH v3 0/2] Add PRUSS UIO driver support
From: Pratheesh Gangadhar @ 2011-02-23 13:52 UTC (permalink / raw)
To: linux-arm-kernel
This patch series add support for PRUSS (Programmable Real-time Unit Sub
System) UIO driver in Texas Instruments DA850, AM18xx and OMAPL1-38 processors.
PRUSS is programmable RISC core which can be used to implement Soft IPs
(eg:- DMA, CAN, UART,SmartCard) and Industrial communications data link layers
(eg:- PROFIBUS). UIO driver exposes PRUSS resources like memory and interrupts
to user space application.PRUSS UIO application API can be used to control PRUs
in PRUSS, setup PRU INTC, load firmware to PRUs and implement IPC between Host
processor and PRUs. More information on PRUSS and UIO linux user space API
available in the links below
http://processors.wiki.ti.com/index.php/Programmable_Realtime_Unit_Subsystem
http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader
http://processors.wiki.ti.com/index.php/PRU_Linux_Application_Loader_API_Guide
Pratheesh Gangadhar (2):
PRUSS UIO driver support
Defines DA850/AM18xx/OMAPL1-38 SOC resources used by PRUSS UIO driver
arch/arm/mach-davinci/board-da850-evm.c | 4 +
arch/arm/mach-davinci/da850.c | 35 +++++
arch/arm/mach-davinci/devices-da8xx.c | 73 +++++++++
arch/arm/mach-davinci/include/mach/da8xx.h | 3 +
drivers/uio/Kconfig | 17 ++
drivers/uio/Makefile | 1 +
drivers/uio/uio_pruss.c | 223 ++++++++++++++++++++++++++++
7 files changed, 356 insertions(+), 0 deletions(-)
create mode 100644 drivers/uio/uio_pruss.c
^ permalink raw reply
* [PATCH 5/5] arm: mach-mx3: use IMX_GPIO_NR instead of hard-coded values
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>
The latter are error-prone because the bank number is one less than one
would read in the documentation.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Eric Benard <eric@eukrea.com>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c | 4 ++--
arch/arm/mach-mx3/mach-cpuimx35.c | 2 +-
arch/arm/mach-mx3/mach-pcm043.c | 10 +++++-----
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
index 14a5ffc..8076147 100644
--- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
@@ -165,8 +165,8 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
};
-#define GPIO_LED1 (2 * 32 + 29)
-#define GPIO_SWITCH1 (2 * 32 + 25)
+#define GPIO_LED1 IMX_GPIO_NR(3, 29)
+#define GPIO_SWITCH1 IMX_GPIO_NR(3, 25)
#define GPIO_LCDPWR (4)
static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
index 26ae90f..892c3a9 100644
--- a/arch/arm/mach-mx3/mach-cpuimx35.c
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -60,7 +60,7 @@ static struct tsc2007_platform_data tsc2007_info = {
.x_plate_ohms = 180,
};
-#define TSC2007_IRQGPIO (2 * 32 + 2)
+#define TSC2007_IRQGPIO IMX_GPIO_NR(3, 2)
static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51),
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index 26b686c..51542f7 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -224,12 +224,12 @@ static iomux_v3_cfg_t pcm043_pads[] = {
MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
};
-#define AC97_GPIO_TXFS (1 * 32 + 31)
-#define AC97_GPIO_TXD (1 * 32 + 28)
-#define AC97_GPIO_RESET (1 * 32 + 0)
+#define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31)
+#define AC97_GPIO_TXD IMX_GPIO_NR(2, 28)
+#define AC97_GPIO_RESET IMX_GPIO_NR(2, 0)
-#define SD1_GPIO_WP (1 * 32 + 23)
-#define SD1_GPIO_CD (1 * 32 + 24)
+#define SD1_GPIO_WP IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD IMX_GPIO_NR(2, 24)
static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
{
--
1.7.2.3
^ permalink raw reply related
* [PATCH 4/5] arm: mach-mx3: pcm043: add write-protect and card-detect for SD1
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-mx3/mach-pcm043.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index bcf83fc..26b686c 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -40,6 +40,7 @@
#include <mach/mx3fb.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
+#include <mach/esdhc.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -219,12 +220,17 @@ static iomux_v3_cfg_t pcm043_pads[] = {
MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+ MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
};
#define AC97_GPIO_TXFS (1 * 32 + 31)
#define AC97_GPIO_TXD (1 * 32 + 28)
#define AC97_GPIO_RESET (1 * 32 + 0)
+#define SD1_GPIO_WP (1 * 32 + 23)
+#define SD1_GPIO_CD (1 * 32 + 24)
+
static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
{
iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
@@ -307,6 +313,11 @@ pcm037_nand_board_info __initconst = {
.hw_ecc = 1,
};
+static struct esdhc_platform_data sd1_pdata = {
+ .wp_gpio = SD1_GPIO_WP,
+ .cd_gpio = SD1_GPIO_CD,
+};
+
#if defined(CONFIG_USB_ULPI)
static struct mxc_usbh_platform_data otg_pdata __initdata = {
.portsc = MXC_EHCI_MODE_UTMI,
@@ -393,7 +404,7 @@ static void __init mxc_board_init(void)
imx35_add_fsl_usb2_udc(&otg_device_pdata);
imx35_add_flexcan1(NULL);
- imx35_add_sdhci_esdhc_imx(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
}
static void __init pcm043_timer_init(void)
--
1.7.2.3
^ permalink raw reply related
* [PATCH 3/5] mmc: sdhci-esdhc-imx: add card detect on custom GPIO
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Marc Reilly <marc@cpdesign.com.au>
Tested-by: Eric Benard <eric@eukrea.com>
---
change since last version:
* improve kerneldoc
* intercept SDHCI_SIGNAL_ENABLE, too (mx25)
* remove BROKEN_CARD_DETECTION as default quirk
arch/arm/plat-mxc/include/mach/esdhc.h | 2 +
drivers/mmc/host/sdhci-esdhc-imx.c | 79 +++++++++++++++++++++++++++++++-
2 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
index 47da109..86003f4 100644
--- a/arch/arm/plat-mxc/include/mach/esdhc.h
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -16,9 +16,11 @@
* strongly recommended for i.MX25/35, not needed for other variants
*
* @wp_gpio: gpio for write_protect (-EINVAL if unused)
+ * @cd_gpio: gpio for card_detect interrupt (-EINVAL if unused)
*/
struct esdhc_platform_data {
unsigned int wp_gpio;
+ unsigned int cd_gpio;
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 49c9801..353fc63 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -32,6 +32,39 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
}
+static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
+{
+ /* fake CARD_PRESENT flag on mx25/35 */
+ u32 val = readl(host->ioaddr + reg);
+
+ if (unlikely(reg == SDHCI_PRESENT_STATE)) {
+ struct esdhc_platform_data *boarddata =
+ host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->cd_gpio)
+ && gpio_get_value(boarddata->cd_gpio))
+ /* no card, if a valid gpio says so... */
+ val &= SDHCI_CARD_PRESENT;
+ else
+ /* ... in all other cases assume card is present */
+ val |= SDHCI_CARD_PRESENT;
+ }
+
+ return val;
+}
+
+static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
+{
+ if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))
+ /*
+ * these interrupts won't work with a custom card_detect gpio
+ * (only applied to mx25/35)
+ */
+ val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+
+ writel(val, host->ioaddr + reg);
+}
+
static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
{
if (unlikely(reg == SDHCI_HOST_VERSION))
@@ -121,6 +154,14 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.get_min_clock = esdhc_pltfm_get_min_clock,
};
+static irqreturn_t cd_irq(int irq, void *data)
+{
+ struct sdhci_host *sdhost = (struct sdhci_host *)data;
+
+ tasklet_schedule(&sdhost->card_tasklet);
+ return IRQ_HANDLED;
+};
+
static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -142,6 +183,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
if (cpu_is_mx25() || cpu_is_mx35()) {
/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+ /* card_detect can't be routed to controller, mark broken */
+ host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
/* write_protect can't be routed to controller, use gpio */
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
}
@@ -153,9 +196,35 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
"no write-protect pin available!\n");
boarddata->wp_gpio = err;
}
+
+ err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
+ if (err) {
+ dev_warn(mmc_dev(host->mmc),
+ "no card-detect pin available!\n");
+ goto no_card_detect_pin;
+ }
+
+ err = request_irq(gpio_to_irq(boarddata->cd_gpio), cd_irq,
+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+ mmc_hostname(host->mmc), host);
+ if (err) {
+ dev_warn(mmc_dev(host->mmc), "request irq error\n");
+ goto no_card_detect_irq;
+ }
+
+ sdhci_esdhc_ops.write_l = esdhc_writel_le;
+ sdhci_esdhc_ops.read_l = esdhc_readl_le;
+ /* Now we have a working card_detect again */
+ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
return 0;
+
+ no_card_detect_irq:
+ gpio_free(boarddata->cd_gpio);
+ no_card_detect_pin:
+ boarddata->cd_gpio = err;
+ return 0;
}
static void esdhc_pltfm_exit(struct sdhci_host *host)
@@ -166,13 +235,19 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
gpio_free(boarddata->wp_gpio);
+ if (boarddata && gpio_is_valid(boarddata->cd_gpio)) {
+ gpio_free(boarddata->cd_gpio);
+
+ if (!(host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION))
+ free_irq(gpio_to_irq(boarddata->cd_gpio), host);
+ }
+
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
- | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
/* ADMA has issues. Might be fixable */
.ops = &sdhci_esdhc_ops,
.init = esdhc_pltfm_init,
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/5] mmc: sdhci-esdhc: broken card detection is not a default quirk
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>
It can be worked around using a GPIO which will be done for i.MX later.
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Acked-by: Anton Vorontsov <cbouatmailru@gmail.com>
Tested-by: Marc Reilly <marc@cpdesign.com.au>
Tested-by: Eric Benard <eric@eukrea.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 3 ++-
drivers/mmc/host/sdhci-esdhc.h | 1 -
drivers/mmc/host/sdhci-of-esdhc.c | 3 ++-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 65df00b..49c9801 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -171,7 +171,8 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA
+ | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
/* ADMA has issues. Might be fixable */
.ops = &sdhci_esdhc_ops,
.init = esdhc_pltfm_init,
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index afaf1bc..c55aae8 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -19,7 +19,6 @@
*/
#define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
- SDHCI_QUIRK_BROKEN_CARD_DETECTION | \
SDHCI_QUIRK_NO_BUSY_IRQ | \
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index fcd0e1f..08161f6 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -73,7 +73,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
}
struct sdhci_of_data sdhci_esdhc = {
- .quirks = ESDHC_DEFAULT_QUIRKS,
+ /* card detection could be handled via GPIO */
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
.ops = {
.read_l = sdhci_be32bs_readl,
.read_w = esdhc_readw,
--
1.7.2.3
^ permalink raw reply related
* [PATCH 1/5] mmc: sdhci-esdhc-imx: add support for write protect on custom GPIO
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298469118-25282-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Tested-by: Marc Reilly <marc@cpdesign.com.au>
Tested-by: Eric Benard <eric@eukrea.com>
---
change since last version:
* improve kerneldoc
arch/arm/plat-mxc/include/mach/esdhc.h | 10 +++++-
drivers/mmc/host/sdhci-esdhc-imx.c | 52 +++++++++++++++++++++++++-------
2 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
index a48a9aa..47da109 100644
--- a/arch/arm/plat-mxc/include/mach/esdhc.h
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -10,7 +10,15 @@
#ifndef __ASM_ARCH_IMX_ESDHC_H
#define __ASM_ARCH_IMX_ESDHC_H
+/**
+ * struct esdhc_platform_data - optional platform data for esdhc on i.MX
+ *
+ * strongly recommended for i.MX25/35, not needed for other variants
+ *
+ * @wp_gpio: gpio for write_protect (-EINVAL if unused)
+ */
+
struct esdhc_platform_data {
- unsigned int wp_gpio; /* write protect pin */
+ unsigned int wp_gpio;
};
#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 9b82910..65df00b 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -15,9 +15,11 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
#include <mach/hardware.h>
+#include <mach/esdhc.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
@@ -100,10 +102,31 @@ static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
return clk_get_rate(pltfm_host->clk) / 256 / 16;
}
+static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
+{
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+ return gpio_get_value(boarddata->wp_gpio);
+ else
+ return -ENOSYS;
+}
+
+static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_w = esdhc_readw_le,
+ .write_w = esdhc_writew_le,
+ .write_b = esdhc_writeb_le,
+ .set_clock = esdhc_set_clock,
+ .get_max_clock = esdhc_pltfm_get_max_clock,
+ .get_min_clock = esdhc_pltfm_get_min_clock,
+};
+
static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pdata)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
struct clk *clk;
+ int err;
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
@@ -116,9 +139,21 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
if (cpu_is_mx35() || cpu_is_mx51())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
- /* Fix errata ENGcm07207 which is present on i.MX25 and i.MX35 */
- if (cpu_is_mx25() || cpu_is_mx35())
+ if (cpu_is_mx25() || cpu_is_mx35()) {
+ /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
+ /* write_protect can't be routed to controller, use gpio */
+ sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
+ }
+
+ if (boarddata) {
+ err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
+ if (err) {
+ dev_warn(mmc_dev(host->mmc),
+ "no write-protect pin available!\n");
+ boarddata->wp_gpio = err;
+ }
+ }
return 0;
}
@@ -126,20 +161,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
static void esdhc_pltfm_exit(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+
+ if (boarddata && gpio_is_valid(boarddata->wp_gpio))
+ gpio_free(boarddata->wp_gpio);
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
}
-static struct sdhci_ops sdhci_esdhc_ops = {
- .read_w = esdhc_readw_le,
- .write_w = esdhc_writew_le,
- .write_b = esdhc_writeb_le,
- .set_clock = esdhc_set_clock,
- .get_max_clock = esdhc_pltfm_get_max_clock,
- .get_min_clock = esdhc_pltfm_get_min_clock,
-};
-
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA,
/* ADMA has issues. Might be fixable */
--
1.7.2.3
^ permalink raw reply related
* [PATCH V3 0/5] sdhci-esdhc-imx: use gpio for write protection and card detection
From: Wolfram Sang @ 2011-02-23 13:51 UTC (permalink / raw)
To: linux-arm-kernel
Take #3, changes:
* also intercept calls to SDHCI_SIGNAL_ENABLE (needed on mx25)
* remove unconditional BROKEN_CARD_DETECTION (leftover)
* improved kernel-doc about unused GPIO
* added tags from Eric
Tested now by me and Marc on mx35, Eric on mx25/35/51. Arnaud, did you have a
chance to retest on mx51? What about the FSL guys? :)
Regards,
Wolfram
Wolfram Sang (5):
mmc: sdhci-esdhc-imx: add support for write protect on custom GPIO
mmc: sdhci-esdhc: broken card detection is not a default quirk
mmc: sdhci-esdhc-imx: add card detect on custom GPIO
arm: mach-mx3: pcm043: add write-protect and card-detect for SD1
arm: mach-mx3: use IMX_GPIO_NR instead of hard-coded values
arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c | 4 +-
arch/arm/mach-mx3/mach-cpuimx35.c | 2 +-
arch/arm/mach-mx3/mach-pcm043.c | 19 +++-
arch/arm/plat-mxc/include/mach/esdhc.h | 12 ++-
drivers/mmc/host/sdhci-esdhc-imx.c | 128 +++++++++++++++++++++++--
drivers/mmc/host/sdhci-esdhc.h | 1 -
drivers/mmc/host/sdhci-of-esdhc.c | 3 +-
7 files changed, 148 insertions(+), 21 deletions(-)
--
1.7.2.3
^ permalink raw reply
* [PATCH v3 2/2] OMAP: IOMMU: add support to callback during fault handling
From: Guzman Lugo, Fernando @ 2011-02-23 13:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=C01Yf9rQN1uxMptFyOrwqxJWt+quJ8ipiM+k6@mail.gmail.com>
On Wed, Feb 23, 2011 at 3:45 AM, David Cohen <dacohen@gmail.com> wrote:
> On Wed, Feb 23, 2011 at 3:17 AM, Guzman Lugo, Fernando
> <fernando.lugo@ti.com> wrote:
>> On Wed, Feb 16, 2011 at 1:35 PM, David Cohen <dacohen@gmail.com> wrote:
>>> Add support to register an isr for IOMMU fault situations and adapt it
>>> to allow such (*isr)() to be used as fault callback. Drivers using IOMMU
>>> module might want to be informed when errors happen in order to debug it
>>> or react.
>>>
>>> Signed-off-by: David Cohen <dacohen@gmail.com>
>>> ---
>>> ?arch/arm/mach-omap2/iommu2.c ? ? ? ? ? ?| ? 17 +++++++++-
>>> ?arch/arm/plat-omap/include/plat/iommu.h | ? 14 ++++++++-
>>> ?arch/arm/plat-omap/iommu.c ? ? ? ? ? ? ?| ? 52 ++++++++++++++++++++++---------
>>> ?3 files changed, 65 insertions(+), 18 deletions(-)
>>>
>> ....
>>
>>> @@ -917,6 +912,33 @@ void iommu_put(struct iommu *obj)
>>> ?}
>>> ?EXPORT_SYMBOL_GPL(iommu_put);
>>>
>>> +int iommu_set_isr(const char *name,
>>> + ? ? ? ? ? ? ? ? int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs,
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?void *priv),
>>> + ? ? ? ? ? ? ? ? void *isr_priv)
>>> +{
>>> + ? ? ? struct device *dev;
>>> + ? ? ? struct iommu *obj;
>>> +
>>
>> if the driver support multiple user for the same iommu why can only
>> one callback be registered? should it support register multiple
>> callback function (one per user)?
>
> Can you define a scenario for that?
> On OMAP3 ISP the multiple users are the multiple ISP submodule, but I
> don't think it's necessary all submodule to have a specific callback.
> ISP core layer should handle.
Hi,
In OMAP4 the cortex M3 is a double core processor and as each core is
running they own version of the RTOS we threat them independently. So
our driver which controls the remote processor sees two processor but
both use the same iommu hw. When a iommu fault happens, at this
moment, it is consider as a faltal error and it is no managed to
recover and continue, instead a restart of the processor is needed, if
the fault happens in core0 we need to reset core1 too and vice versa.
if the iommu would support several user callbacks, we can register the
callback which resets core0 and also the callback which resets core1
and treat them as totally independent processors. Also we have an
error event notifier driver, which is only in charge of notifying
error events to userspace, so we would have multiple callbacks we
could do this
iommu <---- register fault callback for error notify driver
instead of
iommu <--- register fault callback for remote processor driver
<----register fault event for error notify driver.
with that, we remove one dependency of the errornotify driver.
Moreover, the iommu code support serveral users of the same hw iommu,
and it does not make sense for me, that you can register only one
callback, or if other user register its callback the previous one will
be overwritten.
Regards,
Fernando.
>
> Br,
>
> David
>
>>
>> Regards,
>> Fernando.
>>
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox