* [PATCH] ARM: imx/mx25_3ds: Fix build failure
From: Uwe Kleine-König @ 2011-03-02 8:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299028552-13186-1-git-send-email-festevam@gmail.com>
On Tue, Mar 01, 2011 at 10:15:52PM -0300, Fabio Estevam wrote:
> Commit
> ca8d906 (ARM: mach-imx: mx25_3ds: add write-protect and card-detect for SD)
>
> assigned a non-existing member .cd_gpio in a struct esdhc_platform_data.
> This field can be added later after the esdhc patches are merged.
> Fix the build for now.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
> ---
> arch/arm/mach-imx/mach-mx25_3ds.c | 1 -
> 1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/mach-imx/mach-mx25_3ds.c b/arch/arm/mach-imx/mach-mx25_3ds.c
> index 561f07f..11c25f9 100644
> --- a/arch/arm/mach-imx/mach-mx25_3ds.c
> +++ b/arch/arm/mach-imx/mach-mx25_3ds.c
> @@ -208,7 +208,6 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
>
> static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
> .wp_gpio = SD1_GPIO_WP,
> - .cd_gpio = SD1_GPIO_CD,
> };
Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 0/2] OMAP3: cpuidle: prevent CORE pwrdm from entering low-power state when DSS active
From: Tero.Kristo at nokia.com @ 2011-03-02 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110301220833.32613.54669.stgit@twilight.localdomain>
>-----Original Message-----
>From: ext Paul Walmsley [mailto:paul at pwsan.com]
>Sent: 02 March, 2011 00:49
>To: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>Kristo Tero (Nokia-MS/Tampere)
>Subject: [PATCH 0/2] OMAP3: cpuidle: prevent CORE pwrdm from entering
>low-power state when DSS active
>
>This series prevents the OMAP3 CPUIdle code from programming the CORE
>powerdomain to enter any power state lower than ON when the DSS power
>domain
>is ON. (The assumption is that in this case, the DSS is active, DMA'ing
>lines from RAM and displaying them somewhere.)
>
>Tero, please don't hesitate to comment on the patch from you if I got
>the
>commit message wrong.
Hi Paul,
It looks good to me.
>
>
>- Paul
>
>---
>
>Tero Kristo (1):
> OMAP3: cpuidle: prevent CORE power domain from going to RET or OFF
>when DSS is on
>
>Paul Walmsley (1):
> OMAP3: cpuidle: add more details to the DSS-related CORE power
>domain state restriction
>
>
> arch/arm/mach-omap2/cpuidle34xx.c | 36
>++++++++++++++++++++++++++++++++++--
> 1 files changed, 34 insertions(+), 2 deletions(-)
^ permalink raw reply
* [PATCH 6/7] OMAP: Serial: Allow UART parameters to be configured from board file
From: Sricharan R @ 2011-03-02 8:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimD9rOC=4P6Vy2jzvcXZ-gZmF42Te4CBjS8AJLT@mail.gmail.com>
Hi,
>-----Original Message-----
>From: Govindraj [mailto:govindraj.ti at gmail.com]
>Sent: Wednesday, March 02, 2011 1:11 PM
>To: Sricharan R
>Cc: Govindraj.R; linux-omap at vger.kernel.org;
linux-serial at vger.kernel.org;
>linux-arm-kernel at lists.infradead.org; Jon Hunter; Tony Lindgren; Benoit
>Cousson; Kevin Hilman; Paul Walmsley; Rajendra Nayak; Deepak Kattungal
>Subject: Re: [PATCH 6/7] OMAP: Serial: Allow UART parameters to be
>configured from board file
>
>On Wed, Mar 2, 2011 at 12:46 AM, Sricharan R <r.sricharan@ti.com> wrote:
>> Hi,
>>>diff --git a/arch/arm/mach-omap2/serial.c
b/arch/arm/mach-omap2/serial.c
>>>index 755f4aa..530e9e3 100644
>>>--- a/arch/arm/mach-omap2/serial.c
>>>+++ b/arch/arm/mach-omap2/serial.c
>>>@@ -44,6 +44,15 @@
>>>
>>> static int omap_uart_con_id __initdata = -1;
>>>
>>>+static struct omap_uart_port_info omap_serial_default_info[] = {
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.dma_enabled ? ?= 0,
>>>+ ? ? ? ? ? ? ?.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
>>>+ ? ? ? ? ? ? ?.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
>>>+ ? ? ? ? ? ? ?.idle_timeout ? = DEFAULT_IDLE_TIMEOUT,
>>>+ ? ? ?},
>>>+};
>>>+
>>> static int uart_idle_hwmod(struct omap_device *od)
>>> {
>>> ? ? ? omap_hwmod_idle(od->hwmods[0]);
>>>@@ -66,6 +75,54 @@ static struct omap_device_pm_latency
>> omap_uart_latency[]
>>>= {
>>> ? ? ? },
>>> };
>>>
>>>+#ifdef CONFIG_OMAP_MUX
>>>+static struct omap_device_pad default_serial0_pads[] __initdata = {
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.name ? = "uart1_rx.uart1_rx",
>>>+ ? ? ? ? ? ? ?.flags ?= OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP,
>>>+ ? ? ? ? ? ? ?.enable = OMAP_MUX_MODE0,
>>>+ ? ? ?},
>>>+};
>>>+
>>>+static struct omap_device_pad default_serial1_pads[] __initdata = {
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.name ? = "uart2_rx.uart2_rx",
>>>+ ? ? ? ? ? ? ?.flags ?= OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP,
>>>+ ? ? ? ? ? ? ?.enable = OMAP_MUX_MODE0,
>>>+ ? ? ?},
>>>+};
>>>+
>>>+static struct omap_device_pad default_serial2_pads[] __initdata = {
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.name ? = "uart3_rx_irrx.uart3_rx_irrx",
>>>+ ? ? ? ? ? ? ?.flags ?= OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP,
>>>+ ? ? ? ? ? ? ?.enable = OMAP_MUX_MODE0,
>>>+ ? ? ?},
>>>+};
>>>+
>>>+static struct omap_device_pad default_omap36xx_serial3_pads[]
__initdata
>> =
>>>{
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.name ? = "gpmc_wait3.uart4_rx",
>>>+ ? ? ? ? ? ? ?.flags ?= OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP,
>>>+ ? ? ? ? ? ? ?.enable = OMAP_MUX_MODE2,
>>>+ ? ? ?},
>>>+};
>>>+
>>>+static struct omap_device_pad default_omap4_serial3_pads[] __initdata
=
>> {
>>>+ ? ? ?{
>>>+ ? ? ? ? ? ? ?.name ? = "uart4_rx.uart4_rx",
>>>+ ? ? ? ? ? ? ?.flags ?= OMAP_DEVICE_PAD_REMUX |
OMAP_DEVICE_PAD_WAKEUP,
>>>+ ? ? ? ? ? ? ?.enable = OMAP_MUX_MODE0,
>>>+ ? ? ?},
>>>+};
>> Here only the UART RX pins are muxed, so what about the cts, rts, tx
>pins?
>
>The intention here is to enable wakeup capabilities for uart rx pad.
>
>AFAIK most of the boards are currently dependent on bootloader for
>uart-muxing if any board is not dependent on bootloader then we
>can use omap_serial_init_port along with board_mux_info from board.
>
Yes. The idea is to be independent of the bootloaders for mux settings.
>Prior to this change uart wakeup is based on rx_pad and we were
populating
>offset and using omap_ctrl api's to read/write which is cleaned up now.
>Most of boards are dependent on uart-rx wakeup to avoid breaking any
>board support we
>are using omap_serial_init by filling default values, which provides
>us with same
>environment but with right approach towards handling mux data with a
>handshake with
>hwmod framework.
>
Now, in this change only the RX pin is configured. So if some board uses
omap_serial_init then only the RX is going to be configured.
How will they configure the rest of the pins?
They cannot call omap_serial_init_port after this just to configure the
rest of the mux pins( cts, rts, tx).
So data which is passed from omap_serial_init should have the
configuration
for all the pins, and this default data should be consistent across
atleast
some boards, so that they can use this. This will reduce the data
duplication across board files.
If this is not true, then all the pads can be configured from the board
files itself using omap_serial_init_port and you can set the required
RX wakeup capability there as well.
>So if any board needs specific mux they can go ahead and add required
>mux data in
>board file and use map_serial_init_port instead of current
>omap_serial_init.
>
>
>> Is it consistent that across all socs that only UART3 would have
>UART/IRDA
>> functions capability so that serial2 pads can always be called
"rx_irxx"
>> ?.
>
>Yes from OMAP2420 to OMAP4430 uart3 can used as irda.
>
Ok.
>--
>Thanks,
>Govindraj.R
^ permalink raw reply
* [PATCHv5 0/3] Introduce the /proc/socinfo and use it to export OMAP data
From: Maxime Coquelin @ 2011-03-02 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D6DB1B1.4060908@codeaurora.org>
On 03/02/2011 03:55 AM, Saravana Kannan wrote:
> On 03/01/2011 06:41 PM, Ryan Mallon wrote:
>> On 03/02/2011 03:23 PM, Saravana Kannan wrote:
>>> I don't have any attachment to the "arch" file suggestion. If there is a
>>> better solution to identify the different implementations of socinfo
>>> without having to maintain some "unique id" list in the kernel, then I'm
>>> all for it. But cpuinfo is not it.
>> Sorry I am confusing the 'arch' and 'mach' bits here. I definitely have
>> an objection to having an 'arch' file (i.e. ARM). A 'mach' (i.e. omap)
>> file makes a bit more sense, but should probably be called 'mach' rather
>> than 'arch' to avoid this confusion :-).
> Sorry for the confusion. Sure, I don't care much for the filename as
> long as we can all agree on it. I care more about the content of the
> file (using names very close to xxxx in mach-xxxx). I like "soc-family"
> better since it's generic enough to not force, say omap3 and omap4, to
> report different values.
>
> Linus Walleij, Eduardo, Maxime, Andrei,
>
> Would like to hear your opinion on the file name (soc-family vs. mach vs
> <somethingelse>) and the path /sys/devices/system/soc/.
>
> If we settle on this, may be it would be easier to get this through.
>
I think we should have a tree like this :
/sys/devices/system/soc/
/sys/devices/system/soc/unique_id<- Unified way to export an ID for all machs
/sys/devices/system/soc/mach/
/sys/devices/system/soc/mach/name<- Name of the mach
/sys/devices/system/soc/mach/foo_id
/sys/devices/system/soc/mach/bar_id<- Vendors may have several/different IDs to export (IDCODE for OMAP, Production ID...)
Linus, do you agree?
>> I still think it is a solution in search of a problem though. What
>> userspace programs need to know what specific SoC they are on? My
>> feeling is that if userspace needs to know this information, then it is
>> probably dicking around with things that should be managed by the
>> kernel. Differences in available peripherals, etc can be determined by
>> looking at existing sysfs files.
> I certainly have seen several use cases. Couple of easy examples:
>
> * A lot of test scripts would find this very useful. For example, some
> clock (present is all/most MSMs) shouldn't be tested on some SOCs as it
> would lock up the system if you try to turn it off while the CPU is running.
>
> * Some of the user space tools might want to report different "product
> id/type" (nothing to do with USB, etc) depending on what SOC it is
> running on.
>
For example, we have some user-space tools which need to have serial
number to write it in logs.
> Thank,
> Saravana
> P.S: Removed felipe.balbi at nokia.com<felipe.balbi@nokia.com> since I
> keep getting delivery failure emails.
>
^ permalink raw reply
* CONFIG_ARM_DMA_MEM_BUFFERABLE and readl/writel weirdness
From: Arnd Bergmann @ 2011-03-02 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D6D9C03.2080906@codeaurora.org>
On Wednesday 02 March 2011 02:23:15 Saravana Kannan wrote:
> There are so many other drivers that don't use or care about DMA and
> might still want to ensure some ordering constraints between their
> readl(s)/writel(s). They can't depend on readl/writel taking care of it
> for them since their code could be used in a kernel configuration that
> doesn't enable this config.
What exactly are the ordering constraints, do you need the full
dmb() for readl() and dsb() for writel(), or just a compiler barrier?
I think we need the barrier() even for the relaxed variant, but
that is fairly lightweight. What would be a reason to have more?
> Firstly, I don't know how many people noticed this and realize they
> can't depend on readl/writel to take care of the mb()s for them. Seems
> like an unnecessary encouragement to make mistakes when it didn't need
> to be so.
>
> Secondly, even if they realize they have to take care of it, they will
> have to continue using mb()s in to force ordering between their
> reads/writes. So, are we depending on the compiler to optimize these
> extra mb() out in the case where the config is enabled? I'm not sure it
> will be able to optimize out the extra mb()s in all cases.
The compiler certainly won't merge multiple inline assembly statements,
but multiple barrier() statements don't make it worse than just one.
barrier() just forces accessing variables from memory that could otherwise
be kept in registers.
The other problems we still need to fix are the complete absence of
barriers in inb()/outb() style accessors, which are meant to be stricter
than readl()/writel(), and the fact that we rely on undefined behavior
in gcc regarding the atomicity of multi-byte accesses, as we recently
found out when a new gcc turned a readl into byte accesses.
Arnd
^ permalink raw reply
* [PATCH 1/5] ARM: mx35_3ds: Add I2C support
From: Sascha Hauer @ 2011-03-02 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=c_vWNqBbqPzRpCzWD-s5PFvLmD8ROr=Jss1hA@mail.gmail.com>
On Wed, Mar 02, 2011 at 03:14:30PM +0800, Jason Liu wrote:
> Hi, Uwe,
>
> 2011/3/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> > On Tue, Mar 01, 2011 at 04:59:44PM -0300, Fabio Estevam wrote:
> >> + ? ? imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
> > I'd slightly prefer using
> >
> > ? ? ? ?imx35_add_imx_i2c(0, ...)
> >
> > because I intend to remove the imx35_add_imx_i2c0-like macros soon. ?But
>
> Could you please explain why you intend to remove
> imx35_add_imx_i2c0-like macros?
> What you would like to do instead? Thanks,
These just produce additional macros without value.
Sascha
--
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
* CONFIG_ARM_DMA_MEM_BUFFERABLE and readl/writel weirdness
From: Russell King - ARM Linux @ 2011-03-02 8:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D6D9C03.2080906@codeaurora.org>
On Tue, Mar 01, 2011 at 05:23:15PM -0800, Saravana Kannan wrote:
> If I'm not missing some magic, this would mean that
> "CONFIG_ARM_DMA_MEM_BUFFERABLE" determines if readl(s)/writel(s) get to
> have a built in mb() or not.
You're missing that CONFIG_ARM_DMA_MEM_BUFFERABLE not only changes
readl/writel but also the type for DMA coherent memory from strongly
ordered to memory, non-cacheable.
The barriers are required to ensure that reads and writes to DMA
coherent memory are visible to the DMA device before the write
completes, and any value read from DMA coherent memory will not
bypass a read from a DMA device.
The barriers in the IO macros have nothing to do with whether reads/writes
to normal cacheable memory are visible to DMA devices. That is what the
streaming DMA API is for.
In any case, the IO macros are always ordered with respect to other
device writes irrespective of CONFIG_ARM_DMA_MEM_BUFFERABLE.
> There are so many other drivers that don't use or care about DMA and
> might still want to ensure some ordering constraints between their
> readl(s)/writel(s). They can't depend on readl/writel taking care of it
> for them since their code could be used in a kernel configuration that
> doesn't enable this config.
The majority of device drivers don't need ordering on their IO macros.
However, Linus refuses to introduce relaxed IO ordering to the kernel,
saying that architectures must reflect the x86 behaviour as much as
possible.
So, we're stuck with device drivers which use readl/writel both where
they don't need the ordering constraints _and_ where they do need the
ordering constraints. That means we must provide the ordering in these
macros to ensure proper system functioning.
> Firstly, I don't know how many people noticed this and realize they
> can't depend on readl/writel to take care of the mb()s for them. Seems
> like an unnecessary encouragement to make mistakes when it didn't need
> to be so.
I think you misunderstand what's going on. IO accesses are always ordered
with respect to themselves. The barriers are there to ensure ordering
between DMA coherent memory (normal non-cached memory) and IO accesses
(device).
^ permalink raw reply
* [PATCH 2/2] ARM MX53_LOCO: add pwm backlight device
From: Sascha Hauer @ 2011-03-02 8:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298972303-1010-2-git-send-email-b02280@freescale.com>
On Tue, Mar 01, 2011 at 05:38:23PM +0800, Jason Chen wrote:
> Signed-off-by: Jason Chen <b02280@freescale.com>
> ---
> arch/arm/mach-mx5/Kconfig | 1 +
> arch/arm/mach-mx5/board-mx53_loco.c | 11 +++++++++++
> arch/arm/mach-mx5/devices-imx53.h | 4 ++++
> 3 files changed, 16 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
> index f065a0d..baf5223 100644
> --- a/arch/arm/mach-mx5/Kconfig
> +++ b/arch/arm/mach-mx5/Kconfig
> @@ -162,6 +162,7 @@ config MACH_MX53_LOCO
> select IMX_HAVE_PLATFORM_IMX2_WDT
> select IMX_HAVE_PLATFORM_IMX_I2C
> select IMX_HAVE_PLATFORM_IMX_UART
> + select IMX_HAVE_PLATFORM_MXC_PWM
> help
> Include support for MX53 LOCO platform. This includes specific
> configurations for the board and its peripherals.
> diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
> index 160899e..3b0b200 100644
> --- a/arch/arm/mach-mx5/board-mx53_loco.c
> +++ b/arch/arm/mach-mx5/board-mx53_loco.c
> @@ -23,6 +23,7 @@
> #include <linux/fec.h>
> #include <linux/delay.h>
> #include <linux/gpio.h>
> +#include <linux/pwm_backlight.h>
>
> #include <mach/common.h>
> #include <mach/hardware.h>
> @@ -203,6 +204,13 @@ static const struct imxi2c_platform_data mx53_loco_i2c_data __initconst = {
> .bitrate = 100000,
> };
>
> +static struct platform_pwm_backlight_data loco_pwm_backlight_data = {
> + .pwm_id = 1,
> + .max_brightness = 255,
> + .dft_brightness = 128,
> + .pwm_period_ns = 50000,
> +};
> +
> static void __init mx53_loco_board_init(void)
> {
> mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
> @@ -213,6 +221,9 @@ static void __init mx53_loco_board_init(void)
> imx53_add_imx2_wdt(0, NULL);
> imx53_add_imx_i2c(0, &mx53_loco_i2c_data);
> imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
> +
> + imx53_add_mxc_pwm(1);
> + imx53_add_mxc_pwm_backlight(0, &loco_pwm_backlight_data);
> }
>
> static void __init mx53_loco_timer_init(void)
> diff --git a/arch/arm/mach-mx5/devices-imx53.h b/arch/arm/mach-mx5/devices-imx53.h
> index 5a1d6c9..e9c5661 100644
> --- a/arch/arm/mach-mx5/devices-imx53.h
> +++ b/arch/arm/mach-mx5/devices-imx53.h
> @@ -37,3 +37,7 @@ extern const struct imx_imx2_wdt_data imx53_imx2_wdt_data[] __initconst;
> extern const struct imx_mxc_pwm_data imx53_mxc_pwm_data[] __initconst;
> #define imx53_add_mxc_pwm(id) \
> imx_add_mxc_pwm(&imx53_mxc_pwm_data[id])
> +
> +#define imx53_add_mxc_pwm_backlight(id, pdata) \
> + imx_add_platform_device("pwm-backlight", id, NULL, \
> + 0, pdata, sizeof(*pdata));
No. There is nothing i.MX53 specific in this, not even i.MX specific.
Please just add a static struct platform_device or maybe
platform_device_register_resndata.
Sascha
--
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 v7 1/1] PRUSS UIO driver support
From: TK, Pratheesh Gangadhar @ 2011-03-02 8:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1103012238360.2701@localhost6.localdomain6>
Hi,
> From: Thomas Gleixner [mailto:tglx at linutronix.de]
> Sent: Wednesday, March 02, 2011 3:15 AM
> > +
> > +static DEFINE_SPINLOCK(lock);
> > +static struct clk *pruss_clk;
> > +static struct uio_info *info;
> > +static dma_addr_t sram_paddr, ddr_paddr;
> > +static void *prussio_vaddr, *sram_vaddr, *ddr_vaddr;
> > +
> > +static irqreturn_t pruss_handler(int irq, struct uio_info *info)
> > +{
> > + int intr_bit = (irq - IRQ_DA8XX_EVTOUT0 + 2);
> > + int val, intr_mask = (1 << intr_bit);
> > + void __iomem *base = info->mem[0].internal_addr;
> > + void __iomem *intren_reg = base + PINTC_HIER;
> > + void __iomem *intrstat_reg = base + PINTC_HIPIR + (intr_bit << 2);
> > +
> > + spin_lock_irq(&lock);
>
> No, I said: spin_lock() is sufficient.
Ok.
> > + val = ioread32(intren_reg);
> > + /* Is interrupt enabled and active ? */
> > + if (!(val & intr_mask) && (ioread32(intrstat_reg) & HIPIR_NOPEND)) {
> > + spin_unlock_irq(&lock);
>
> You unconditinally enable interrupts here where you are not supposed
> to do so.
>
Ok.
> > + return IRQ_NONE;
> > + }
> > +
> > + /* Disable interrupt */
> > + iowrite32((val & ~intr_mask), intren_reg);
I checked more on this and actually INTC h/w has Host Interrupt
Enable Indexed Set Register (HIEISR) and Host Interrupt Enable Indexed
Clear Register(HIEICR) which I can use to enable/disable interrupts
without doing RMW. I will use these registers and then we don't need
all the spinlock and irqcontrol stuff. So I need to do
iowrite32((intr_bit, HIEICR);// This disable the interrupt bit
in intern_reg.
Userspace can use HIEISR to re-enable the interrupt.
> > + spin_unlock_irq(&lock);
> > + return IRQ_HANDLED;
> > +}
> > +
> > +static int pruss_irqcontrol(struct uio_info *info, s32 irq_on)
> > +{
> > + int intr_bit = info->irq - IRQ_DA8XX_EVTOUT0 + 2;
> > + int val, intr_mask = (1 << intr_bit);
> > + void __iomem *base = info->mem[0].internal_addr;
> > + void __iomem *intren_reg = base + PINTC_HIER;
> > +
> > + spin_lock_irq(&lock);
>
> This one is correct, as this is always called from non interrupt
> disabled context.
>
> > + val = ioread32(intren_reg);
> > + if (irq_on)
> > + iowrite32((val | intr_mask), intren_reg);
> > + else
> > + iowrite32((val & ~intr_mask), intren_reg);
> > + spin_unlock_irq(&lock);
> > +
> > + return 0;
> > +}
>
>
> > +
> > + spin_lock_init(&lock);
>
> Sigh. DEFINE_SPINLOCK(lock); already initializes the lock.
>
> It's not the purpose of a review to tell you what you need to change
> mechanically. Reviewers hint to a correct solution and you are
> supposed to lookup what that solution means and act accordingly. If
> you do not understand the hint or its implications please ask _before_
> sending a new patch set.
Seriously, I went to "fix the comments" mode. Sorry about that. Anyway
I learnt more about things by making mistakes i.e. the positive side.
Thanks a lot for helping us improve on this.
Pratheesh
^ permalink raw reply
* [PATCHv5 0/3] Introduce the /proc/socinfo and use it to export OMAP data
From: Maxime Coquelin @ 2011-03-02 8:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D6DBF59.2050005@bluewatersys.com>
On 03/02/2011 04:54 AM, Ryan Mallon wrote:
> On 03/02/2011 04:46 PM, Saravana Kannan wrote:
>> On 03/01/2011 07:35 PM, Ryan Mallon wrote:
>>> The only real objection I have to adding the SoC family information is
>>> basically to discourage it being abused by userspace. I can see it being
>>> useful in debug situations, but I can also see stupid userspace
>>> applications explicitly testing for some particular SoC, rather than
>>> more correctly (IMHO) checking for presence of certain drivers etc.
>> True, but so many other things could be misused by stupid userspace
>> programs. When there are legitimate usecases, I think we shouldn't
>> prevent them just because we think a stupid userspace program could
>> misuse it.
>>
>> Again, although you might not be gung-ho about this, I think I have at
>> least made you indifferent/mildly supportive to adding socinfo. If you
>> don't mind, I would like to wait for others to chime in before
>> continuing this discussion.
> Agreed.
>
> In general I am in support of having the SoC information exposed
> somewhere. I think we just want to be careful that it doesn't become a
> dumping ground for anything and everything SoC related whether the
> information is useful or not. I think each piece of exposed information
> should have a genuine use case, not just "because we can".
I definitely agree we should not export every SoC-related information
just because we can do it.
The first goal of this interface was to export some SoCs IDs, as we need
this kind of information for some user-space tools.
Does someone need to export other information than the mach name and
some IDs?
As proposed in my previous mail, do you agree to have a unified file for
all vendors, which exports the unique silicon ID of the chip?
Regards,
Maxime
^ permalink raw reply
* [PATCH 6/6] ARM: nmk: update GPIO chained IRQ handler to use EOI in parent chip
From: Russell King - ARM Linux @ 2011-03-02 8:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1103012133530.2701@localhost6.localdomain6>
On Tue, Mar 01, 2011 at 10:29:37PM +0100, Thomas Gleixner wrote:
> Errm. I did never say that we disable the parent interrupt by any
> means except when the chained handler explicitely wants to do that,
> which is pretty much pointlesss nowadays, as we run all interrupt
> handlers with interrupts disabled.
And that's now why some platforms struggle to work, and we're having
to bodge around this - like the ARM platforms with MMC support. Like
some other platforms where having IRQs disabled during IDE prevents
interrupts being recevied for long periods of time (longer than the
100Hz tick period).
I *violently* disagree with the direction that genirq is heading. It's
*actively* breaking stuff. What's really annoying is that problems like
the above I did point out, but you seem happy to completely ignore them.
The result is that more and more ARM platforms *are* becoming utterly
useless, or requiring additional complexity being shoved into subsystems
to cope with this crap.
What we need is a *decent* IRQ support system. Not something created out
of religious arguments which is what we have now.
^ permalink raw reply
* [PATCH 1/5] ARM: mx35_3ds: Add I2C support
From: Jason Liu @ 2011-03-02 8:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110302083736.GR29521@pengutronix.de>
Hi, Sascha,
2011/3/2 Sascha Hauer <s.hauer@pengutronix.de>:
> On Wed, Mar 02, 2011 at 03:14:30PM +0800, Jason Liu wrote:
>> Hi, Uwe,
>>
>> 2011/3/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello,
>> >
>> > On Tue, Mar 01, 2011 at 04:59:44PM -0300, Fabio Estevam wrote:
>> >> + ? ? imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
>> > I'd slightly prefer using
>> >
>> > ? ? ? ?imx35_add_imx_i2c(0, ...)
>> >
>> > because I intend to remove the imx35_add_imx_i2c0-like macros soon. ?But
>>
>> Could you please explain why you intend to remove
>> imx35_add_imx_i2c0-like macros?
>> What you would like to do instead? Thanks,
>
> These just produce additional macros without value.
Get it. Thanks,
>
> Sascha
>
>
> --
> 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] arm: mxs: add irq_chip-name for GPIO IRQs
From: Shawn Guo @ 2011-03-02 9:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298971311-21937-1-git-send-email-w.sang@pengutronix.de>
On Tue, Mar 01, 2011 at 10:21:51AM +0100, Wolfram Sang wrote:
> Reported-by: Alexander Stein <alexander.stein@systec-electronic.com>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> ---
> arch/arm/mach-mxs/gpio.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
Acked-by: Shawn Guo <shawn.guo@freescale.com>
--
Regards,
Shawn
^ permalink raw reply
* [PATCH 6/6] ARM: nmk: update GPIO chained IRQ handler to use EOI in parent chip
From: Thomas Gleixner @ 2011-03-02 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110302085356.GB4493@n2100.arm.linux.org.uk>
On Wed, 2 Mar 2011, Russell King - ARM Linux wrote:
> On Tue, Mar 01, 2011 at 10:29:37PM +0100, Thomas Gleixner wrote:
> > Errm. I did never say that we disable the parent interrupt by any
> > means except when the chained handler explicitely wants to do that,
> > which is pretty much pointlesss nowadays, as we run all interrupt
> > handlers with interrupts disabled.
>
> And that's now why some platforms struggle to work, and we're having
> to bodge around this - like the ARM platforms with MMC support. Like
Whats the problem for MMC?
> some other platforms where having IRQs disabled during IDE prevents
> interrupts being recevied for long periods of time (longer than the
> 100Hz tick period).
That was discussed to death already and the general agreement was that
those handlers should either enable interrupts themself, when it's
required, or being converted to threaded handlers. An interrupt
handler or any other code section which runs more than 10ms with
interrupts disabled is a bug by definition.
> I *violently* disagree with the direction that genirq is heading. It's
> *actively* breaking stuff. What's really annoying is that problems like
> the above I did point out, but you seem happy to completely ignore them.
> The result is that more and more ARM platforms *are* becoming utterly
> useless, or requiring additional complexity being shoved into subsystems
> to cope with this crap.
>
> What we need is a *decent* IRQ support system. Not something created out
> of religious arguments which is what we have now.
I'm not religious about it, at least not more than you with your total
refusement to distinguish between special case oddball FPGA demux and
bog standard functional irq chips.
Thanks,
tglx
^ permalink raw reply
* [PATCH v7 1/1] PRUSS UIO driver support
From: Thomas Gleixner @ 2011-03-02 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <B85A65D85D7EB246BE421B3FB0FBB593024BF36776@dbde02.ent.ti.com>
On Wed, 2 Mar 2011, TK, Pratheesh Gangadhar wrote:
> > From: Thomas Gleixner [mailto:tglx at linutronix.de]
> > > + /* Disable interrupt */
> > > + iowrite32((val & ~intr_mask), intren_reg);
>
> I checked more on this and actually INTC h/w has Host Interrupt
> Enable Indexed Set Register (HIEISR) and Host Interrupt Enable Indexed
> Clear Register(HIEICR) which I can use to enable/disable interrupts
> without doing RMW. I will use these registers and then we don't need
> all the spinlock and irqcontrol stuff. So I need to do
>
> iowrite32((intr_bit, HIEICR);// This disable the interrupt bit
> in intern_reg.
>
> Userspace can use HIEISR to re-enable the interrupt.
Great, that makes it way simpler!
> > It's not the purpose of a review to tell you what you need to change
> > mechanically. Reviewers hint to a correct solution and you are
> > supposed to lookup what that solution means and act accordingly. If
> > you do not understand the hint or its implications please ask _before_
> > sending a new patch set.
>
> Seriously, I went to "fix the comments" mode. Sorry about that. Anyway
> I learnt more about things by making mistakes i.e. the positive side.
> Thanks a lot for helping us improve on this.
Welcome!
tglx
^ permalink raw reply
* [RFC PATCH 1/1] ARM: imx5x: clean up ARCH_MX5X
From: Shawn Guo @ 2011-03-02 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299036526-15674-1-git-send-email-richard.zhao@freescale.com>
On Wed, Mar 02, 2011 at 11:28:46AM +0800, Richard Zhao wrote:
> Remove legacy support of ARCH_MX5X. Move to SOC_SOC_IMX5X.
>
+1
As SOC_IMXxx is introduced, ARCH_MXxx seems a little bit messy to me.
--
Regards,
Shawn
^ permalink raw reply
* [PATCH 1/2 v2] ARM: iomux-imx31: allow pin_list to be const
From: Uwe Kleine-König @ 2011-03-02 9:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299011621-18886-1-git-send-email-u.kleine-koenig@pengutronix.de>
This fixes the following warning in a mx3_defconfig build:
arch/arm/mach-mx3/mach-bug.c: In function 'bug_board_init':
arch/arm/mach-mx3/mach-bug.c:47: warning: passing argument 1 of 'mxc_iomux_setup_multiple_pins' discards qualifiers from pointer target type
While at it remove some useless consts from unsigned int arguments.
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
Hello,
while testing the first version Sascha noticed that the
mxc_iomux_release_multiple_pins function needs a const, too, because
it's called by mxc_iomux_setup_multiple_pins in the error path.
(And it's a logical thing to do, too.)
When implementing that I wondered about the useless const unsigned ints
and removed them.
Thanks
Uwe
arch/arm/mach-mx3/iomux-imx31.c | 12 ++++++------
arch/arm/plat-mxc/include/mach/iomux-mx3.h | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-mx3/iomux-imx31.c b/arch/arm/mach-mx3/iomux-imx31.c
index a1d7fa5..cf8f809 100644
--- a/arch/arm/mach-mx3/iomux-imx31.c
+++ b/arch/arm/mach-mx3/iomux-imx31.c
@@ -97,7 +97,7 @@ EXPORT_SYMBOL(mxc_iomux_set_pad);
* - reserves the pin so that it is not claimed by another driver
* - setups the iomux according to the configuration
*/
-int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
+int mxc_iomux_alloc_pin(unsigned int pin, const char *label)
{
unsigned pad = pin & IOMUX_PADNUM_MASK;
@@ -118,10 +118,10 @@ int mxc_iomux_alloc_pin(const unsigned int pin, const char *label)
}
EXPORT_SYMBOL(mxc_iomux_alloc_pin);
-int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
const char *label)
{
- unsigned int *p = pin_list;
+ const unsigned int *p = pin_list;
int i;
int ret = -EINVAL;
@@ -139,7 +139,7 @@ setup_error:
}
EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
-void mxc_iomux_release_pin(const unsigned int pin)
+void mxc_iomux_release_pin(unsigned int pin)
{
unsigned pad = pin & IOMUX_PADNUM_MASK;
@@ -148,9 +148,9 @@ void mxc_iomux_release_pin(const unsigned int pin)
}
EXPORT_SYMBOL(mxc_iomux_release_pin);
-void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count)
{
- unsigned int *p = pin_list;
+ const unsigned int *p = pin_list;
int i;
for (i = 0; i < count; i++) {
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
index cbaed29..c92f0b1 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h
@@ -112,12 +112,12 @@ enum iomux_gp_func {
* - setups the iomux according to the configuration
* - if the pin is configured as a GPIO, we claim it through kernel gpiolib
*/
-int mxc_iomux_alloc_pin(const unsigned int pin, const char *label);
+int mxc_iomux_alloc_pin(unsigned int pin, const char *label);
/*
* setups mutliple pins
* convenient way to call the above function with tables
*/
-int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
const char *label);
/*
@@ -126,12 +126,12 @@ int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
* - frees the GPIO if the pin was configured as GPIO
* - DOES NOT reconfigure the IOMUX in its reset state
*/
-void mxc_iomux_release_pin(const unsigned int pin);
+void mxc_iomux_release_pin(unsigned int pin);
/*
* releases multiple pins
* convenvient way to call the above function with tables
*/
-void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count);
/*
* This function enables/disables the general purpose function for a particular
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/2 v2] ARM: mxc91231/iomux: allow pin_list to be const
From: Uwe Kleine-König @ 2011-03-02 9:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299011621-18886-1-git-send-email-u.kleine-koenig@pengutronix.de>
While at it remove some useless consts from unsigned int arguments.
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
arch/arm/mach-mxc91231/iomux.c | 14 +++++++-------
arch/arm/plat-mxc/include/mach/iomux-mxc91231.h | 8 ++++----
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/arch/arm/mach-mxc91231/iomux.c b/arch/arm/mach-mxc91231/iomux.c
index 405d9b1..66fc41c 100644
--- a/arch/arm/mach-mxc91231/iomux.c
+++ b/arch/arm/mach-mxc91231/iomux.c
@@ -50,7 +50,7 @@ unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
/*
* set the mode for a IOMUX pin.
*/
-int mxc_iomux_mode(const unsigned int pin_mode)
+int mxc_iomux_mode(unsigned int pin_mode)
{
u32 side, field, l, mode, ret = 0;
void __iomem *reg;
@@ -114,7 +114,7 @@ EXPORT_SYMBOL(mxc_iomux_set_pad);
* - reserves the pin so that it is not claimed by another driver
* - setups the iomux according to the configuration
*/
-int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
+int mxc_iomux_alloc_pin(unsigned int pin_mode, const char *label)
{
unsigned pad = PIN_GLOBAL_NUM(pin_mode);
if (pad >= (PIN_MAX + 1)) {
@@ -134,10 +134,10 @@ int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
}
EXPORT_SYMBOL(mxc_iomux_alloc_pin);
-int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
const char *label)
{
- unsigned int *p = pin_list;
+ const unsigned int *p = pin_list;
int i;
int ret = -EINVAL;
@@ -155,7 +155,7 @@ setup_error:
}
EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
-void mxc_iomux_release_pin(const unsigned int pin_mode)
+void mxc_iomux_release_pin(unsigned int pin_mode)
{
unsigned pad = PIN_GLOBAL_NUM(pin_mode);
@@ -164,9 +164,9 @@ void mxc_iomux_release_pin(const unsigned int pin_mode)
}
EXPORT_SYMBOL(mxc_iomux_release_pin);
-void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count)
{
- unsigned int *p = pin_list;
+ const unsigned int *p = pin_list;
int i;
for (i = 0; i < count; i++) {
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
index 15d5951..bf28df0 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
@@ -46,12 +46,12 @@
* - setups the iomux according to the configuration
* - if the pin is configured as a GPIO, we claim it through kernel gpiolib
*/
-int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label);
+int mxc_iomux_alloc_pin(unsigned int pin_mode, const char *label);
/*
* setups mutliple pins
* convenient way to call the above function with tables
*/
-int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
+int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
const char *label);
/*
@@ -60,12 +60,12 @@ int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
* - frees the GPIO if the pin was configured as GPIO
* - DOES NOT reconfigure the IOMUX in its reset state
*/
-void mxc_iomux_release_pin(const unsigned int pin_mode);
+void mxc_iomux_release_pin(unsigned int pin_mode);
/*
* releases multiple pins
* convenvient way to call the above function with tables
*/
-void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);
+void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count);
#define MUX_SIDE_AP (0)
#define MUX_SIDE_SP (1)
--
1.7.2.3
^ permalink raw reply related
* [PATCH] ARM: SAMSUNG: Include devs.h in dev-uart.c to prototype devices
From: Mark Brown @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
Ensures that the declaration agrees with the definition and makes sparse
happy.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
arch/arm/plat-samsung/dev-uart.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-samsung/dev-uart.c b/arch/arm/plat-samsung/dev-uart.c
index 5928105..3776cd9 100644
--- a/arch/arm/plat-samsung/dev-uart.c
+++ b/arch/arm/plat-samsung/dev-uart.c
@@ -15,8 +15,6 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
-#include <plat/devs.h>
-
/* uart devices */
static struct platform_device s3c24xx_uart_device0 = {
--
1.7.2.3
^ permalink raw reply related
* [PATCH V5 1/6] ARM: imx51/53: add sdhc3/4 clock
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
---
arch/arm/mach-mx5/clock-mx51-mx53.c | 140 ++++++++++++++++++++++++++++++++++-
arch/arm/mach-mx5/crm_regs.h | 7 ++
2 files changed, 146 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..652ace4 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 */
@@ -1143,10 +1146,80 @@ 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)
+static int clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else if (parent == &esdhc2_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static int clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc2_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+/* mx53 specific */
+static int clk_esdhc2_mx53_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
+ else if (parent == &esdhc3_mx53_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC2_MSHC2_MX53_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+CLK_GET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
+CLK_SET_PARENT(esdhc3_mx53, 1, ESDHC3_MX53)
+CLK_SET_RATE(esdhc3_mx53, 1, ESDHC3_MX53)
+
+static int clk_esdhc4_mx53_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk)
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc3_mx53_clk)
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
static struct clk name = { \
.id = i, \
@@ -1251,9 +1324,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 +1438,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 +1460,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 +1555,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
^ permalink raw reply related
* [PATCH V5 2/6] mmc: sdhci-esdhc: remove SDHCI_QUIRK_NO_CARD_NO_RESET from ESDHC_DEFAULT_QUIRKS
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299060283-6404-1-git-send-email-Hong-Xing.Zhu@freescale.com>
sdhci-esdhc-imx does not need SDHCI_QUIRK_NO_CARD_NO_RESET. Make it OF-specific.
Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
Tested-by: Wolfram Sang <w.sang@pengutronix.de>
---
drivers/mmc/host/sdhci-esdhc.h | 3 +--
drivers/mmc/host/sdhci-of-esdhc.c | 3 ++-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index c55aae8..c3b08f1 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -23,8 +23,7 @@
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
- SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \
- SDHCI_QUIRK_NO_CARD_NO_RESET)
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
#define ESDHC_SYSTEM_CONTROL 0x2c
#define ESDHC_CLOCK_MASK 0x0000fff0
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 08161f6..ba40d6d 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -74,7 +74,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
struct sdhci_of_data sdhci_esdhc = {
/* card detection could be handled via GPIO */
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
+ | SDHCI_QUIRK_NO_CARD_NO_RESET,
.ops = {
.read_l = sdhci_be32bs_readl,
.read_w = esdhc_readw,
--
1.7.1
^ permalink raw reply related
* [PATCH V5 3/6] mmc: add the abort CMDTYE bits definition
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299060283-6404-1-git-send-email-Hong-Xing.Zhu@freescale.com>
Add the abort CMDTYPE bits definition of command register (offset 0xE)
Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
---
drivers/mmc/host/sdhci.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 6e0969e..25e8bde 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -45,6 +45,7 @@
#define SDHCI_CMD_CRC 0x08
#define SDHCI_CMD_INDEX 0x10
#define SDHCI_CMD_DATA 0x20
+#define SDHCI_CMD_ABORTCMD 0xC0
#define SDHCI_CMD_RESP_NONE 0x00
#define SDHCI_CMD_RESP_LONG 0x01
--
1.7.1
^ permalink raw reply related
* [PATCH V5 4/6] mmc: sdhci-esdhc: make the writel/readl as the general APIs
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299060283-6404-1-git-send-email-Hong-Xing.Zhu@freescale.com>
Add one flag to indicate the GPIO CD/WP is enabled or not
on imx platforms, and reuse the writel/readl as the general
APIs for imx SOCs.
Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 40 ++++++++++++++++++++++++++++++-----
1 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3b52485..42f5687 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
#include <mach/hardware.h>
@@ -24,6 +25,13 @@
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+#define IMX_GPIO_CD_WP (1 << 0)
+
+struct pltfm_imx_data {
+ int flags;
+ u32 mod_val;
+};
+
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
{
void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -34,10 +42,15 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data =
+ (struct pltfm_imx_data *)pltfm_host->scratchpad;
+
/* fake CARD_PRESENT flag on mx25/35 */
u32 val = readl(host->ioaddr + reg);
- if (unlikely(reg == SDHCI_PRESENT_STATE)) {
+ if (unlikely((reg == SDHCI_PRESENT_STATE)
+ && (imx_data->flags & IMX_GPIO_CD_WP))) {
struct esdhc_platform_data *boarddata =
host->mmc->parent->platform_data;
@@ -55,7 +68,12 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
{
- if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data =
+ (struct pltfm_imx_data *)pltfm_host->scratchpad;
+
+ if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
+ && (imx_data->flags & IMX_GPIO_CD_WP)))
/*
* these interrupts won't work with a custom card_detect gpio
* (only applied to mx25/35)
@@ -76,6 +94,8 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data =
+ (struct pltfm_imx_data *)pltfm_host->scratchpad;
switch (reg) {
case SDHCI_TRANSFER_MODE:
@@ -83,10 +103,10 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
- pltfm_host->scratchpad = val;
+ imx_data->mod_val = val;
return;
case SDHCI_COMMAND:
- writel(val << 16 | pltfm_host->scratchpad,
+ writel(val << 16 | imx_data->mod_val,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
case SDHCI_BLOCK_SIZE:
@@ -146,7 +166,9 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
}
static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
+ .write_l = esdhc_writel_le,
.write_w = esdhc_writew_le,
.write_b = esdhc_writeb_le,
.set_clock = esdhc_set_clock,
@@ -168,6 +190,10 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
struct clk *clk;
int err;
+ struct pltfm_imx_data *imx_data;
+
+ imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ pltfm_host->scratchpad = (u32)imx_data;
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
@@ -214,8 +240,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
goto no_card_detect_irq;
}
- sdhci_esdhc_ops.write_l = esdhc_writel_le;
- sdhci_esdhc_ops.read_l = esdhc_readl_le;
+ imx_data->flags |= IMX_GPIO_CD_WP;
/* Now we have a working card_detect again */
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
@@ -234,6 +259,8 @@ 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;
+ struct pltfm_imx_data *imx_data =
+ (struct pltfm_imx_data *)pltfm_host->scratchpad;
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
gpio_free(boarddata->wp_gpio);
@@ -247,6 +274,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
+ kfree(imx_data);
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
--
1.7.1
^ permalink raw reply related
* [PATCH V5 5/6] mmc: sdhci-esdhc: enable esdhc on imx53
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299060283-6404-1-git-send-email-Hong-Xing.Zhu@freescale.com>
Fix the NO INT in the Multi-BLK IO in SD/MMC, and Multi-BLK
read in SDIO on imx53.
The CMDTYPE of the CMD register (offset 0xE) should be set to
"11" when the STOP CMD12 is issued on imx53 to abort one
open ended multi-blk IO. Otherwise one the TC INT wouldn't
be generated.
In exact block transfer, the controller doesn't complete the
operations automatically as required at the end of the
transfer and remains on hold if the abort command is not sent on
imx53.
As a result, the TC flag is not asserted and SW received timeout
exeception. set bit1 of Vendor Spec registor to fix it.
Signed-off-by: Richard Zhu <Hong-Xing.Zhu@freescale.com>
Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
---
drivers/mmc/host/sdhci-esdhc-imx.c | 44 +++++++++++++++++++++++++++++++++++-
1 files changed, 43 insertions(+), 1 deletions(-)
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 42f5687..9ef7bfd 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -19,13 +19,31 @@
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
#include <mach/hardware.h>
#include <mach/esdhc.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+/* VENDOR SPEC register */
+#define SDHCI_VENDOR_SPEC 0xC0
+#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+
#define IMX_GPIO_CD_WP (1 << 0)
+/*
+ * The CMDTYPE of the CMD register (offset 0xE) should be set to
+ * "11" when the STOP CMD12 is issued on imx53 to abort one
+ * open ended multi-blk IO. Otherwise the TC INT wouldn't
+ * be generated.
+ * In exact block transfer, the controller doesn't complete the
+ * operations automatically as required@the end of the
+ * transfer and remains on hold if the abort command is not sent.
+ * As a result, the TC flag is not asserted and SW received timeout
+ * exeception. Bit1 of Vendor Spec registor is used to fix it.
+ */
+#define IMX_MULTIBLK_NO_INT (1 << 1)
struct pltfm_imx_data {
int flags;
@@ -80,6 +98,15 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
*/
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+ if (unlikely((imx_data->flags & IMX_MULTIBLK_NO_INT)
+ && (reg == SDHCI_INT_STATUS)
+ && (val & SDHCI_INT_DATA_END))) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+
writel(val, host->ioaddr + reg);
}
@@ -103,9 +130,21 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
+ if ((host->cmd->opcode == SD_IO_RW_EXTENDED)
+ && (host->cmd->data->blocks > 1)
+ && (host->cmd->data->flags & MMC_DATA_READ)
+ && (imx_data->flags & IMX_MULTIBLK_NO_INT)) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
imx_data->mod_val = val;
return;
case SDHCI_COMMAND:
+ if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
+ && (imx_data->flags & IMX_MULTIBLK_NO_INT))
+ val |= SDHCI_CMD_ABORTCMD;
writel(val << 16 | imx_data->mod_val,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
@@ -203,7 +242,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
clk_enable(clk);
pltfm_host->clk = clk;
- if (cpu_is_mx35() || cpu_is_mx51())
+ if (!cpu_is_mx25())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
if (cpu_is_mx25() || cpu_is_mx35()) {
@@ -213,6 +252,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
}
+ if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
+ imx_data->flags |= IMX_MULTIBLK_NO_INT;
+
if (boarddata) {
err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
if (err) {
--
1.7.1
^ permalink raw reply related
* [PATCH V5 6/6] ARM: imx53_loco: add esdhc device support
From: Richard Zhu @ 2011-03-02 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299060283-6404-1-git-send-email-Hong-Xing.Zhu@freescale.com>
Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
Acked-by: Wolfram Sang <w.sang@pengutronix.de>
---
arch/arm/mach-mx5/Kconfig | 1 +
arch/arm/mach-mx5/board-mx53_loco.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index f065a0d..a72c833 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -162,6 +162,7 @@ config MACH_MX53_LOCO
select IMX_HAVE_PLATFORM_IMX2_WDT
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
help
Include support for MX53 LOCO platform. This includes specific
configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 160899e..0a18f8d 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -213,6 +213,8 @@ static void __init mx53_loco_board_init(void)
imx53_add_imx2_wdt(0, NULL);
imx53_add_imx_i2c(0, &mx53_loco_i2c_data);
imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
+ imx53_add_sdhci_esdhc_imx(0, NULL);
+ imx53_add_sdhci_esdhc_imx(2, NULL);
}
static void __init mx53_loco_timer_init(void)
--
1.7.1
^ 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