* [patch 47/75] arm: tegra: Remove unused function which fiddles with irq_desc
From: Thomas Gleixner @ 2011-02-10 23:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110210222908.661199947@linutronix.de>
An embedded and charset-unspecified text was scrubbed...
Name: arm-tegra.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110210/f5bcbf8a/attachment.ksh>
^ permalink raw reply
* [patch 20/75] arm: Ns9xxx: Remove private irq flow handler
From: Thomas Gleixner @ 2011-02-10 23:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110210222908.661199947@linutronix.de>
An embedded and charset-unspecified text was scrubbed...
Name: arm-ns9xxx-remove-private-irq-flow-handler.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110210/6d23cb43/attachment.ksh>
^ permalink raw reply
* [RFC,PATCH 2/3] clk: Generic support for fixed-rate clocks
From: Ryan Mallon @ 2011-02-10 23:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297233693.242725.820672531799.2.gpush@pororo>
On 02/09/2011 07:41 PM, Jeremy Kerr wrote:
> Since most platforms will need a fixed-rate clock, add one. This will
> also serve as a basic example of an implementation of struct clk.
>
> Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
>
> ---
> drivers/clk/clk.c | 14 ++++++++++++++
> include/linux/clk.h | 16 ++++++++++++++++
> 2 files changed, 30 insertions(+)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index c35478a..bbbdb0d 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -124,3 +124,17 @@ void __clk_put(struct clk *clk)
> if (clk->ops->put)
> clk->ops->put(clk);
> }
> +
> +/* clk_fixed support */
> +
> +#define to_clk_fixed(clk) (container_of(clk, struct clk_fixed, clk))
> +
> +static unsigned long clk_fixed_get_rate(struct clk *clk)
> +{
> + return to_clk_fixed(clk)->rate;
> +}
> +
> +struct clk_ops clk_fixed_ops = {
> + .get_rate = clk_fixed_get_rate,
> +};
> +EXPORT_SYMBOL_GPL(clk_fixed_ops);
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index fe806b7..e67fdb0 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -185,6 +185,22 @@ static inline void clk_common_init(struct clk *clk)
> mutex_init(&clk->prepare_lock);
> }
>
> +/* Simple fixed-rate clock */
> +struct clk_fixed {
> + struct clk clk;
> + unsigned long rate;
> +};
> +
> +extern struct clk_ops clk_fixed_ops;
> +
> +#define INIT_CLK_FIXED(name, r) { \
> + .clk = INIT_CLK(name.clk, clk_fixed_ops), \
> + .rate = (r) \
> +}
A fixed clock may still have other operations such as enable/disable.
Maybe do something like this instead:
#define INIT_CLK_FIXED(name, ops, r) { \
.clk = INIT_CLK(name.clk, ops, rate), \
.clk.ops.get_rate = clk_fixed_get_rate, \
.rate = (r), \
}
That's untested though. I'm not sure if you can reliably assign
something twice in a struct initialiser?
~Ryan
--
Bluewater Systems Ltd - ARM Technology Solution Centre
Ryan Mallon 5 Amuri Park, 404 Barbadoes St
ryan at bluewatersys.com PO Box 13 889, Christchurch 8013
http://www.bluewatersys.com New Zealand
Phone: +64 3 3779127 Freecall: Australia 1800 148 751
Fax: +64 3 3779135 USA 1800 261 2934
^ permalink raw reply
* [PATCH] OMAP2/3: PM: remove unnecessary wakeup/sleep dependency clear
From: Paul Walmsley @ 2011-02-10 23:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <871v3ffps6.fsf@ti.com>
Hi Kevin,
On Thu, 10 Feb 2011, Kevin Hilman wrote:
> While testing, I found out this patch breaks suspend/resume and idle on
> at least 34xx.
>
> A first suspend/resume works fine, but on subsequent ones SGX
> powerdomain does not hit retention (and thus CORE powerdomain does not
> either....
...
> Simply adding back the above 5 lines (the SGX ones) gets things working
> again, which suggests something isn't quite right with SGX, but I
> haven't found the exact reason yet.
Thanks for the report, I will take a look.
- Paul
^ permalink raw reply
* [PATCH] OMAP2/3: PM: remove unnecessary wakeup/sleep dependency clear
From: Kevin Hilman @ 2011-02-10 23:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <871v3yp5km.fsf@ti.com>
Hi Paul,
Kevin Hilman <khilman@ti.com> writes:
> Paul Walmsley <paul@pwsan.com> writes:
>
>> The OMAP2 and OMAP3 PM code clears clockdomain wakeup and sleep
>> dependencies. This is unnecessary after commit
>> 6f7f63cc9adf3192e6fcac4e8bed5cc10fd924aa ("OMAP clockdomain:
>> initialize clockdomain registers when the clockdomain layer starts")
>> which clears these dependencies during clockdomain init.
>>
>> Signed-off-by: Paul Walmsley <paul@pwsan.com>
>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>> ---
>> Full-chip retention idle entry tested on OMAP35xx Beagleboard.
>
> Also tested on 3630/Zoom3.
>
> Queueing for 2.6.39. Thanks,
>
While testing, I found out this patch breaks suspend/resume and idle on
at least 34xx.
A first suspend/resume works fine, but on subsequent ones SGX
powerdomain does not hit retention (and thus CORE powerdomain does not
either....
More below...
>
>> arch/arm/mach-omap2/pm24xx.c | 8 +-------
>> arch/arm/mach-omap2/pm34xx.c | 15 ---------------
>> 2 files changed, 1 insertions(+), 22 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
>> index 97feb3a..10f8747 100644
>> --- a/arch/arm/mach-omap2/pm24xx.c
>> +++ b/arch/arm/mach-omap2/pm24xx.c
>> @@ -363,9 +363,6 @@ static const struct platform_suspend_ops __initdata omap_pm_ops;
>> /* XXX This function should be shareable between OMAP2xxx and OMAP3 */
>> static int __init clkdms_setup(struct clockdomain *clkdm, void *unused)
>> {
>> - clkdm_clear_all_wkdeps(clkdm);
>> - clkdm_clear_all_sleepdeps(clkdm);
>> -
>> if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
>> omap2_clkdm_allow_idle(clkdm);
>> else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
>> @@ -411,10 +408,7 @@ static void __init prcm_setup_regs(void)
>> pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF);
>> omap2_clkdm_sleep(gfx_clkdm);
>>
>> - /*
>> - * Clear clockdomain wakeup dependencies and enable
>> - * hardware-supervised idle for all clkdms
>> - */
>> + /* Enable hardware-supervised idle for all clkdms */
>> clkdm_for_each(clkdms_setup, NULL);
>> clkdm_add_wkdep(mpu_clkdm, wkup_clkdm);
>>
>> diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
>> index a4aa192..0eb9738 100644
>> --- a/arch/arm/mach-omap2/pm34xx.c
>> +++ b/arch/arm/mach-omap2/pm34xx.c
>> @@ -694,21 +694,6 @@ static void __init prcm_setup_regs(void)
>> u32 omap3630_grpsel_uart4_mask = cpu_is_omap3630() ?
>> OMAP3630_GRPSEL_UART4_MASK : 0;
>>
>> -
>> - /* XXX Reset all wkdeps. This should be done when initializing
>> - * powerdomains */
>> - omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
>> - if (omap_rev() > OMAP3430_REV_ES1_0) {
>> - omap2_prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
>> - omap2_prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
>> - } else
>> - omap2_prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
Simply adding back the above 5 lines (the SGX ones) gets things working
again, which suggests something isn't quite right with SGX, but I
haven't found the exact reason yet.
Kevin
>> /*
>> * Enable interface clock autoidle for all modules.
>> * Note that in the long run this should be done by clockfw
^ permalink raw reply
* [PATCH 1/5] mmc: sdhci-esdhc-imx: add support for write protect on custom GPIO
From: Marc Reilly @ 2011-02-10 22:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-2-git-send-email-w.sang@pengutronix.de>
Hi Wolfram,
First three patches work well on my vpr200 board (mx35).
One comment inline...
I ran some tests of insert/remove card with the card locked and unlocked, and
trying to append a file. It behaved as expected, thus:
Tested-by: Marc Reilly <marc@cpdesign.com.au>
> +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;
> +}
> +
..snip..
> @@ -116,9 +139,20 @@ 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) {
Perhaps (boarddata && gpio_is_valid(boarddata->wp_gpio) as above?
For example what if someone sets up the boarddata for a card detect, but not
write protect.
> + err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
> + if (err) {
> + dev_warn(mmc_dev(host->mmc), "can't get wp_pin!\n");
> + boarddata->wp_gpio = err;
> + }
> + }
>
> return 0;
> }
Cheers,
Marc
^ permalink raw reply
* [PATCH v2 5/5] ARM: omap3: Thumb-2 compatibility for sleep34xx.S
From: Kevin Hilman @ 2011-02-10 22:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1296756161-26092-6-git-send-email-dave.martin@linaro.org>
Dave Martin <dave.martin@linaro.org> writes:
> * Use BSYM() to get the correct Thumb branch address
> for adr <Rd>, <label>
>
> * Fix an out-of-range ADR when building for ARM
>
> * Correctly call es3_sdrc_fix as Thumb when copied to SRAM.
>
> * Remove deprecated/undefined PC-relative stores
>
> * Add the required ENDPROC() directive for each ENTRY().
>
> * .align before data words
>
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
I'm attempting to test this series with OMAP PM, but some changes here
don't compile for me.
My toolchain is: gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50)
First, I merged your arm/omap-thumb2+merged branch with my pm branch
from git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git
There were some minor conflicts here, but they looked simple enough and
I just resolved in favor of your branch.
Trying to build with CONFIG_THUMB2_KERNEL=y, I ran into a compile
problem...
> ---
> arch/arm/mach-omap2/sleep34xx.S | 42 +++++++++++++++++++++++++++++---------
> 1 files changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
> index 4032a8e..ef73429 100644
> --- a/arch/arm/mach-omap2/sleep34xx.S
> +++ b/arch/arm/mach-omap2/sleep34xx.S
> @@ -80,8 +80,10 @@
> /* Function call to get the restore pointer for resume from OFF */
> ENTRY(get_restore_pointer)
> stmfd sp!, {lr} @ save registers on stack
> - adr r0, restore
> + adr r0, BSYM(restore)
> ldmfd sp!, {pc} @ restore regs and return
> +ENDPROC(get_restore_pointer)
> + .align
> ENTRY(get_restore_pointer_sz)
> .word . - get_restore_pointer
>
> @@ -89,8 +91,10 @@ ENTRY(get_restore_pointer_sz)
> /* Function call to get the restore pointer for 3630 resume from OFF */
> ENTRY(get_omap3630_restore_pointer)
> stmfd sp!, {lr} @ save registers on stack
> - adr r0, restore_3630
> + adr r0, BSYM(restore_3630)
> ldmfd sp!, {pc} @ restore regs and return
> +ENDPROC(get_omap3630_restore_pointer)
> + .align
> ENTRY(get_omap3630_restore_pointer_sz)
> .word . - get_omap3630_restore_pointer
>
> @@ -98,8 +102,10 @@ ENTRY(get_omap3630_restore_pointer_sz)
> /* Function call to get the restore pointer for ES3 to resume from OFF */
> ENTRY(get_es3_restore_pointer)
> stmfd sp!, {lr} @ save registers on stack
> - adr r0, restore_es3
> + adr r0, BSYM(restore_es3)
> ldmfd sp!, {pc} @ restore regs and return
> +ENDPROC(get_es3_restore_pointer)
> + .align
> ENTRY(get_es3_restore_pointer_sz)
> .word . - get_es3_restore_pointer
>
> @@ -113,8 +119,11 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
> stmfd sp!, {lr} @ save registers on stack
> /* Setup so that we will disable and enable l2 */
> mov r1, #0x1
> - str r1, l2dis_3630
> + ARM( adrl r2, l2dis_3630 ) @ may be out of range for adr in ARM
> + THUMB( adr r2, l2dis_3630 ) @ Thumb has more range, but not adrl
> + str r1, [r2]
> ldmfd sp!, {pc} @ restore regs and return
> +ENDPROC(enable_omap3630_toggle_l2_on_restore)
>
> .text
> /* Function to call rom code to save secure ram context */
> @@ -139,12 +148,14 @@ ENTRY(save_secure_ram_context)
> nop
> nop
> ldmfd sp!, {r1-r12, pc}
> + .align
> sram_phy_addr_mask:
> .word SRAM_BASE_P
> high_mask:
> .word 0xffff
> api_params:
> .word 0x4, 0x0, 0x0, 0x1, 0x1
> +ENDPROC(save_secure_ram_context)
> ENTRY(save_secure_ram_context_sz)
> .word . - save_secure_ram_context
>
> @@ -279,8 +290,7 @@ clean_l2:
> * - 'might' have to copy address, load and jump to it
> */
> ldr r1, kernel_flush
> - mov lr, pc
> - bx r1
> + blx r1
>
> omap3_do_wfi:
> ldr r4, sdrc_power @ read the SDRC_POWER register
> @@ -346,8 +356,8 @@ restore_es3:
> and r4, r4, #0x3
> cmp r4, #0x0 @ Check if previous power state of CORE is OFF
> bne restore
> - adr r0, es3_sdrc_fix
> - ldr r1, sram_base
> + adr r0, es3_sdrc_fix @ Not using BSYM clears the Thumb bit.
This fails to compile:
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep34xx.S: Assembler messages:
/work/kernel/omap/pm/arch/arm/mach-omap2/sleep34xx.S:361: Error: invalid immediate for address calculation (value = 0x00000004)
Kevin
> + ldr r1, sram_base @ Must be 8-byte aligned to preserve alignment.
> ldr r2, es3_sdrc_fix_sz
> mov r2, r2, ror #2
> copy_to_sram:
> @@ -356,6 +366,7 @@ copy_to_sram:
> subs r2, r2, #0x1 @ num_words--
> bne copy_to_sram
> ldr r1, sram_base
> + THUMB( orr r1, r1, #BSYM(es3_sdrc_fix) & 1 )
> blx r1
> b restore
>
> @@ -438,6 +449,7 @@ skipl2dis:
> #endif
> b logic_l1_restore
>
> + .align
> l2_inv_api_params:
> .word 0x1, 0x00
> l2_inv_gp:
> @@ -607,6 +619,7 @@ usettbr0:
>
> /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
> .text
> + .align 3
> ENTRY(es3_sdrc_fix)
> ldr r4, sdrc_syscfg @ get config addr
> ldr r5, [r4] @ get value
> @@ -634,6 +647,7 @@ ENTRY(es3_sdrc_fix)
> str r5, [r4] @ kick off refreshes
> bx lr
>
> + .align
> sdrc_syscfg:
> .word SDRC_SYSCONFIG_P
> sdrc_mr_0:
> @@ -648,6 +662,7 @@ sdrc_emr2_1:
> .word SDRC_EMR2_1_P
> sdrc_manual_1:
> .word SDRC_MANUAL_1_P
> +ENDPROC(es3_sdrc_fix)
> ENTRY(es3_sdrc_fix_sz)
> .word . - es3_sdrc_fix
>
> @@ -682,6 +697,10 @@ wait_sdrc_ready:
> bic r5, r5, #0x40
> str r5, [r4]
>
> +@ PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
> +@ base instead.
> +@ Be careful not to clobber r7 when maintaing this code.
> +
> is_dll_in_lock_mode:
> /* Is dll in lock mode? */
> ldr r4, sdrc_dlla_ctrl
> @@ -689,10 +708,11 @@ is_dll_in_lock_mode:
> tst r5, #0x4
> bxne lr @ Return if locked
> /* wait till dll locks */
> + adr r7, kick_counter
> wait_dll_lock_timed:
> ldr r4, wait_dll_lock_counter
> add r4, r4, #1
> - str r4, wait_dll_lock_counter
> + str r4, [r7, #wait_dll_lock_counter - kick_counter]
> ldr r4, sdrc_dlla_status
> /* Wait 20uS for lock */
> mov r6, #8
> @@ -718,9 +738,10 @@ kick_dll:
> dsb
> ldr r4, kick_counter
> add r4, r4, #1
> - str r4, kick_counter
> + str r4, [r7] @ kick_counter
> b wait_dll_lock_timed
>
> + .align
> cm_idlest1_core:
> .word CM_IDLEST1_CORE_V
> cm_idlest_ckgen:
> @@ -763,6 +784,7 @@ kick_counter:
> .word 0
> wait_dll_lock_counter:
> .word 0
> +ENDPROC(omap34xx_cpu_suspend)
>
> ENTRY(omap34xx_cpu_suspend_sz)
> .word . - omap34xx_cpu_suspend
^ permalink raw reply
* [PATCH] mx31: add support for the bugbase 1.3 from buglabs
From: Marc Kleine-Budde @ 2011-02-10 21:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297372554-19527-1-git-send-email-GNUtoo@no-log.org>
Hello,
(sorry if this mail is sent twice..)
On 02/10/2011 10:15 PM, Denis 'GNUtoo' Carikli wrote:
> This work was based on bug-linux-2.6.30.patch that can be found
> in buglabs's svn here:
> svn://bugcamp.net/bug/branches/izzy/experimental
>
> Note that the hardware schematics and documentations can be obtained
> here: http://www.bugcommunity.com/wiki/index.php/BUGbase
some nitpicking inside:
>
> Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
> ---
> arch/arm/mach-mx3/Kconfig | 9 +++
> arch/arm/mach-mx3/Makefile | 1 +
> arch/arm/mach-mx3/mach-mx31bugbase.c | 97 ++++++++++++++++++++++++++++++++++
> 3 files changed, 107 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mx3/mach-mx31bugbase.c
>
> diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
> index de80d98..4f57f13 100644
> --- a/arch/arm/mach-mx3/Kconfig
> +++ b/arch/arm/mach-mx3/Kconfig
> @@ -199,6 +199,15 @@ config MACH_KZM_ARM11_01
> Include support for KZM-ARM11-01. This includes specific
> configurations for the board and its peripherals.
>
> +config MACH_BUG
> + bool "Support Buglabs BUGBase platform"
> + select SOC_IMX31
> + select IMX_HAVE_PLATFORM_IMX_UART
> + default y
> + help
> + Include support for BUGBase 1.3 platform. This includes specific
> + configurations for the board and its peripherals.
> +
> config MACH_EUKREA_CPUIMX35
> bool "Support Eukrea CPUIMX35 Platform"
> select SOC_IMX35
> diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
> index bc7294f..98e5eb3 100644
> --- a/arch/arm/mach-mx3/Makefile
> +++ b/arch/arm/mach-mx3/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o
> obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o
> obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
> obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o
> +obj-$(CONFIG_MACH_BUG) += mach-mx31bugbase.o
> obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
> obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd-baseboard.o
> obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
> diff --git a/arch/arm/mach-mx3/mach-mx31bugbase.c b/arch/arm/mach-mx3/mach-mx31bugbase.c
> new file mode 100644
> index 0000000..e0ad0f0
> --- /dev/null
> +++ b/arch/arm/mach-mx3/mach-mx31bugbase.c
> @@ -0,0 +1,97 @@
> +/*
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright (C) 2002 Shane Nay (shane at minirl.com)
> + * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The address isn't correct anymore, just remove the paragraph, see commit
aa71251c5b8c673361281fbfd8be5a9ee8b9f4cc.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +
> +#include <mach/iomux-mx3.h>
> +#include <mach/imx-uart.h>
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#include <asm/mach/time.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach-types.h>
> +
> +#include "devices-imx31.h"
> +
> +/*!
> + * @file mx31bugbase.c
> + *
> + * @brief This file contains the board-specific initialization routines.
> + *
> + * @ingroup System
> + */
> +
> +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
> +static struct imxuart_platform_data uart_pdata = {
> + .flags = IMXUART_HAVE_RTSCTS,
> +};
> +
> +static unsigned int uart5_pins[] = {
> + MX31_PIN_PC_RST__CTS5,
> + MX31_PIN_PC_VS2__RTS5,
> + MX31_PIN_PC_BVD2__TXD5,
> + MX31_PIN_PC_BVD1__RXD5
please add a ","
> +};
> +
> +static inline void mxc_init_imx_uart(void)
> +{
> + mxc_iomux_setup_multiple_pins(uart5_pins,
> + ARRAY_SIZE(uart5_pins), "uart-4");
> + imx31_add_imx_uart4(&uart_pdata);
> +}
> +#else /* !SERIAL_IMX */
> +static inline void mxc_init_imx_uart(void)
> +{
> +}
> +#endif /* !SERIAL_IMX */
> +
> +/*!
> + * Board specific initialization.
> + */
> +static void __init mxc_board_init(void)
> +{
> + mxc_init_imx_uart();
> +}
> +
> +
> +static void __init mx31bug_timer_init(void)
> +{
> + mx31_clocks_init(26000000);
> +}
> +
> +static struct sys_timer mx31bug_timer = {
> + .init = mx31bug_timer_init,
> +};
> +
> +/*
> + * The following uses standard kernel macros defined in arch.h in order to
> + * initialize __mach_desc_MX31BUG data structure.
> + */
> +
> +MACHINE_START(BUG, "BugLabs BUGBase")
> + .boot_params = PHYS_OFFSET + 0x100,
> + .timer = &mx31bug_timer,
> + .map_io = mx31_map_io,
> + .init_irq = mx31_init_irq,
> + .init_machine = mxc_board_init,
> +MACHINE_END
cheers, Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110210/79462723/attachment.sig>
^ permalink raw reply
* [PATCH v2 0/5] ARM: omap[34]: Thumb-2 compatibility fixes
From: Kevin Hilman @ 2011-02-10 21:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <82c254dc5a3a4a405b25350e1ef3240e@mail.gmail.com>
Santosh Shilimkar <santosh.shilimkar@ti.com> writes:
[...]
>>
>> The SD card gets suspended, but nothing else seems to happen, and I
>> can't resume the system.
>>
>> Am I doing something wrong?
>>
> MMC suspend is broken. I use ramdisk-ext3 or NFS for my testing
>
Just to clarify, MMC suspend is not broken. It's a "feature" the MMC
core. See the help text of the following Kconfig option, and ensure
that it's enabled:
config MMC_UNSAFE_RESUME
bool "Assume MMC/SD cards are non-removable (DANGEROUS)"
help
If you say Y here, the MMC layer will assume that all cards
stayed in their respective slots during the suspend. The
normal behaviour is to remove them at suspend and
redetecting them at resume. Breaking this assumption will
in most cases result in data corruption.
This option is usually just for embedded systems which use
a MMC/SD card for rootfs. Most people should say N here.
This option sets a default which can be overridden by the
module parameter "removable=0" or "removable=1".
Looking at Dave's .config, this option is disabled, so suspend will hang
when rootfs is on MMC.
Kevin
^ permalink raw reply
* [RFC PATCH 3/3] ARM: vfp: Use cpu pm notifiers to save vfp state
From: Colin Cross @ 2011-02-10 21:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297373487-23902-1-git-send-email-ccross@android.com>
Signed-off-by: Colin Cross <ccross@android.com>
---
arch/arm/vfp/vfpmodule.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 0797cb5..8b27c18 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -21,6 +21,7 @@
#include <asm/cputype.h>
#include <asm/thread_notify.h>
#include <asm/vfp.h>
+#include <asm/cpu_pm.h>
#include "vfpinstr.h"
#include "vfp.h"
@@ -149,6 +150,28 @@ static struct notifier_block vfp_notifier_block = {
.notifier_call = vfp_notifier,
};
+static int vfp_idle_notifier(struct notifier_block *self, unsigned long cmd,
+ void *v)
+{
+ u32 fpexc = fmrx(FPEXC);
+ unsigned int cpu = smp_processor_id();
+
+ if (cmd != CPU_PM_ENTER)
+ return NOTIFY_OK;
+
+ /* The VFP may be reset in idle, save the state */
+ if ((fpexc & FPEXC_EN) && last_VFP_context[cpu]) {
+ vfp_save_state(last_VFP_context[cpu], fpexc);
+ last_VFP_context[cpu]->hard.cpu = cpu;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block vfp_idle_notifier_block = {
+ .notifier_call = vfp_idle_notifier,
+};
+
/*
* Raise a SIGFPE for the current process.
* sicode describes the signal being raised.
@@ -549,6 +572,7 @@ static int __init vfp_init(void)
vfp_vector = vfp_support_entry;
thread_register_notifier(&vfp_notifier_block);
+ cpu_pm_register_notifier(&vfp_idle_notifier_block);
vfp_pm_init();
/*
--
1.7.3.1
^ permalink raw reply related
* [RFC PATCH 2/3] ARM: gic: Use cpu pm notifiers to save gic state
From: Colin Cross @ 2011-02-10 21:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297373487-23902-1-git-send-email-ccross@android.com>
Signed-off-by: Colin Cross <ccross@android.com>
---
arch/arm/common/gic.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 204 insertions(+), 0 deletions(-)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 2243772..219eb71 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -29,6 +29,7 @@
#include <linux/cpumask.h>
#include <linux/io.h>
+#include <asm/cpu_pm.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/hardware/gic.h>
@@ -42,6 +43,17 @@ struct gic_chip_data {
unsigned int irq_offset;
void __iomem *dist_base;
void __iomem *cpu_base;
+#ifdef CONFIG_PM
+ u32 saved_spi_enable[DIV_ROUND_UP(1020, 32)];
+ u32 saved_spi_conf[DIV_ROUND_UP(1020, 16)];
+ u32 saved_spi_pri[DIV_ROUND_UP(1020, 4)];
+ u32 saved_spi_target[DIV_ROUND_UP(1020, 4)];
+ u32 __percpu *saved_ppi_enable;
+ u32 __percpu *saved_ppi_conf;
+ u32 __percpu *saved_ppi_pri;
+#endif
+
+ unsigned int gic_irqs;
};
#ifndef MAX_GIC_NR
@@ -237,6 +249,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
if (gic_irqs > 1020)
gic_irqs = 1020;
+ gic->gic_irqs = gic_irqs;
+
/*
* Set all global interrupts to be level triggered, active low.
*/
@@ -305,6 +319,182 @@ static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
writel(1, base + GIC_CPU_CTRL);
}
+/*
+ * Saves the GIC distributor registers during suspend or idle. Must be called
+ * with interrupts disabled but before powering down the GIC. After calling
+ * this function, no interrupts will be delivered by the GIC, and another
+ * platform-specific wakeup source must be enabled.
+ */
+static void gic_dist_save(unsigned int gic_nr)
+{
+ unsigned int gic_irqs;
+ void __iomem *dist_base;
+ int i;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ gic_irqs = gic_data[gic_nr].gic_irqs;
+ dist_base = gic_data[gic_nr].dist_base;
+
+ if (!dist_base)
+ return;
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+ gic_data[gic_nr].saved_spi_conf[i] =
+ readl(dist_base + GIC_DIST_CONFIG + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ gic_data[gic_nr].saved_spi_pri[i] =
+ readl(dist_base + GIC_DIST_PRI + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ gic_data[gic_nr].saved_spi_target[i] =
+ readl(dist_base + GIC_DIST_TARGET + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+ gic_data[gic_nr].saved_spi_enable[i] =
+ readl(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ writel(0, dist_base + GIC_DIST_CTRL);
+}
+
+/*
+ * Restores the GIC distributor registers during resume or when coming out of
+ * idle. Must be called before enabling interrupts. If a level interrupt
+ * that occured while the GIC was suspended is still present, it will be
+ * handled normally, but any edge interrupts that occured will not be seen by
+ * the GIC and need to be handled by the platform-specific wakeup source.
+ */
+static void gic_dist_restore(unsigned int gic_nr)
+{
+ unsigned int gic_irqs;
+ unsigned int i;
+ void __iomem *dist_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ gic_irqs = gic_data[gic_nr].gic_irqs;
+ dist_base = gic_data[gic_nr].dist_base;
+
+ if (!dist_base)
+ return;
+
+ writel(0, dist_base + GIC_DIST_CTRL);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++)
+ writel(gic_data[gic_nr].saved_spi_conf[i],
+ dist_base + GIC_DIST_CONFIG + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ writel(gic_data[gic_nr].saved_spi_pri[i],
+ dist_base + GIC_DIST_PRI + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++)
+ writel(gic_data[gic_nr].saved_spi_target[i],
+ dist_base + GIC_DIST_TARGET + i * 4);
+
+ for (i = 0; i < DIV_ROUND_UP(gic_irqs, 32); i++)
+ writel(gic_data[gic_nr].saved_spi_enable[i],
+ dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ writel(1, dist_base + GIC_DIST_CTRL);
+}
+
+static void gic_cpu_save(unsigned int gic_nr)
+{
+ int i;
+ u32 *ptr;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ dist_base = gic_data[gic_nr].dist_base;
+ cpu_base = gic_data[gic_nr].cpu_base;
+
+ if (!dist_base || !cpu_base)
+ return;
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+ ptr[i] = readl(dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+ ptr[i] = readl(dist_base + GIC_DIST_CONFIG + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_pri);
+ for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+ ptr[i] = readl(dist_base + GIC_DIST_PRI + i * 4);
+
+ writel(0, cpu_base + GIC_CPU_CTRL);
+}
+
+static void gic_cpu_restore(unsigned int gic_nr)
+{
+ int i;
+ u32 *ptr;
+ void __iomem *dist_base;
+ void __iomem *cpu_base;
+
+ if (gic_nr >= MAX_GIC_NR)
+ BUG();
+
+ dist_base = gic_data[gic_nr].dist_base;
+ cpu_base = gic_data[gic_nr].cpu_base;
+
+ if (!dist_base || !cpu_base)
+ return;
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_enable);
+ for (i = 0; i < DIV_ROUND_UP(32, 32); i++)
+ writel(ptr[i], dist_base + GIC_DIST_ENABLE_SET + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_conf);
+ for (i = 0; i < DIV_ROUND_UP(32, 16); i++)
+ writel(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
+
+ ptr = __this_cpu_ptr(gic_data[gic_nr].saved_ppi_pri);
+ for (i = 0; i < DIV_ROUND_UP(32, 4); i++)
+ writel(ptr[i], dist_base + GIC_DIST_PRI + i * 4);
+
+ writel(0xf0, cpu_base + GIC_CPU_PRIMASK);
+ writel(1, cpu_base + GIC_CPU_CTRL);
+}
+
+static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
+{
+ int i;
+
+ for (i = 0; i < MAX_GIC_NR; i++) {
+ switch (cmd) {
+ case CPU_PM_ENTER:
+ gic_cpu_save(i);
+ break;
+ case CPU_PM_ENTER_FAILED:
+ case CPU_PM_EXIT:
+ gic_cpu_restore(i);
+ break;
+ case CPU_COMPLEX_PM_ENTER:
+ gic_dist_save(i);
+ break;
+ case CPU_COMPLEX_PM_ENTER_FAILED:
+ case CPU_COMPLEX_PM_EXIT:
+ gic_dist_restore(i);
+ break;
+ }
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block gic_notifier_block = {
+ .notifier_call = gic_notifier,
+};
+
void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
void __iomem *dist_base, void __iomem *cpu_base)
{
@@ -322,6 +512,20 @@ void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
gic_dist_init(gic, irq_start);
gic_cpu_init(gic);
+
+ gic->saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_enable);
+
+ gic->saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_conf);
+
+ gic->saved_ppi_pri = __alloc_percpu(DIV_ROUND_UP(32, 4) * 4,
+ sizeof(u32));
+ BUG_ON(!gic->saved_ppi_pri);
+
+ cpu_pm_register_notifier(&gic_notifier_block);
}
void __cpuinit gic_secondary_init(unsigned int gic_nr)
--
1.7.3.1
^ permalink raw reply related
* [RFC PATCH 1/3] ARM: Add cpu power management notifiers
From: Colin Cross @ 2011-02-10 21:31 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297373487-23902-1-git-send-email-ccross@android.com>
During some CPU power modes entered during idle, hotplug and
suspend, peripherals located in the CPU power domain, such as
the GIC, localtimers, and VFP, may be powered down. Add a
notifier chain that allows drivers for those peripherals to
be notified before and after they may be reset.
Signed-off-by: Colin Cross <ccross@android.com>
---
arch/arm/include/asm/cpu_pm.h | 123 +++++++++++++++++++++++++++++++++++++++++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/cpu_pm.c | 116 ++++++++++++++++++++++++++++++++++++++
3 files changed, 240 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/cpu_pm.h
create mode 100644 arch/arm/kernel/cpu_pm.c
diff --git a/arch/arm/include/asm/cpu_pm.h b/arch/arm/include/asm/cpu_pm.h
new file mode 100644
index 0000000..07b1b6e
--- /dev/null
+++ b/arch/arm/include/asm/cpu_pm.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _ASMARM_CPU_PM_H
+#define _ASMARM_CPU_PM_H
+
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+
+/*
+ * When a CPU goes to a low power state that turns off power to the CPU's
+ * power domain, the contents of some blocks (floating point coprocessors,
+ * interrutp controllers, caches, timers) in the same power domain can
+ * be lost. The cpm_pm notifiers provide a method for platform idle, suspend,
+ * and hotplug implementations to notify the drivers for these blocks that
+ * they may be reset.
+ *
+ * All cpu_pm notifications must be called with interrupts disabled.
+ *
+ * The notifications are split into two classes, CPU notifications and CPU
+ * complex notifications.
+ *
+ * CPU notifications apply to a single CPU, and must be called on the affected
+ * CPU. They are used to save per-cpu context for affected blocks.
+ *
+ * CPU complex notifications apply to all CPUs in a single power domain. They
+ * are used to save any global context for affected blocks, and must be called
+ * after all the CPUs in the power domain have been notified of the low power
+ * state.
+ *
+ */
+
+/*
+ * Event codes passed as unsigned long val to notifier calls
+ */
+enum cpu_pm_event {
+ /* A single cpu is entering a low power state */
+ CPU_PM_ENTER,
+
+ /* A single cpu failed to enter a low power state */
+ CPU_PM_ENTER_FAILED,
+
+ /* A single cpu is exiting a low power state */
+ CPU_PM_EXIT,
+
+ /* A cpu power domain is entering a low power state */
+ CPU_COMPLEX_PM_ENTER,
+
+ /* A cpu power domain failed to enter a low power state */
+ CPU_COMPLEX_PM_ENTER_FAILED,
+
+ /* A cpu power domain is exiting a low power state */
+ CPU_COMPLEX_PM_EXIT,
+};
+
+int cpu_pm_register_notifier(struct notifier_block *nb);
+int cpu_pm_unregister_notifier(struct notifier_block *nb);
+
+/*
+ * cpm_pm_enter
+ *
+ * Notifies listeners that a single cpu is entering a low power state that may
+ * cause some blocks in the same power domain as the cpu to reset.
+ *
+ * Must be called on the affected cpu with interrupts disabled. Platform is
+ * responsible for ensuring that cpu_pm_enter is not called twice on the same
+ * cpu before cpu_pm_exit is called.
+ */
+int cpu_pm_enter(void);
+
+/*
+ * cpm_pm_exit
+ *
+ * Notifies listeners that a single cpu is exiting a low power state that may
+ * have caused some blocks in the same power domain as the cpu to reset.
+ *
+ * Must be called on the affected cpu with interrupts disabled.
+ */
+int cpu_pm_exit(void);
+
+/*
+ * cpm_complex_pm_enter
+ *
+ * Notifies listeners that all cpus in a power domain are entering a low power
+ * state that may cause some blocks in the same power domain to reset.
+ *
+ * Must be called after cpu_pm_enter has been called on all cpus in the power
+ * domain, and before cpu_pm_exit has been called on any cpu in the power
+ * domain.
+ *
+ * Must be called with interrupts disabled.
+ */
+int cpu_complex_pm_enter(void);
+
+/*
+ * cpm_pm_enter
+ *
+ * Notifies listeners that a single cpu is entering a low power state that may
+ * cause some blocks in the same power domain as the cpu to reset.
+ *
+ * Must be called after cpu_pm_enter has been called on all cpus in the power
+ * domain, and before cpu_pm_exit has been called on any cpu in the power
+ * domain.
+ *
+ * Must be called with interrupts disabled.
+ */
+int cpu_complex_pm_exit(void);
+
+#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee82..b0f25cb 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
+obj-$(CONFIG_CPU_IDLE) += cpu_pm.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
ifneq ($(CONFIG_ARCH_EBSA110),y)
diff --git a/arch/arm/kernel/cpu_pm.c b/arch/arm/kernel/cpu_pm.c
new file mode 100644
index 0000000..9a04ba1
--- /dev/null
+++ b/arch/arm/kernel/cpu_pm.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/notifier.h>
+#include <linux/smp.h>
+
+#include <asm/cpu_pm.h>
+
+static DEFINE_SPINLOCK(idle_notifier_lock);
+static RAW_NOTIFIER_HEAD(idle_notifier_chain);
+
+int cpu_pm_register_notifier(struct notifier_block *nb)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&idle_notifier_lock, flags);
+ ret = raw_notifier_chain_register(&idle_notifier_chain, nb);
+ spin_unlock_irqrestore(&idle_notifier_lock, flags);
+
+ return ret;
+}
+
+int cpu_pm_unregister_notifier(struct notifier_block *nb)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&idle_notifier_lock, flags);
+ ret = raw_notifier_chain_unregister(&idle_notifier_chain, nb);
+ spin_unlock_irqrestore(&idle_notifier_lock, flags);
+
+ return ret;
+}
+
+static int __idle_notify(enum cpu_pm_event event, int nr_to_call,
+ int *nr_calls)
+{
+ int ret;
+
+ ret = __raw_notifier_call_chain(&idle_notifier_chain, event, NULL,
+ nr_to_call, nr_calls);
+
+ return notifier_to_errno(ret);
+}
+
+int cpu_pm_enter(void)
+{
+ int nr_calls;
+ int ret;
+
+ spin_lock(&idle_notifier_lock);
+ ret = __idle_notify(CPU_PM_ENTER, -1, &nr_calls);
+ if (ret) {
+ __idle_notify(CPU_PM_ENTER_FAILED, nr_calls - 1, NULL);
+ spin_unlock(&idle_notifier_lock);
+ return ret;
+ }
+ spin_unlock(&idle_notifier_lock);
+
+ return 0;
+}
+
+int cpu_pm_exit(void)
+{
+ int ret;
+
+ spin_lock(&idle_notifier_lock);
+ ret = __idle_notify(CPU_PM_EXIT, -1, NULL);
+ spin_unlock(&idle_notifier_lock);
+
+ return ret;
+}
+
+int cpu_complex_pm_enter(void)
+{
+ int nr_calls;
+ int ret;
+
+ spin_lock(&idle_notifier_lock);
+ ret = __idle_notify(CPU_COMPLEX_PM_ENTER, -1, &nr_calls);
+ if (ret) {
+ __idle_notify(CPU_COMPLEX_PM_ENTER_FAILED, nr_calls - 1, NULL);
+ spin_unlock(&idle_notifier_lock);
+ return ret;
+ }
+ spin_unlock(&idle_notifier_lock);
+
+ return 0;
+}
+
+int cpu_complex_pm_exit(void)
+{
+ int ret;
+
+ spin_lock(&idle_notifier_lock);
+ ret = __idle_notify(CPU_COMPLEX_PM_EXIT, -1, NULL);
+ spin_unlock(&idle_notifier_lock);
+
+ return ret;
+}
--
1.7.3.1
^ permalink raw reply related
* [RFC PATCH 0/3] CPU PM notifiers
From: Colin Cross @ 2011-02-10 21:31 UTC (permalink / raw)
To: linux-arm-kernel
This patch set tries to address Russell's concerns with platform
pm code calling into the driver for every block in the Cortex A9s
during idle, hotplug, and suspend. The first patch adds cpu pm
notifiers that can be called by platform code, the second uses
the notifier to save and restore the GIC state, and the third
saves the VFP state.
The notifiers are used for two types of events, CPU PM events and
CPU complex PM events. CPU PM events are used to save per-cpu
context when a single CPU is preparing to enter or has just exited
a low power state. For example, the VFP saves the last thread
context, and the GIC saves banked CPU registers.
CPU complex events are used after all the CPUs in a power domain
have been prepared for the low power state. The GIC uses these
events to save global register state.
What is not included:
* Multiple power states - it is assumed that if the platform
code calls cpu_pm_enter(), every listener needs to save
its context.
* L2 cache - The L2 cache will need very different behavior
depending on the HW implementation and power mode being
entered.
Both problems could be solved be defining a set of power states
shared by all platforms, if an agreeable set exists. For example:
* CPU reset (TWD, GIC, VFP), L1 retention, L2 untouched
* CPU reset + L1 lost, L2 retention
* CPU reset, L1 + L2 lost
Santosh previously mentioned that the GIC is not reset in the first
two states on OMAP, which starts to make the list complicated. Does
disabling the GIC cause a problem in these states?
An alternate solution is to pass a set of flags instead of a power state:
CPU_PM_LOCALTIMERS_RESET
CPU_PM_INTERRUPTS_RESET
CPU_PM_L1_RETENTION
CPU_PM_L1_RESET
CPU_PM_L2_RETENTION
CPU_PM_L2_RESET
arch/arm/common/gic.c | 204 +++++++++++++++++++++++++++++++++++++++++
arch/arm/include/asm/cpu_pm.h | 123 +++++++++++++++++++++++++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/cpu_pm.c | 116 +++++++++++++++++++++++
arch/arm/vfp/vfpmodule.c | 24 +++++
5 files changed, 468 insertions(+), 0 deletions(-)
^ permalink raw reply
* [PATCH] mx31: add support for the bugbase 1.3 from buglabs
From: Denis 'GNUtoo' Carikli @ 2011-02-10 21:15 UTC (permalink / raw)
To: linux-arm-kernel
This work was based on bug-linux-2.6.30.patch that can be found
in buglabs's svn here:
svn://bugcamp.net/bug/branches/izzy/experimental
Note that the hardware schematics and documentations can be obtained
here: http://www.bugcommunity.com/wiki/index.php/BUGbase
Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
---
arch/arm/mach-mx3/Kconfig | 9 +++
arch/arm/mach-mx3/Makefile | 1 +
arch/arm/mach-mx3/mach-mx31bugbase.c | 97 ++++++++++++++++++++++++++++++++++
3 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mx3/mach-mx31bugbase.c
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index de80d98..4f57f13 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -199,6 +199,15 @@ config MACH_KZM_ARM11_01
Include support for KZM-ARM11-01. This includes specific
configurations for the board and its peripherals.
+config MACH_BUG
+ bool "Support Buglabs BUGBase platform"
+ select SOC_IMX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ default y
+ help
+ Include support for BUGBase 1.3 platform. This includes specific
+ configurations for the board and its peripherals.
+
config MACH_EUKREA_CPUIMX35
bool "Support Eukrea CPUIMX35 Platform"
select SOC_IMX35
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index bc7294f..98e5eb3 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o
obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o
obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o
+obj-$(CONFIG_MACH_BUG) += mach-mx31bugbase.o
obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd-baseboard.o
obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
diff --git a/arch/arm/mach-mx3/mach-mx31bugbase.c b/arch/arm/mach-mx3/mach-mx31bugbase.c
new file mode 100644
index 0000000..e0ad0f0
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-mx31bugbase.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane at minirl.com)
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/iomux-mx3.h>
+#include <mach/imx-uart.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "devices-imx31.h"
+
+/*!
+ * @file mx31bugbase.c
+ *
+ * @brief This file contains the board-specific initialization routines.
+ *
+ * @ingroup System
+ */
+
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static unsigned int uart5_pins[] = {
+ MX31_PIN_PC_RST__CTS5,
+ MX31_PIN_PC_VS2__RTS5,
+ MX31_PIN_PC_BVD2__TXD5,
+ MX31_PIN_PC_BVD1__RXD5
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+ mxc_iomux_setup_multiple_pins(uart5_pins,
+ ARRAY_SIZE(uart5_pins), "uart-4");
+ imx31_add_imx_uart4(&uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* !SERIAL_IMX */
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_init_imx_uart();
+}
+
+
+static void __init mx31bug_timer_init(void)
+{
+ mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31bug_timer = {
+ .init = mx31bug_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros defined in arch.h in order to
+ * initialize __mach_desc_MX31BUG data structure.
+ */
+
+MACHINE_START(BUG, "BugLabs BUGBase")
+ .boot_params = PHYS_OFFSET + 0x100,
+ .timer = &mx31bug_timer,
+ .map_io = mx31_map_io,
+ .init_irq = mx31_init_irq,
+ .init_machine = mxc_board_init,
+MACHINE_END
--
1.7.0.4
^ permalink raw reply related
* [PATCH v5 0/5] omap: mailbox: hwmod support
From: Kevin Hilman @ 2011-02-10 21:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimah86Mj37rCMYnuprUfeP1XwmxcNBD9S=8g6_N@mail.gmail.com>
"Poddar, Sourav" <sourav.poddar@ti.com> writes:
> On Thu, Feb 3, 2011 at 12:57 AM, Omar Ramirez Luna <omar.ramirez@ti.com> wrote:
>> Mailbox hwmod support for OMAP 2,3,4.
>>
>> This was tested on OMAP3 (3430, 3630), minor testing
>> was made on OMAP4.
>>
>> No testing on OMAP2 since I don't have the hardware.
>>
>> Highlights from v5 include the comments received from
>> previous version v4[1].
>>
>> Benoit Cousson (1):
>> ?OMAP4: hwmod data: add mailbox data
>>
>> Felipe Contreras (2):
>> ?OMAP3: hwmod data: add mailbox data
>> ?OMAP: mailbox: build device using omap_device/omap_hwmod
>>
>> Omar Ramirez Luna (1):
>> ?OMAP: mailbox: use runtime pm for clk and sysc handling
>>
>> omar ramirez (1):
>> ?OMAP2: hwmod data: add mailbox data
>>
>> ?arch/arm/mach-omap2/devices.c ? ? ? ? ? ? ?| ? 98 +++++-----------------------
>> ?arch/arm/mach-omap2/mailbox.c ? ? ? ? ? ? ?| ? 67 ++-----------------
>> ?arch/arm/mach-omap2/omap_hwmod_2420_data.c | ? 74 +++++++++++++++++++++
>> ?arch/arm/mach-omap2/omap_hwmod_2430_data.c | ? 73 +++++++++++++++++++++
>> ?arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | ? 72 ++++++++++++++++++++
>> ?arch/arm/mach-omap2/omap_hwmod_44xx_data.c | ? 67 +++++++++++++++++++
>> ?6 files changed, 308 insertions(+), 143 deletions(-)
>
> Boot tested mainline v2.6.38-rc4 along with this 5 patch series on
> Omap 2420,2430 SDPs.
>
> Tested-by: Sourav Poddar<sourav.poddar@ti.com>
Boot testing is a start, but I'm pretty sure that bootup does not use
the mailbox on any of these platforms. This needs to be tested with
something that actually uses the mailbox.
Kevin
^ permalink raw reply
* [PATCH] i.MX51 iomux: Fixes MX51_PAD_UART2_TXD__UART2_TXD declaration
From: Sascha Hauer @ 2011-02-10 20:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D53EE2C.2030209@free.fr>
On Thu, Feb 10, 2011 at 02:54:52PM +0100, Julien Boibessot wrote:
> Hi Sascha,
>
> Sascha Hauer a ?crit :
> > The patch is probably fine. Can you provide a better commit log,
> > something like 'fixes uart3 on $myboard'?
> >
> yes, I will try :-)
> > >From looking at the datasheet it is not clear to me how the current pin
> > configuration bahaves. It looks like a uart tx loopback in the iomuxer.
> > Is this correct?
> >
> Well I just reverted the setting back to what it was on 2.6.36, before
> the recent MX51 iomux reorganisation.
> IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT register (0x09ec) shouldn't
> be used to configure UART2_TXD PAD, otherwise you overwrite current
> UART2_RXD PAD config.
> Current pin configuration seems to act as a kind of Tx->Rx loopback, yes.
Ok, would be good to have this in the commit log aswell.
Sascha
>
> Without my patch, my board (not mainlined yet) can't receive anything on
> UART2 (used as console).
>
> Julien
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
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
* [PATCH V3 1/1] ST SPEAr: PCIE gadget suppport
From: Andrew Morton @ 2011-02-10 20:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D53B4C1.5080804@st.com>
On Thu, 10 Feb 2011 15:19:53 +0530
pratyush <pratyush.anand@st.com> wrote:
> On 2/10/2011 4:59 AM, Andrew Morton wrote:
> > On Thu, 3 Feb 2011 19:39:09 +0530
> > Pratyush Anand <pratyush.anand@st.com> wrote:
> >
> >> This is a configurable gadget. can be configured by configfs interface. Any
> >> IP available at PCIE bus can be programmed to be used by host
> >> controller.It supoorts both INTX and MSI.
> >> By default, gadget is configured for INTX and SYSRAM1 is mapped to BAR0
> >> with size 0x1000
> >>
> >>
> >> ...
> >>
> >> --- /dev/null
> >> +++ b/Documentation/ABI/testing/configfs-spear-pcie-gadget
> >> @@ -0,0 +1,30 @@
> >> +What: /config/pcie-gadget
> >> +Date: Feb 2011
> >> +KernelVersion: 2.6.37
> >> +Contact: Pratyush Anand <pratyush.anand@st.com>
> >> +Description:
> >> +
> >> + Interface is used to configure selected dual mode pcie controller
> >> + as device and then program its various registers to configure it
> >> + as a particular device type.
> >> + This interfaces can be used to show spear's pcie device capability.
> >> +
> >> + Nodes are only visible when configfs is mounted. To mount configfs
> >> + in /config directory use:
> >> + # mount -t configfs none /config/
> >> +
> >> + /config/pcie-gadget/
> >> + link ... used to enable ltssm and read its status.
> >> + int_type ...used to configure and read type of supported
> >> + interrupt
> >> + no_of_msi ... used to configure number of MSI vector needed and
> >> + to read no of MSI granted.
> >> + inta ... write 1 to assert INTA and 0 to de-assert.
> >> + send_msi ... write MSI vector to be sent.
> >> + vendor_id ... used to write and read vendor id (hex)
> >> + device_id ... used to write and read device id (hex)
> >> + bar0_size ... used to write and read bar0_size
> >> + bar0_address ... used to write and read bar0 mapped area in hex.
> >> + bar0_rw_offset ... used to write and read offset of bar0 where
> >> + bar0_data will be written or read.
> >> + bar0_data ... used to write and read data at bar0_rw_offset.
> >
> > This interface implies that there will only ever be one device in the
> > machine, yes? Seems a bit short-sighted?
> >
>
> This device supports only one BAR in EP mode.
I don't understand that.
What happens if someone builds a computer with three of these devices
in it?
> >> + flags &= ~PCI_MSI_FLAGS_QMASK;
> >> + flags |= vec << 1;
> >> + spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
> >> + } else
> >> + return -EINVAL;
> >> +
> >> + strcpy(config->int_type, int_type);
> >> +
> >> + return count;
> >> +}
> >> +
> >> +static ssize_t pcie_gadget_show_no_of_msi(
> >> + struct spear_pcie_gadget_config *config,
> >> + char *buf)
> >> +{
> >> + struct pcie_app_reg __iomem *app_reg =
> >> + (struct pcie_app_reg __iomem *)config->va_app_base;
> >> + u32 cap, vector, vec, flags;
> >> +
> >> + if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
> >> + != (1 << CFG_MSI_EN_ID))
> >> + vector = 0;
> >> + else {
> >> + cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
> >> + spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
> >> + flags &= ~PCI_MSI_FLAGS_QSIZE;
> >> + vec = flags >> 4;
> >> + vector = 1;
> >> + while (vec--)
> >> + vector *= 2;
> >> + }
> >> + config->configured_msi = vector;
> >
> > Wait. A "show" function is modifying kernel state?!?!?
> >
>
> this show is a must call part of MSI vector negotiation.
> A device must read first configured number of MSI, before
> sending any MSI. Here value of vector is read from HW
> and stored in a SW variable. So, it is not programmed
> by any application input.
What happens if a (buggy?) application tries to send an MSI before
calling pcie_gadget_show_no_of_msi()?
^ permalink raw reply
* [PATCH v2] OMAP: hwmod: Do not expect an entry in clkdev for opt_clks
From: Paul Walmsley @ 2011-02-10 20:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1296626117-31716-1-git-send-email-rnayak@ti.com>
On Wed, 2 Feb 2011, Rajendra Nayak wrote:
> The _add_optional_clock_alias function expects an entry
> already existing in the clkdev table in the form of
> <dev-id=NULL, con-id=role> which might not be the case
> always.
>
> Instead, just check if an entry already exists in clkdev
> in the <dev-id=dev_name, con-id=role> form, else go ahead
> and add one.
>
> Remove any assumption of an entry already existing in clkdev
> table in any form.
>
> Since this means, adding a new entry in clkdev if it does
> not already exist, and not really adding an 'alias',
> also rename the function name
> (s/_add_optional_clock_alias/_add_optional_clock_clkdev)
> to reflect this.
>
> Signed-off-by: Rajendra Nayak <rnayak@ti.com>
> Reported-by: Sumit Semwal <sumit.semwal@ti.com>
> Cc: Sumit Semwal <sumit.semwal@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@ti.com>
> Cc: Partha Basak <p-basak2@ti.com>
Thanks. I changed the subject line to read:
OMAP2+: omap_device/clock: Do not expect an entry in clkdev for opt_clks
before queuing for 2.6.39 in the branch 'omap_device_a_2.6.39' of
git://git.pwsan.com/linux-2.6
Also added to the 'integration-2.6.39' branch of
git://git.pwsan.com/linux-2.6 and is part of the stable tag
'integration-2.6.39-20110210-002'
- Paul
^ permalink raw reply
* ARM: relocation out of range (when loading a module)
From: Nicolas Pitre @ 2011-02-10 19:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110210154322.GE1742@n2100.arm.linux.org.uk>
On Thu, 10 Feb 2011, Russell King - ARM Linux wrote:
> On Thu, Jan 27, 2011 at 12:43:54AM -0500, Nicolas Pitre wrote:
> > The MMU-less kernel should still favor allocations close to the kernel
> > text for modules, and anything else away from the kernel going
> > downwards.
> >
> > Otherwise a veneer should be created by the module symbol resolver such
> > that if the branch distance to reach, say, printk is too large, then the
> > following code would have to be dynamically generated right next to the
> > module:
> >
> > ldr pc, [pc, #-4]
> > .word <far_away_symbol>
> >
> > Then, in your module, you patch the branch relocation for printk so that
> > it branches to the code above instead, and then store the address of
> > printk at the location represented by the .word directive.
>
> What you're suggesting is what we used to do with the old user-space
> module tools, which would've been nice to carry forwards to the new
> module code. I never found a way to do it.
>
> The problems:
> 1. Where do you create those veneers?
> 2. How many veneers do you allocate space for?
> 3. How do you determine that you need a veneer?
>
> While you can say "next to the module" for (1), you can only do that at
> the point in time when the space for the module is allocated, and you
> need to know at that point how much space you require.
You would have to guess of course. Having a guess of 1/2 the module
size should be pretty safe. So allocating 3/2 the space in
module_alloc(), and then suffice to free the unused portion in
module_finalize().
> For (2), you could always allocate space for one veneer per symbol present
> in the module, but that's very wasteful.
>
> (3) is almost impossible to know ahead of time as you don't have the
> relocations, realistically you have to allocate one veneer per symbol,
> and as you don't know whether it's a data or code symbol, you'll have
> to allocate one veneer for every symbol in a module.
I don't think you may know the number of symbols in advance either
anyway.
> I really don't like it, and I don't see that this is sanely solvable
> without giving architectures much more control over module loading,
> which I don't think will ever happen. It's probably simpler to build
> modules with whatever that magic option is to tell GCC to always generate
> 'far call' veneers for everything rather than trying to 'fix' the kernel
> module loader.
Well, this is certainly possible indeed to just use -mlong-calls to
build modules which would solve the issue right away, and with a smaller
cost than if each function calls were going through a veneer, but with a
higher cost than a relocatable direct branch. So this could be decided
with a Kconfig option.
Nicolas
^ permalink raw reply
* [PATCH 2/5] mmc: sdhci-esdhc: broken card detection is not a default quirk
From: Wolfram Sang @ 2011-02-10 19:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-3-git-send-email-w.sang@pengutronix.de>
Adding Anton to Cc...
On Thu, Feb 10, 2011 at 08:14:48PM +0100, Wolfram Sang wrote:
> 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>
> ---
> 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 83d178b..e0fa1f3 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -170,7 +170,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
>
--
Pengutronix e.K. | Wolfram Sang |
Industrial Linux Solutions | http://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110210/398800b4/attachment-0001.sig>
^ permalink raw reply
* [PATCH 5/5] arm: mach-mx3: use IMX_GPIO_NR instead of hard-coded values
From: Wolfram Sang @ 2011-02-10 19:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-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>
Cc: Eric B?nard <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-10 19:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@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-10 19:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/plat-mxc/include/mach/esdhc.h | 2 +
drivers/mmc/host/sdhci-esdhc-imx.c | 75 ++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
index dbf6d56..7501d4e 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
+ * @cd_gpio: gpio for card_detect interrupt
*/
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 e0fa1f3..e9c56b6 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))
+ /*
+ * 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;
}
@@ -152,9 +195,34 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
dev_warn(mmc_dev(host->mmc), "can't get wp_pin!\n");
boarddata->wp_gpio = err;
}
+
+ err = gpio_request_one(boarddata->cd_gpio, GPIOF_IN, "ESDHC_CD");
+ if (err) {
+ dev_warn(mmc_dev(host->mmc), "can't get cd_pin!\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)
@@ -165,6 +233,13 @@ 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);
}
--
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-10 19:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-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>
---
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 83d178b..e0fa1f3 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -170,7 +170,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-10 19:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1297365291-1038-1-git-send-email-w.sang@pengutronix.de>
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/plat-mxc/include/mach/esdhc.h | 10 +++++-
drivers/mmc/host/sdhci-esdhc-imx.c | 51 +++++++++++++++++++++++++-------
2 files changed, 49 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..dbf6d56 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
+ */
+
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..83d178b 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,20 @@ 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), "can't get wp_pin!\n");
+ boarddata->wp_gpio = err;
+ }
+ }
return 0;
}
@@ -126,20 +160,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
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