All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28
@ 2010-11-26  6:48 Shawn Guo
  2010-11-26  6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
                   ` (46 more replies)
  0 siblings, 47 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series is the successor of the following one.

[PATCH 00/11] ARM: imx: Add initial i.MX28 support
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/031464.html

It puts everything about MX23 and MX28 into mach-mxs to address
the concern from Uwe and Sascha.

It's being developed against Sascha's imx-for-2.6.38 tree,
and supports single image for MX23 and MX28, since they share
the same PHYS_OFFSET.

Shawn Guo (15):
 arch/arm/Kconfig                                |   10 +
 arch/arm/Makefile                               |    1 +
 arch/arm/mach-mxs/Kconfig                       |   34 +
 arch/arm/mach-mxs/Makefile                      |   14 +
 arch/arm/mach-mxs/Makefile.boot                 |    3 +
 arch/arm/mach-mxs/clock-mx23.c                  |  521 ++++++++++++++++
 arch/arm/mach-mxs/clock-mx28.c                  |  732 +++++++++++++++++++++++
 arch/arm/mach-mxs/clock.c                       |  201 +++++++
 arch/arm/mach-mxs/cpu.c                         |   11 +
 arch/arm/mach-mxs/devices-mx23.h                |   16 +
 arch/arm/mach-mxs/devices-mx28.h                |   22 +
 arch/arm/mach-mxs/devices.c                     |   75 +++
 arch/arm/mach-mxs/devices/Kconfig               |    5 +
 arch/arm/mach-mxs/devices/Makefile              |    2 +
 arch/arm/mach-mxs/devices/platform-duart.c      |   47 ++
 arch/arm/mach-mxs/devices/platform-fec.c        |   51 ++
 arch/arm/mach-mxs/gpio.c                        |  364 +++++++++++
 arch/arm/mach-mxs/icoll.c                       |   77 +++
 arch/arm/mach-mxs/include/mach/clkdev.h         |    7 +
 arch/arm/mach-mxs/include/mach/clock.h          |   64 ++
 arch/arm/mach-mxs/include/mach/common.h         |   33 +
 arch/arm/mach-mxs/include/mach/debug-macro.S    |   51 ++
 arch/arm/mach-mxs/include/mach/devices-common.h |   46 ++
 arch/arm/mach-mxs/include/mach/entry-macro.S    |   36 ++
 arch/arm/mach-mxs/include/mach/gpio.h           |   49 ++
 arch/arm/mach-mxs/include/mach/hardware.h       |   66 ++
 arch/arm/mach-mxs/include/mach/io.h             |   22 +
 arch/arm/mach-mxs/include/mach/iomux-mx23.h     |   29 +
 arch/arm/mach-mxs/include/mach/iomux-mx28.h     |   44 ++
 arch/arm/mach-mxs/include/mach/iomux.h          |   77 +++
 arch/arm/mach-mxs/include/mach/irqs.h           |   32 +
 arch/arm/mach-mxs/include/mach/memory.h         |   24 +
 arch/arm/mach-mxs/include/mach/mx23.h           |  147 +++++
 arch/arm/mach-mxs/include/mach/mx28.h           |  227 +++++++
 arch/arm/mach-mxs/include/mach/mxs.h            |   60 ++
 arch/arm/mach-mxs/include/mach/system.h         |   27 +
 arch/arm/mach-mxs/include/mach/timex.h          |   21 +
 arch/arm/mach-mxs/include/mach/uncompress.h     |   82 +++
 arch/arm/mach-mxs/include/mach/vmalloc.h        |   22 +
 arch/arm/mach-mxs/iomux.c                       |  110 ++++
 arch/arm/mach-mxs/mach-mx23evk.c                |   59 ++
 arch/arm/mach-mxs/mach-mx28evk.c                |  108 ++++
 arch/arm/mach-mxs/mm-mx23.c                     |   48 ++
 arch/arm/mach-mxs/mm-mx28.c                     |   48 ++
 arch/arm/mach-mxs/regs-clkctrl-mx23.h           |  455 ++++++++++++++
 arch/arm/mach-mxs/regs-clkctrl-mx28.h           |  663 ++++++++++++++++++++
 arch/arm/mach-mxs/system.c                      |  152 +++++
 arch/arm/mach-mxs/timer.c                       |  285 +++++++++
 48 files changed, 5280 insertions(+), 0 deletions(-)

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 01/15] ARM: mxs: Add core definitions
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-26 11:30   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
                   ` (45 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add core definitions for MXS-based SoC MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/hardware.h |   66 +++++++++
 arch/arm/mach-mxs/include/mach/irqs.h     |   32 ++++
 arch/arm/mach-mxs/include/mach/memory.h   |   24 +++
 arch/arm/mach-mxs/include/mach/mx23.h     |  147 +++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mx28.h     |  227 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mxs.h      |   60 ++++++++
 6 files changed, 556 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h

diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..5edccd5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr)	(addr)
+#else
+#define IOMEM(addr)	((void __force __iomem *)(addr))
+#endif
+
+#define MXS_IO_P2V_MODULE(addr, module)					\
+	(((addr) - module ## _BASE_ADDR) < module ## _SIZE ?		\
+	 (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
+ *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
+ */
+#define MXS_IO_P2V(x)	(						\
+			0xf4000000 + 					\
+			(((x) & 0x50000000) >> 6) +			\
+			(((x) & 0x0b000000) >> 4) +			\
+			(((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
+
+#ifdef CONFIG_SOC_IMX23
+# include <mach/mx23.h>
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# include <mach/mx28.h>
+#endif
+
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type)	{				\
+	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
+	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
+	.length = soc ## _ ## name ## _SIZE,				\
+	.type = _type,							\
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS	128
+
+#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS		(32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS		16
+
+#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET		UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..27a11ee
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR		0x00000000
+#define MX23_OCRAM_SIZE			SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR		0x80000000
+#define MX23_IO_SIZE			SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART			0
+#define MX23_INT_COMMS_RX		1
+#define MX23_INT_COMMS_TX		1
+#define MX23_INT_SSP2_ERROR		2
+#define MX23_INT_VDD5V			3
+#define MX23_INT_HEADPHONE_SHORT	4
+#define MX23_INT_DAC_DMA		5
+#define MX23_INT_DAC_ERROR		6
+#define MX23_INT_ADC_DMA		7
+#define MX23_INT_ADC_ERROR		8
+#define MX23_INT_SPDIF_DMA		9
+#define MX23_INT_SAIF2_DMA		9
+#define MX23_INT_SPDIF_ERROR		10
+#define MX23_INT_SAIF1_IRQ		10
+#define MX23_INT_SAIF2_IRQ		10
+#define MX23_INT_USB_CTRL		11
+#define MX23_INT_USB_WAKEUP		12
+#define MX23_INT_GPMI_DMA		13
+#define MX23_INT_SSP1_DMA		14
+#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_GPIO0			16
+#define MX23_INT_GPIO1			17
+#define MX23_INT_GPIO2			18
+#define MX23_INT_SAIF1_DMA		19
+#define MX23_INT_SSP2_DMA		20
+#define MX23_INT_ECC8_IRQ		21
+#define MX23_INT_RTC_ALARM		22
+#define MX23_INT_UARTAPP_TX_DMA		23
+#define MX23_INT_UARTAPP_INTERNAL	24
+#define MX23_INT_UARTAPP_RX_DMA		25
+#define MX23_INT_I2C_DMA		26
+#define MX23_INT_I2C_ERROR		27
+#define MX23_INT_TIMER0			28
+#define MX23_INT_TIMER1			29
+#define MX23_INT_TIMER2			30
+#define MX23_INT_TIMER3			31
+#define MX23_INT_BATT_BRNOUT		32
+#define MX23_INT_VDDD_BRNOUT		33
+#define MX23_INT_VDDIO_BRNOUT		34
+#define MX23_INT_VDD18_BRNOUT		35
+#define MX23_INT_TOUCH_DETECT		36
+#define MX23_INT_LRADC_CH0		37
+#define MX23_INT_LRADC_CH1		38
+#define MX23_INT_LRADC_CH2		39
+#define MX23_INT_LRADC_CH3		40
+#define MX23_INT_LRADC_CH4		41
+#define MX23_INT_LRADC_CH5		42
+#define MX23_INT_LRADC_CH6		43
+#define MX23_INT_LRADC_CH7		44
+#define MX23_INT_LCDIF_DMA		45
+#define MX23_INT_LCDIF_ERROR		46
+#define MX23_INT_DIGCTL_DEBUG_TRAP	47
+#define MX23_INT_RTC_1MSEC		48
+#define MX23_INT_DRI_DMA		49
+#define MX23_INT_DRI_ATTENTION		50
+#define MX23_INT_GPMI_ATTENTION		51
+#define MX23_INT_IR			52
+#define MX23_INT_DCP_VMI		53
+#define MX23_INT_DCP			54
+#define MX23_INT_BCH			56
+#define MX23_INT_PXP			57
+#define MX23_INT_UARTAPP2_TX_DMA	58
+#define MX23_INT_UARTAPP2_INTERNAL	59
+#define MX23_INT_UARTAPP2_RX_DMA	60
+#define MX23_INT_VDAC_DETECT		61
+#define MX23_INT_VDD5V_DROOP		64
+#define MX23_INT_DCDC4P2_BO		65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..836d807
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR		0x00000000
+#define MX28_OCRAM_SIZE			SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR		0x80000000
+#define MX28_IO_SIZE			SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT		0
+#define MX28_INT_VDDD_BRNOUT		1
+#define MX28_INT_VDDIO_BRNOUT		2
+#define MX28_INT_VDDA_BRNOUT		3
+#define MX28_INT_VDD5V_DROOP		4
+#define MX28_INT_DCDC4P2_BRNOUT		5
+#define MX28_INT_VDD5V			6
+#define MX28_INT_RESV7			7
+#define MX28_INT_CAN0			8
+#define MX28_INT_CAN1			9
+#define MX28_INT_LRADC_TOUCH		10
+#define MX28_INT_RESV11			11
+#define MX28_INT_RESV12			12
+#define MX28_INT_HSADC			13
+#define MX28_INT_IRADC_THRESH0		14
+#define MX28_INT_IRADC_THRESH1		15
+#define MX28_INT_LRADC_CH0		16
+#define MX28_INT_LRADC_CH1		17
+#define MX28_INT_LRADC_CH2		18
+#define MX28_INT_LRADC_CH3		19
+#define MX28_INT_LRADC_CH4		20
+#define MX28_INT_LRADC_CH5		21
+#define MX28_INT_LRADC_CH6		22
+#define MX28_INT_LRADC_CH7		23
+#define MX28_INT_LRADC_BUTTON0		24
+#define MX28_INT_LRADC_BUTTON1		25
+#define MX28_INT_RESV26			26
+#define MX28_INT_PERFMON		27
+#define MX28_INT_RTC_1MSEC		28
+#define MX28_INT_RTC_ALARM		29
+#define MX28_INT_RESV30			30
+#define MX28_INT_COMMS			31
+#define MX28_INT_EMI_ERR		32
+#define MX28_INT_RESV33			33
+#define MX28_INT_RESV34			34
+#define MX28_INT_RESV35			35
+#define MX28_INT_RESV36			36
+#define MX28_INT_RESV37			37
+#define MX28_INT_LCDIF			38
+#define MX28_INT_PXP			39
+#define MX28_INT_RESV40			40
+#define MX28_INT_BCH			41
+#define MX28_INT_GPMI			42
+#define MX28_INT_RESV43			43
+#define MX28_INT_RESV44			44
+#define MX28_INT_SPDIF_ERROR		45
+#define MX28_INT_RESV46			46
+#define MX28_INT_DUART			47
+#define MX28_INT_TIMER0			48
+#define MX28_INT_TIMER1			49
+#define MX28_INT_TIMER2			50
+#define MX28_INT_TIMER3			51
+#define MX28_INT_DCP_VMI		52
+#define MX28_INT_DCP			53
+#define MX28_INT_DCP_SECURE		54
+#define MX28_INT_RESV55			55
+#define MX28_INT_RESV56			56
+#define MX28_INT_RESV57			57
+#define MX28_INT_SAIF1			58
+#define MX28_INT_SAIF0			59
+#define MX28_INT_RESV60			60
+#define MX28_INT_RESV61			61
+#define MX28_INT_RESV62			62
+#define MX28_INT_RESV63			63
+#define MX28_INT_RESV64			64
+#define MX28_INT_RESV65			65
+#define MX28_INT_SPDIF_DMA		66
+#define MX28_INT_RESV67			67
+#define MX28_INT_I2C0_DMA		68
+#define MX28_INT_I2C1_DMA		69
+#define MX28_INT_AUART0_RX_DMA		70
+#define MX28_INT_AUART0_TX_DMA		71
+#define MX28_INT_AUART1_RX_DMA		72
+#define MX28_INT_AUART1_TX_DMA		73
+#define MX28_INT_AUART2_RX_DMA		74
+#define MX28_INT_AUART2_TX_DMA		75
+#define MX28_INT_AUART3_RX_DMA		76
+#define MX28_INT_AUART3_TX_DMA		77
+#define MX28_INT_AUART4_RX_DMA		78
+#define MX28_INT_AUART4_TX_DMA		79
+#define MX28_INT_SAIF0_DMA		80
+#define MX28_INT_SAIF1_DMA		81
+#define MX28_INT_SSP0_DMA		82
+#define MX28_INT_SSP1_DMA		83
+#define MX28_INT_SSP2_DMA		84
+#define MX28_INT_SSP3_DMA		85
+#define MX28_INT_LCDIF_DMA		86
+#define MX28_INT_HSADC_DMA		87
+#define MX28_INT_GPMI_DMA		88
+#define MX28_INT_DIGCTL_DEBUG_TRAP	89
+#define MX28_INT_RESV90			90
+#define MX28_INT_RESV91			91
+#define MX28_INT_USB1			92
+#define MX28_INT_USB0			93
+#define MX28_INT_USB1_WAKEUP		94
+#define MX28_INT_USB0_WAKEUP		95
+#define MX28_INT_SSP0			96
+#define MX28_INT_SSP1			97
+#define MX28_INT_SSP2			98
+#define MX28_INT_SSP3			99
+#define MX28_INT_ENET_SWI		100
+#define MX28_INT_ENET_MAC0		101
+#define MX28_INT_ENET_MAC1		102
+#define MX28_INT_ENET_MAC0_1588		103
+#define MX28_INT_ENET_MAC1_1588		104
+#define MX28_INT_RESV105		105
+#define MX28_INT_RESV106		106
+#define MX28_INT_RESV107		107
+#define MX28_INT_RESV108		108
+#define MX28_INT_RESV109		109
+#define MX28_INT_I2C1_ERROR		110
+#define MX28_INT_I2C0_ERROR		111
+#define MX28_INT_AUART0			112
+#define MX28_INT_AUART1			113
+#define MX28_INT_AUART2			114
+#define MX28_INT_AUART3			115
+#define MX28_INT_AUART4			116
+#define MX28_INT_RESV117		117
+#define MX28_INT_RESV118		118
+#define MX28_INT_RESV119		119
+#define MX28_INT_RESV120		120
+#define MX28_INT_RESV121		121
+#define MX28_INT_RESV122		122
+#define MX28_INT_GPIO4			123
+#define MX28_INT_GPIO3			124
+#define MX28_INT_GPIO2			125
+#define MX28_INT_GPIO1			126
+#define MX28_INT_GPIO0			127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..128c114
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#define MXS_SET_ADDR		0x4
+#define MXS_CLR_ADDR		0x8
+#define MXS_TOG_ADDR		0xc
+
+/*
+ * MXS CPU types
+ */
+#define MXS_CPU_MX23		23
+#define MXS_CPU_MX28		28
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxs_cpu_type;
+#endif
+
+#ifdef CONFIG_SOC_IMX23
+# ifdef mxs_cpu_type
+#  undef mxs_cpu_type
+#  define mxs_cpu_type __mxs_cpu_type
+# else
+#  define mxs_cpu_type MXS_CPU_MX23
+# endif
+# define cpu_is_mx23()		(mxs_cpu_type == MXS_CPU_MX23)
+#else
+# define cpu_is_mx23()		(0)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# ifdef mxs_cpu_type
+#  undef mxs_cpu_type
+#  define mxs_cpu_type __mxs_cpu_type
+# else
+#  define mxs_cpu_type MXS_CPU_MX28
+# endif
+# define cpu_is_mx28()		(mxs_cpu_type == MXS_CPU_MX28)
+#else
+# define cpu_is_mx28()		(0)
+#endif
+
+#endif /* __MACH_MXS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 02/15] ARM: mxs: Add helper definition and function
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
  2010-11-26  6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-26  6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
                   ` (44 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add helper definition and function for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/cpu.c                  |   11 ++++++++++
 arch/arm/mach-mxs/include/mach/common.h  |   33 ++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/io.h      |   22 ++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/timex.h   |   21 +++++++++++++++++++
 arch/arm/mach-mxs/include/mach/vmalloc.h |   22 ++++++++++++++++++++
 5 files changed, 109 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/cpu.c
 create mode 100644 arch/arm/mach-mxs/include/mach/common.h
 create mode 100644 arch/arm/mach-mxs/include/mach/io.h
 create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
 create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h

diff --git a/arch/arm/mach-mxs/cpu.c b/arch/arm/mach-mxs/cpu.c
new file mode 100644
index 0000000..764b0d5
--- /dev/null
+++ b/arch/arm/mach-mxs/cpu.c
@@ -0,0 +1,11 @@
+
+#include <linux/module.h>
+
+unsigned int __mxs_cpu_type;
+EXPORT_SYMBOL(__mxs_cpu_type);
+
+void mxs_set_cpu_type(unsigned int type)
+{
+	__mxs_cpu_type = type;
+}
+
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..2911057
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_arch_reset_init(void __iomem *);
+extern void mxs_set_cpu_type(unsigned int);
+extern void mxs_timer_init(struct clk *, void __iomem *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void __iomem *);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a)		__typesafe_io(a)
+
+#define __mem_pci(a)	(a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ * Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE		32000	/* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2000 Russell King.
+ *  Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END       0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
  2010-11-26  6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
  2010-11-26  6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-26  9:31   ` Lothar Waßmann
  2010-11-26  6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
                   ` (43 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

* The mxs wdog is implemented in RTC block.
* There is a generic software reset routine for most modules on mxs.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
 arch/arm/mach-mxs/system.c              |  152 +++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/system.h
 create mode 100644 arch/arm/mach-mxs/system.c

diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..de33c66
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG	0x50
+#define MXS_WATCHDOG_EN		(1 << 4)
+
+#define MXS_MODULE_CLKGATE	(1 << 30)
+#define MXS_MODULE_SFTRST	(1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+	struct clk *clk;
+
+	clk = clk_get_sys("rtc", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+
+	/* Set wdog count */
+	__raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
+
+	/* Assert SRS signal */
+	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+	/* Wait for reset to assert... */
+	mdelay(500);
+
+	pr_err("Watchdog reset failed to assert reset\n");
+
+	/* Delay to allow the serial port to show the message */
+	mdelay(50);
+
+	/* We'll take a jump through zero as a poor second */
+	cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+	wdog_base = base;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+	u32 val;
+	int timeout;
+
+	/*
+	 * The process of software reset of IP block is done
+	 * in several steps:
+	 *
+	 * 1) clear SFTRST and wait it cleared;
+	 * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
+	 * 3) clear SFTRST and wait it cleared;
+	 * 4) clear CLKGATE and wait it cleared.
+	 */
+
+	/* Clear SFTRST */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/*
+	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
+	 * recommends to wait 1us.
+	 */
+	udelay(1);
+	/* Poll SFTRST cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear CLKGATE */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_CLKGATE;
+	__raw_writel(val, reset_addr);
+	/* Set SFTRST to reset the block */
+	val = __raw_readl(reset_addr);
+	val |= MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll CLKGATE set */
+	timeout = 0x400;
+	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear SFTRST */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll SFTRST cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear CLKGATE */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_CLKGATE;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll CLKGATE cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	return 0;
+
+error:
+	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+	return -ETIMEDOUT;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 04/15] ARM: mxs: Add interrupt support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (2 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 13:56   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
                   ` (42 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add Interrupt Collector (ICOLL) support for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/icoll.c                    |   77 ++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/entry-macro.S |   36 ++++++++++++
 2 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/icoll.c
 create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S

diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..a7a7d4f
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR				0x0000
+#define HW_ICOLL_LEVELACK			0x0010
+#define HW_ICOLL_CTRL				0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
+
+void __iomem *icoll_base;
+
+static void icoll_ack_irq(unsigned int irq)
+{
+	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
+
+	/* ACK current interrupt (level 0) */
+	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+			icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+	.ack = icoll_ack_irq,
+	.mask = icoll_mask_irq,
+	.unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void __iomem *irqbase)
+{
+	int i;
+
+	icoll_base = irqbase;
+
+	/* Reset icoll */
+	mxs_reset_block(irqbase + HW_ICOLL_CTRL);
+
+	for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxs_icoll_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..597948d
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,36 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\base, =icoll_base
+	ldr	\base, [\base]
+	ldr	\irqnr, [\base, #0x70]
+	cmp	\irqnr, #0x7F
+	moveqs	\irqnr, #0
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 05/15] ARM: mxs: Add low-level debug UART support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (3 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 15:48   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
                   ` (41 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

* DEBUG_LL support, which is incompatible with single MXS image
  because of different DUART base address on MX23 and MX28
* uncompress message support

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/debug-macro.S |   51 ++++++++++++++++
 arch/arm/mach-mxs/include/mach/uncompress.h  |   82 ++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h

diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..efb3173
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,51 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/hardware.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR)
+
+		.macro	addruart, rp, rv
+		ldr	\rp, =UART_PADDR	@ physical
+		ldr	\rv, =UART_VADDR	@ virtual
+		.endm
+
+		.macro	senduart, rd, rx
+		str	\rd, [\rx, #0x0]	@ DR
+		.endm
+
+		.macro	waituart, rd, rx
+1001:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 5		@ FR_TXFF
+		bne	1001b
+		.endm
+
+		.macro	busyuart, rd, rx
+1002:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 3		@ FR_BUSY
+		beq	1002b
+		.endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..47e5479
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,82 @@
+/*
+ *  arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) Shane Nay (shane@minirl.com)
+ *  Copyright 2010 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#define __MXS_BOOT_UNCOMPRESS
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define DR		0x00
+#define FR		0x18
+#define FR_BUSY		(1 << 3)
+#define FR_TXFE		(1 << 7)
+#define CR		0x30
+#define CR_UARTEN	1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.  We search for the first enabled
+ * port in the most probable order.  If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+static void putc(int ch)
+{
+	if (!uart_base)
+		return;
+	if (!(UART(CR) & CR_UARTEN))
+		return;
+
+	while (!(UART(FR) & FR_TXFE))
+		barrier();
+
+	UART(DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR	0x80070000
+#define MX28_DUART_BASE_ADDR	0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+	switch (arch_id) {
+	case MACH_TYPE_MX23EVK:
+		uart_base = MX23_DUART_BASE_ADDR;
+		break;
+	case MACH_TYPE_MX28EVK:
+		uart_base = MX28_DUART_BASE_ADDR;
+		break;
+	default:
+		break;
+	}
+}
+
+#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 06/15] ARM: mxs: Add timer support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (4 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 16:13   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
                   ` (40 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.

As the result, we need two instances of timers with v1 for better
implementation, one for next_event and another for get_cycles.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/timer.c |  285 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 285 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/timer.c

diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..c52b465
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,285 @@
+/*
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for next_event and another for get_cycles. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1()	(cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL			0x00
+#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n)		(0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE		(1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT		0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL	(timrot_is_v1() ? 0x8 : 0xb)
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+	if (timrot_is_v1())
+		return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+				& 0xffff0000) >> 16);
+	else
+		return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrot_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	unsigned long match;
+	int ret;
+
+	/* timrot decrements the count */
+	if (timrot_is_v1()) {
+		__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+		ret = 0;
+	} else {
+		match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNTn(0))
+				- evt;
+		__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+		ret = (int)(match - __raw_readl(timer_base +
+				HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+	}
+
+	return ret;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_mxs;
+
+	timrot_irq_acknowledge();
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+	.name		= "MXS Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call mxs_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in timer module */
+	timrot_irq_disable();
+
+	if (mode != clockevent_mode) {
+		/* Set event time into far-far future */
+		__raw_writel(__raw_readl(timer_base +
+				HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+				timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+		/* Clear pending interrupt */
+		timrot_irq_acknowledge();
+	}
+
+#ifdef DEBUG
+	printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+		clock_event_mode_label[clockevent_mode],
+		clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+	/* Remember timer mode */
+	clockevent_mode = mode;
+	local_irq_restore(flags);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+				"supported for MXS-based\n");
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * mxs_set_next_event(), the core has about 4 minutes
+	 * to call mxs_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+		local_irq_save(flags);
+		timrot_irq_enable();
+		local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_mxs = {
+	.name		= "mxs_timrot",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_mode	= mxs_set_mode,
+	.set_next_event	= timrot_set_next_event,
+	.rating		= 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+	clockevent_mxs.cpumask = cpumask_of(0);
+	if (timrot_is_v1()) {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xf, &clockevent_mxs);
+	} else {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xff, &clockevent_mxs);
+	}
+
+	clockevents_register_device(&clockevent_mxs);
+
+	return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+	.name 		= "mxs_timer",
+	.rating		= 200,
+	.read		= timrot_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift 		= 10,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	if (timrot_is_v1())
+		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+	clocksource_register(&clocksource_mxs);
+
+	return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+				void __iomem *base, int irq)
+{
+	clk_enable(timer_clk);
+
+	timer_base = base;
+
+	/*
+	 * Initialize timers to a known state
+	 */
+	mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+	if (timrot_is_v1()) {
+		/* timer0 is for next_event */
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_UPDATE |
+			BM_TIMROT_TIMCTRLn_IRQ_EN,
+			base + HW_TIMROT_TIMCTRLn(0));
+		/* timer1 is for get_cycles */
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_RELOAD,
+			base + HW_TIMROT_TIMCTRLn(1));
+		__raw_writel(0xffff, timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
+
+	} else {
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_IRQ_EN |
+			BM_TIMROT_TIMCTRLn_MATCH_MODE,
+			timer_base + HW_TIMROT_TIMCTRLn(0));
+	}
+
+	/* init and register the timer to the framework */
+	mxs_clocksource_init(timer_clk);
+	mxs_clockevent_init(timer_clk);
+
+	/* Make irqs happen */
+	setup_irq(irq, &mxs_timer_irq);
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 07/15] ARM: mxs: Add gpio support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (5 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 16:21   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
                   ` (39 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implement gpio support in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/gpio.c              |  364 +++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/gpio.h |   49 +++++
 2 files changed, 413 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/gpio.c
 create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h

diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..7e3674b
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,364 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n)		((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n)		((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n)		((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n)	((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n)	((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n)	((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n)	((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n)	((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE	0x0
+#define GPIO_INT_LOW_LEV	0x1
+#define GPIO_INT_RISE_EDGE	0x2
+#define GPIO_INT_HIGH_LEV	0x3
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+	__raw_writel(1 << index,
+			port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+				int enable)
+{
+	if (enable == 0) {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+	} else {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+	}
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+	u32 gpio = irq_to_gpio(irq);
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+	u32 val;
+	int edge;
+
+	port->both_edges &= ~(1 << (gpio & 31));
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		edge = GPIO_INT_RISE_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		edge = GPIO_INT_FALL_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		val = mxs_gpio_get(&port->chip, gpio & 31);
+		if (val) {
+			edge = GPIO_INT_LOW_LEV;
+			pr_debug("mxs: set GPIO %d to low trigger\n", gpio);
+		} else {
+			edge = GPIO_INT_HIGH_LEV;
+			pr_debug("mxs: set GPIO %d to high trigger\n", gpio);
+		}
+		port->both_edges |= 1 << (gpio & 31);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		edge = GPIO_INT_LOW_LEV;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		edge = GPIO_INT_HIGH_LEV;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set level or edge */
+	if (edge & 0x1)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+	/* set polarity */
+	if ((edge >> 1) & 0x1)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+	_clear_gpio_irqstatus(port, gpio & 0x1f);
+
+	return 0;
+}
+
+static void mxs_flip_edge(struct mxs_gpio_port *port, u32 gpio)
+{
+	u32 val;
+	int edge;
+
+	edge = 1 << (gpio & 31);
+	val = __raw_readl(port->base + PINCTRL_IRQLEV(port->id));
+	if (val & edge) {
+		/* level is invalid for this function */
+		pr_err("mxs: invalid configuration for GPIO %d: %x\n",
+			gpio, edge);
+		return;
+	}
+	__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_TOG_ADDR);
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_stat;
+	struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+	u32 gpio_irq_no_base = port->virtual_irq_start;
+
+	irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+			__raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+			__raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
+
+		if (port->both_edges & (1 << irqoffset))
+			mxs_flip_edge(port, irqoffset);
+
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+		irq_stat &= ~(1 << irqoffset);
+	}
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+	u32 gpio = irq_to_gpio(irq);
+	u32 gpio_idx = gpio & 0x1f;
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+	if (enable) {
+		if (port->irq_high && (gpio_idx >= 16))
+			enable_irq_wake(port->irq_high);
+		else
+			enable_irq_wake(port->irq);
+	} else {
+		if (port->irq_high && (gpio_idx >= 16))
+			disable_irq_wake(port->irq_high);
+		else
+			disable_irq_wake(port->irq);
+	}
+
+	return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.ack = gpio_ack_irq,
+	.mask = gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+	.set_type = gpio_set_irq_type,
+	.set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+				int dir)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	u32 l;
+	unsigned long flags;
+	void __iomem *reg = port->base + PINCTRL_DOE(port->id);
+
+	spin_lock_irqsave(&port->lock, flags);
+	l = __raw_readl(reg);
+	if (dir)
+		l |= 1 << offset;
+	else
+		l &= ~(1 << offset);
+	__raw_writel(l, reg);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	u32 l;
+	unsigned long flags;
+	void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
+
+	spin_lock_irqsave(&port->lock, flags);
+	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
+	__raw_writel(l, reg);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	void __iomem *reg = port->base + PINCTRL_DIN(port->id);
+
+	return (__raw_readl(reg) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	_set_gpio_direction(chip, offset, 0);
+	return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	mxs_gpio_set(chip, offset, value);
+	_set_gpio_direction(chip, offset, 1);
+	return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+	int i, j;
+
+	/* save for local usage */
+	mxs_gpio_ports = port;
+	gpio_table_size = cnt;
+
+	printk(KERN_INFO "MXS GPIO hardware\n");
+
+	for (i = 0; i < cnt; i++) {
+		/* disable the interrupt and clear the status */
+		__raw_writel(0, port[i].base +
+				PINCTRL_PIN2IRQ(i));
+		__raw_writel(0, port[i].base +
+				PINCTRL_IRQEN(i));
+		__raw_writel(~0, port[i].base +
+				PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+		for (j = port[i].virtual_irq_start;
+			j < port[i].virtual_irq_start + 32; j++) {
+			set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, handle_level_irq);
+			set_irq_flags(j, IRQF_VALID);
+		}
+
+		/* register gpio chip */
+		port[i].chip.direction_input = mxs_gpio_direction_input;
+		port[i].chip.direction_output = mxs_gpio_direction_output;
+		port[i].chip.get = mxs_gpio_get;
+		port[i].chip.set = mxs_gpio_set;
+		port[i].chip.base = i * 32;
+		port[i].chip.ngpio = 32;
+
+		spin_lock_init(&port[i].lock);
+
+		/* its a serious configuration bug when it fails */
+		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+		/* setup one handler for each entry */
+		set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+		set_irq_data(port[i].irq, &port[i]);
+	}
+
+	return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id)					\
+	{								\
+		.chip.label = "gpio-" #_id,				\
+		.id = _id,						\
+		.irq = soc ## _INT_GPIO ## _id,				\
+		.base = soc ## _IO_ADDRESS(				\
+				soc ## _PINCTRL ## _BASE_ADDR),		\
+		.virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,	\
+	}
+
+#define DEFINE_REGISTER_FUNCTION(prefix)				\
+int __init prefix ## _register_gpios(void)				\
+{									\
+	return mxs_gpio_init(prefix ## _gpio_ports,			\
+			ARRAY_SIZE(prefix ## _gpio_ports));		\
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX23, 0),
+	DEFINE_MXS_GPIO_PORT(MX23, 1),
+	DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX28, 0),
+	DEFINE_MXS_GPIO_PORT(MX28, 1),
+	DEFINE_MXS_GPIO_PORT(MX28, 2),
+	DEFINE_MXS_GPIO_PORT(MX28, 3),
+	DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..7692de6
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr)		((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value		__gpio_get_value
+#define gpio_set_value		__gpio_set_value
+#define gpio_cansleep		__gpio_cansleep
+
+#define gpio_to_irq(gpio)	(MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq)	((irq) - MXS_GPIO_IRQ_START)
+
+struct mxs_gpio_port {
+	void __iomem *base;
+	int id;
+	int irq;
+	int irq_high;
+	int virtual_irq_start;
+	struct gpio_chip chip;
+	u32 both_edges;
+	spinlock_t lock;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MACH_MXS_GPIO_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 08/15] ARM: mxs: Add iomux support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (6 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 16:32   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
                   ` (38 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implements iomux functions in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/include/mach/iomux-mx23.h |   29 +++++++
 arch/arm/mach-mxs/include/mach/iomux-mx28.h |   44 +++++++++++
 arch/arm/mach-mxs/include/mach/iomux.h      |   77 +++++++++++++++++++
 arch/arm/mach-mxs/iomux.c                   |  110 +++++++++++++++++++++++++++
 4 files changed, 260 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
 create mode 100644 arch/arm/mach-mxs/iomux.c

diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX			IOMUX_PAD(1, 26, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX			IOMUX_PAD(1, 27, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..ca37a15
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..27bcada
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *			<armlinux@phytec.de>
+ * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+typedef struct pad_desc {
+	unsigned bank:3;
+	unsigned pin:5;
+	unsigned muxsel:2;
+	unsigned ma:3;
+	unsigned vol:2;
+	unsigned pull:1;
+} iomux_cfg_t;
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)	\
+		{						\
+			.bank	= _bank,			\
+			.pin	= _pin,				\
+			.muxsel	= _muxsel,			\
+			.vol	= _vol,				\
+			.ma	= _ma,				\
+			.pull	= _pull,			\
+		}
+
+#define PAD_MUXSEL_0		0
+#define PAD_MUXSEL_1		1
+#define PAD_MUXSEL_2		2
+#define PAD_MUXSEL_GPIO		3
+
+#define PAD_1V8			0
+#define PAD_3V3			1
+#define PAD_VOL_NONE		2
+
+#define PAD_4MA			0
+#define PAD_8MA			1
+#define PAD_12MA		2
+#define PAD_16MA		3
+#define PAD_MA_NONE		4
+
+#define PAD_NOPULL		0
+#define PAD_PULL		1
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t *pad);
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxs_iomux_init(void __iomem *iomux_base);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..803cadf
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *                       <armlinux@phytec.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/iomux.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t *pad)
+{
+	u32 reg, ofs, bp, bm;
+
+	/* muxsel */
+	ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
+	bp = pad->pin % 16 * 2;
+	bm = 0x3 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->muxsel << bp;
+	__raw_writel(reg, base + ofs);
+
+	/* drive */
+	ofs = cpu_is_mx23() ? 0x200 : 0x300;
+	ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
+	/* ma */
+	if (pad->ma != PAD_MA_NONE)
+	{
+		bp = pad->pin % 8 * 4;
+		bm = 0x3 << bp;
+		reg = __raw_readl(base + ofs);
+		reg &= ~bm;
+		reg |= pad->ma << bp;
+		__raw_writel(reg, base + ofs);
+	}
+	/* vol */
+	if (pad->vol != PAD_VOL_NONE)
+	{
+		bp = pad->pin % 8 * 4 + 2;
+		bm = 0x1 << bp;
+		reg = __raw_readl(base + ofs);
+		reg &= ~bm;
+		reg |= pad->vol << bp;
+		__raw_writel(reg, base + ofs);
+	}
+
+	/* pull */
+	ofs = cpu_is_mx23() ? 0x400 : 0x600;
+	ofs += pad->bank * 0x10;
+	bp = pad->pin;
+	bm = 0x1 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->pull << bp;
+	__raw_writel(reg, base + ofs);
+
+	return 0;
+}
+EXPORT_SYMBOL(mxs_iomux_setup_pad);
+
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+{
+	iomux_cfg_t *p = pad_list;
+	int i;
+	int ret;
+
+	for (i = 0; i < count; i++) {
+		ret = mxs_iomux_setup_pad(p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
+
+void mxs_iomux_init(void __iomem *iomux_base)
+{
+	base = iomux_base;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (7 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 16:39   ` Uwe Kleine-König
  2010-12-02 15:07   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
                   ` (37 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add clock for MXS-based SoCs, MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/clock-mx23.c          |  521 ++++++++++++++++++++++
 arch/arm/mach-mxs/clock-mx28.c          |  732 +++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/clock.c               |  201 +++++++++
 arch/arm/mach-mxs/include/mach/clkdev.h |    7 +
 arch/arm/mach-mxs/include/mach/clock.h  |   64 +++
 arch/arm/mach-mxs/regs-clkctrl-mx23.h   |  455 +++++++++++++++++++
 arch/arm/mach-mxs/regs-clkctrl-mx28.h   |  663 ++++++++++++++++++++++++++++
 7 files changed, 2643 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/clock-mx23.c
 create mode 100644 arch/arm/mach-mxs/clock-mx28.c
 create mode 100644 arch/arm/mach-mxs/clock.c
 create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..832db0b
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+	/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+	 * and is incorrect (excessive). Per definition of the PLLCTRL0
+	 * POWER field, waiting at least 10us.
+	 */
+	udelay(10);
+
+	return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+	 .get_rate = pll_clk_get_rate,
+	 .enable = pll_clk_enable,
+	 .disable = pll_clk_disable,
+	 .parent = &ref_xtal_clk,
+};
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return parent_rate * 18 / div;					\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, bm_busy, div_max, d, f, div, frac;
+	unsigned long diff, parent_rate, calc_rate;
+	int i;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &ref_xtal_clk) {
+		div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+		div = DIV_ROUND_UP(parent_rate, rate);
+		if (div == 0 || div > div_max)
+			return -EINVAL;
+	} else {
+		div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+		div = frac = 1;
+		diff = parent_rate;
+		for (d = 1; d <= div_max; d++) {
+			f = parent_rate * 18 / d / rate;
+			if ((parent_rate * 18 / d) % rate)
+				f++;
+			if (f < 18 || f > 35)
+				continue;
+
+			calc_rate = parent_rate * 18 / f / d;
+			if (calc_rate > rate)
+				continue;
+
+			if (rate - calc_rate < diff) {
+				frac = f;
+				div = d;
+				diff = rate - calc_rate;
+			}
+
+			if (diff == 0)
+				break;
+		}
+
+		if (diff == parent_rate)
+			return -EINVAL;
+
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+		reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+		reg |= frac;
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	}
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+	reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+	reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+					HW_CLKCTRL_CPU) & bm_busy))
+			break;
+	if (!i)	{
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+#define _CLK_SET_RATE(name, dr)						\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "usb", usb_clk)
+	_REGISTER_CLOCK(NULL, "audio", audio_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+			&ref_xtal_clk : &ref_io_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_io_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+			&ref_xtal_clk : &ref_pix_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+	reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+	reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX23_IO_ADDRESS(MX23_TIMROT_BASE_ADDR),
+			MX23_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..2cb24c5
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,732 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+	return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g)					\
+static int name##_enable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	udelay(10);							\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+									\
+	return 0;							\
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g)					\
+static void name##_disable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name)						\
+	static struct clk name = {					\
+		.get_rate	= name##_get_rate,			\
+		.enable		= name##_enable,			\
+		.disable	= name##_disable,			\
+		.parent		= &ref_xtal_clk,			\
+	}
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return parent_rate * 18 / div;					\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll0_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	if (clk == &saif0_clk || clk == &saif1_clk)			\
+		return (clk_get_rate(clk->parent) >> 16 * div);		\
+	else								\
+		return clk_get_rate(clk->parent) / div;			\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+_CLK_GET_RATE1(fec_clk, ENET)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV	0
+#define BP_CLKCTRL_CPU_DIV	0
+#define BM_CLKCTRL_CPU_BUSY	0
+
+#define _CLK_SET_RATE(name, dr, fr, fs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, bm_busy, div_max, d, f, div, frac;			\
+	unsigned long diff, parent_rate, calc_rate;			\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+	bm_busy = BM_CLKCTRL_##dr##_BUSY;				\
+									\
+	if (clk->parent == &ref_xtal_clk) {				\
+		div = DIV_ROUND_UP(parent_rate, rate);			\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_XTAL >>		\
+				BP_CLKCTRL_CPU_DIV_XTAL;		\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;		\
+		}							\
+		if (div == 0 || div > div_max)				\
+			return -EINVAL;					\
+	} else {							\
+		div = frac = 1;						\
+		diff = parent_rate;					\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_CPU >>		\
+				BP_CLKCTRL_CPU_DIV_CPU;			\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;		\
+		}							\
+		for (d = 1; d <= div_max; d++) {			\
+			f = parent_rate * 18 / d / rate;		\
+			if ((parent_rate * 18 / d) % rate)		\
+				f++;					\
+			if (f < 18 || f > 35)				\
+				continue;				\
+									\
+			calc_rate = parent_rate * 18 / f / d;		\
+			if (calc_rate > rate)				\
+				continue;				\
+									\
+			if (rate - calc_rate < diff) {			\
+				frac = f;				\
+				div = d;				\
+				diff = rate - calc_rate;		\
+			}						\
+									\
+			if (diff == 0)					\
+				break;					\
+		}							\
+									\
+		if (diff == parent_rate)				\
+			return -EINVAL;					\
+									\
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+		reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC;			\
+		reg |= frac;						\
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+	}								\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	if (clk == &cpu_clk) {						\
+		reg &= ~BM_CLKCTRL_CPU_DIV_CPU;				\
+		reg |= div << BP_CLKCTRL_CPU_DIV_CPU;			\
+	} else {							\
+		reg &= ~BM_CLKCTRL_##dr##_DIV;				\
+		reg |= div << BP_CLKCTRL_##dr##_DIV;			\
+		if (reg | (1 << clk->enable_shift)) {			\
+			pr_err("%s: clock is gated\n", __func__);	\
+			return -EINVAL;					\
+		}							\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & bm_busy))			\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+_CLK_SET_RATE1(fec_clk, ENET)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u16 div;							\
+	u32 reg;							\
+	u64 lrate;							\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	if (rate > parent_rate)						\
+		return -EINVAL;						\
+									\
+	lrate = (u64)rate << 16;					\
+	do_div(lrate, parent_rate);					\
+	div = (u16)lrate;						\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	reg &= ~BM_CLKCTRL_##rs##_DIV;					\
+	reg |= div << BP_CLKCTRL_##rs##_DIV;				\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))	\
+			break;						\
+	if (!i) {							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+	.get_rate = lradc_clk_get_rate,
+	.parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 16,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+/* fec 1588 clock */
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &pll0_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "can0", can0_clk)
+	_REGISTER_CLOCK(NULL, "can1", can1_clk)
+	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+	_REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+			&ref_xtal_clk : &ref_pix_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_gpmi_clk;
+	saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+			&ref_xtal_clk : &pll0_clk;
+	saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+			&ref_xtal_clk : &pll0_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+	reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+	reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+	reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+	reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+	reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+	/* SAIF has to use frac div for functional operation */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+	reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+	reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	/* Extra fec clock setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg &= ~BM_CLKCTRL_ENET_SLEEP;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+			MX28_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e262759
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,201 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+	WARN_ON(!clk->usecount);
+
+	if (!(--clk->usecount)) {
+		if (clk->disable)
+			clk->disable(clk);
+		__clk_disable(clk->parent);
+		__clk_disable(clk->secondary);
+	}
+}
+
+static int __clk_enable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	if (clk->usecount++ == 0) {
+		__clk_enable(clk->parent);
+		__clk_enable(clk->secondary);
+
+		if (clk->enable)
+			clk->enable(clk);
+	}
+	return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	ret = __clk_enable(clk);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
+	mutex_lock(&clocks_mutex);
+	__clk_disable(clk);
+	mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return 0UL;
+
+	if (clk->get_rate)
+		return clk->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+		return 0;
+
+	return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+		return ret;
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_rate(clk, rate);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -EINVAL;
+	struct clk *old;
+
+	if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+	    IS_ERR(parent) || clk->set_parent == NULL)
+		return ret;
+
+	if (clk->usecount)
+		clk_enable(parent);
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_parent(clk, parent);
+	if (ret == 0) {
+		old = clk->parent;
+		clk->parent = parent;
+	} else {
+		old = parent;
+	}
+	mutex_unlock(&clocks_mutex);
+
+	if (clk->usecount)
+		clk_disable(old);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+	struct clk *ret = NULL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+	int id;
+	/* Source clock this clk depends on */
+	struct clk *parent;
+	/* Secondary clock to enable/disable with this clock */
+	struct clk *secondary;
+	/* Reference count of clock enable/disable */
+	__s8 usecount;
+	/* Register bit position for clock's enable/disable control. */
+	u8 enable_shift;
+	/* Register address for clock's enable/disable control. */
+	void __iomem *enable_reg;
+	u32 flags;
+	/* get the current clock rate (always a fresh value) */
+	unsigned long (*get_rate) (struct clk *);
+	/* Function ptr to set the clock to a new rate. The rate must match a
+	   supported rate returned from round_rate. Leave blank if clock is not
+	   programmable */
+	int (*set_rate) (struct clk *, unsigned long);
+	/* Function ptr to round the requested clock rate to the nearest
+	   supported rate that is less than or equal to the requested rate. */
+	unsigned long (*round_rate) (struct clk *, unsigned long);
+	/* Function ptr to enable the clock. Leave blank if clock can not
+	   be gated. */
+	int (*enable) (struct clk *);
+	/* Function ptr to disable the clock. Leave blank if clock can not
+	   be gated. */
+	void (*disable) (struct clk *);
+	/* Function ptr to set the parent clock of the clock. */
+	int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0	(0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2	0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER	0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU	(0x00000020)
+#define HW_CLKCTRL_CPU_SET	(0x00000024)
+#define HW_CLKCTRL_CPU_CLR	(0x00000028)
+#define HW_CLKCTRL_CPU_TOG	(0x0000002c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000030)
+#define HW_CLKCTRL_HBUS_SET	(0x00000034)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000038)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4	30
+#define BM_CLKCTRL_HBUS_RSRVD4	0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+		(((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY	0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE	0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	11
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000050)
+#define HW_CLKCTRL_XTAL_SET	(0x00000054)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000058)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE	30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE	0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE	0x08000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_PIX	(0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE	31
+#define BM_CLKCTRL_PIX_CLKGATE	0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2	0x40000000
+#define BM_CLKCTRL_PIX_BUSY	0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1	13
+#define BM_CLKCTRL_PIX_RSRVD1	0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v)  \
+		(((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN	0x00001000
+#define BP_CLKCTRL_PIX_DIV	0
+#define BM_CLKCTRL_PIX_DIV	0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP	(0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE	31
+#define BM_CLKCTRL_SSP_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP_BUSY	0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1	10
+#define BM_CLKCTRL_SSP_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP_DIV	0
+#define BM_CLKCTRL_SSP_DIV	0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x00000080)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x00000090)
+
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000a0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_IR	(0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE	0x80000000
+#define BM_CLKCTRL_IR_RSRVD3	0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV	0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY	0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY	0x08000000
+#define BP_CLKCTRL_IR_RSRVD2	25
+#define BM_CLKCTRL_IR_RSRVD2	0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v)  \
+		(((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV	16
+#define BM_CLKCTRL_IR_IROV_DIV	0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1	10
+#define BM_CLKCTRL_IR_RSRVD1	0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV	0
+#define BM_CLKCTRL_IR_IR_DIV	0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF	(0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1	17
+#define BM_CLKCTRL_SAIF_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF_DIV	0
+#define BM_CLKCTRL_SAIF_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV	(0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE	0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE	0x40000000
+#define BP_CLKCTRL_TV_RSRVD	0
+#define BM_CLKCTRL_TV_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM	(0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	7
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000040
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC	(0x000000f0)
+#define HW_CLKCTRL_FRAC_SET	(0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR	(0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG	(0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO	31
+#define BM_CLKCTRL_FRAC_CLKGATEIO	0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC	24
+#define BM_CLKCTRL_FRAC_IOFRAC	0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX	23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX	0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC	16
+#define BM_CLKCTRL_FRAC_PIXFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC	8
+#define BM_CLKCTRL_FRAC_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC	0
+#define BM_CLKCTRL_FRAC_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x00000100)
+#define HW_CLKCTRL_FRAC1_SET	(0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR	(0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG	(0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID	0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1	0
+#define BM_CLKCTRL_FRAC1_RSRVD1	0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ	(0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR	0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD	2
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x00000130)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000140)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2009-2010 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_H__
+
+#define HW_CLKCTRL_PLL0CTRL0	(0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0	(0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET	(0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR	(0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG	(0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI	0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6	0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1	(0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0	(0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET	(0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR	(0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG	(0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE	0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3	0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2	0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B	0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER	0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1	0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU	(0x00000050)
+#define HW_CLKCTRL_CPU_SET	(0x00000054)
+#define HW_CLKCTRL_CPU_CLR	(0x00000058)
+#define HW_CLKCTRL_CPU_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000060)
+#define HW_CLKCTRL_HBUS_SET	(0x00000064)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000068)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY	0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE	0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	12
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE	0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000080)
+#define HW_CLKCTRL_XTAL_SET	(0x00000084)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000088)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2	27
+#define BM_CLKCTRL_XTAL_RSRVD2	0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v)  \
+		(((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0	(0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE	31
+#define BM_CLKCTRL_SSP0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP0_BUSY	0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1	10
+#define BM_CLKCTRL_SSP0_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP0_DIV	0
+#define BM_CLKCTRL_SSP0_DIV	0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1	(0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE	31
+#define BM_CLKCTRL_SSP1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP1_BUSY	0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1	10
+#define BM_CLKCTRL_SSP1_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP1_DIV	0
+#define BM_CLKCTRL_SSP1_DIV	0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2	(0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE	31
+#define BM_CLKCTRL_SSP2_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP2_BUSY	0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1	10
+#define BM_CLKCTRL_SSP2_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP2_DIV	0
+#define BM_CLKCTRL_SSP2_DIV	0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3	(0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE	31
+#define BM_CLKCTRL_SSP3_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP3_BUSY	0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1	10
+#define BM_CLKCTRL_SSP3_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP3_DIV	0
+#define BM_CLKCTRL_SSP3_DIV	0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE	31
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0	(0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE	31
+#define BM_CLKCTRL_SAIF0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1	17
+#define BM_CLKCTRL_SAIF0_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF0_DIV	0
+#define BM_CLKCTRL_SAIF0_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1	(0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE	31
+#define BM_CLKCTRL_SAIF1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1	17
+#define BM_CLKCTRL_SAIF1_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF1_DIV	0
+#define BM_CLKCTRL_SAIF1_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF	(0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE	31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY	0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1	14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1	0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v)  \
+		(((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN	0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV	0
+#define BM_CLKCTRL_DIS_LCDIF_DIV	0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM	(0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	8
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000080
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET	(0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP	0x80000000
+#define BP_CLKCTRL_ENET_DISABLE	30
+#define BM_CLKCTRL_ENET_DISABLE	0x40000000
+#define BM_CLKCTRL_ENET_STATUS	0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1	0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME	0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME	21
+#define BM_CLKCTRL_ENET_DIV_TIME	0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY	0x08000000
+#define BP_CLKCTRL_ENET_DIV	21
+#define BM_CLKCTRL_ENET_DIV	0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL	19
+#define BM_CLKCTRL_ENET_TIME_SEL	0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v)  \
+		(((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL      0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL       0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK  0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN	0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP	0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW	0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0	0
+#define BM_CLKCTRL_ENET_RSRVD0	0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v)  \
+		(((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC	(0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2	0x80000000
+#define BM_CLKCTRL_HSADC_RESETB	0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV	28
+#define BM_CLKCTRL_HSADC_FREQDIV	0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v)  \
+		(((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1	0
+#define BM_CLKCTRL_HSADC_RSRVD1	0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN	(0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2	0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0	30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0	0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS	0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1	28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1	0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS	0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1	0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1	0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0	(0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET	(0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR	(0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG	(0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0	31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0	0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC	24
+#define BM_CLKCTRL_FRAC0_IO0FRAC	0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1	23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1	0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC	16
+#define BM_CLKCTRL_FRAC0_IO1FRAC	0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC	8
+#define BM_CLKCTRL_FRAC0_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC	0
+#define BM_CLKCTRL_FRAC0_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET	(0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR	(0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG	(0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2	24
+#define BM_CLKCTRL_FRAC1_RSRVD2	0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+		(((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI	23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI	0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC	16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC	15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC	0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC	8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX	7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX	0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC	0
+#define BM_CLKCTRL_FRAC1_PIXFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ	(0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0	19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+		(((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v)  \
+		(((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF	0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD    0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2	0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v)  \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0	0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD	6
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE	0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE	0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE	0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT	0x00000004
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX28_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 10/15] ARM: mxs: Add static memory mapping
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (8 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-26  6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
                   ` (36 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Create static memory mapping for MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mm-mx23.c |   48 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/mm-mx28.c |   48 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mm-mx23.c
 create mode 100644 arch/arm/mach-mxs/mm-mx28.c

diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..da6776c
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+	mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX23, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx23_map_io(void)
+{
+	mxs_set_cpu_type(MXS_CPU_MX23);
+	mxs_iomux_init(MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR));
+	mxs_arch_reset_init(MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR));
+	iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+	icoll_init_irq(MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR));
+	mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..c0531e7
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+	mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX28, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx28_map_io(void)
+{
+	mxs_set_cpu_type(MXS_CPU_MX28);
+	mxs_iomux_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+	mxs_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+	iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+	icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+	mx28_register_gpios();
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (9 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-26  6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
                   ` (35 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Dynamically allocate duart devices for MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/devices-mx23.h                |   16 +++++
 arch/arm/mach-mxs/devices-mx28.h                |   16 +++++
 arch/arm/mach-mxs/devices.c                     |   75 +++++++++++++++++++++++
 arch/arm/mach-mxs/devices/platform-duart.c      |   47 ++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   34 ++++++++++
 5 files changed, 188 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices-mx23.h
 create mode 100644 arch/arm/mach-mxs/devices-mx28.h
 create mode 100644 arch/arm/mach-mxs/devices.c
 create mode 100644 arch/arm/mach-mxs/devices/platform-duart.c
 create mode 100644 arch/arm/mach-mxs/include/mach/devices-common.h

diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 0000000..d0f49fc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx23_duart_data __initconst;
+#define mx23_add_duart() \
+	mxs_add_duart(&mx23_duart_data)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 0000000..47c2f04
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx28_duart_data __initconst;
+#define mx28_add_duart() \
+	mxs_add_duart(&mx28_duart_data)
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 0000000..6b60f02
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data, u64 dmamask)
+{
+	int ret = -ENOMEM;
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc(name, id);
+	if (!pdev)
+		goto err;
+
+	if (dmamask) {
+		/*
+		 * This memory isn't freed when the device is put,
+		 * I don't have a nice idea for that though.  Conceptually
+		 * dma_mask in struct device should not be a pointer.
+		 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+		 */
+		pdev->dev.dma_mask =
+			kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+		if (!pdev->dev.dma_mask)
+			/* ret is still -ENOMEM; */
+			goto err;
+
+		*pdev->dev.dma_mask = dmamask;
+		pdev->dev.coherent_dma_mask = dmamask;
+	}
+
+	if (res) {
+		ret = platform_device_add_resources(pdev, res, num_resources);
+		if (ret)
+			goto err;
+	}
+
+	if (data) {
+		ret = platform_device_add_data(pdev, data, size_data);
+		if (ret)
+			goto err;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+err:
+		platform_device_put(pdev);
+		return ERR_PTR(ret);
+	}
+
+	return pdev;
+}
diff --git a/arch/arm/mach-mxs/devices/platform-duart.c b/arch/arm/mach-mxs/devices/platform-duart.c
new file mode 100644
index 0000000..7760caf
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-duart.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define mxs_duart_data_entry(soc)					\
+	{								\
+		.iobase = soc ## _DUART_BASE_ADDR,			\
+		.irq = soc ## _INT_DUART,				\
+	}
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_duart_data mx23_duart_data __initconst =
+	mxs_duart_data_entry(MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_duart_data mx28_duart_data __initconst =
+	mxs_duart_data_entry(MX28);
+#endif
+
+struct platform_device *__init mxs_add_duart(
+		const struct mxs_duart_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_8K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("mxs-duart", 0, res, ARRAY_SIZE(res),
+					NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 0000000..07b4439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data)
+{
+	return mxs_add_platform_device_dmamask(
+			name, id, res, num_resources, data, size_data, 0);
+}
+
+/* duart */
+struct mxs_duart_data {
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_duart(
+		const struct mxs_duart_data *data);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (10 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 20:01   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
                   ` (34 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Dynamically allocate fec devices for MX28, which gets dual
fec interface.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/devices-mx28.h                |    6 +++
 arch/arm/mach-mxs/devices/platform-fec.c        |   51 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   12 +++++
 3 files changed, 69 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c

diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..c509e5d 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,9 @@
 extern const struct mxs_duart_data mx28_duart_data __initconst;
 #define mx28_add_duart() \
 	mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+	mxs_add_fec(&mx28_fec_data[id], pdata)
+#define mx28_add_fec0(pdata)	mx28_add_fec(0, pdata)
+#define mx28_add_fec1(pdata)	mx28_add_fec(1, pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..a2389b2
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id, _size)			\
+	{								\
+		.id = _id,						\
+		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
+		.iosize = _size,					\
+		.irq = soc ## _INT_ENET_MAC ## _id,			\
+	}
+
+#define mxs_fec_data_entry(soc, _id, _size)				\
+	[_id] = mxs_fec_data_entry_single(soc, _id, _size)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id)					\
+	mxs_fec_data_entry(MX28, _id, SZ_16K)
+	mx28_fec_data_entry(0),
+	mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + data->iosize - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("fec", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
 };
 struct platform_device *__init mxs_add_duart(
 		const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 13/15] ARM: mxs: Add initial mx23evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (11 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 20:02   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
                   ` (33 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx23evk support with duart.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx23evk.c |   59 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 59 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c

diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..9048035
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+static iomux_cfg_t mx23evk_pads[] = {
+	/* duart */
+	MX23_PAD_PWM0__DUART_RX,
+	MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+	mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+	mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+	.init	= mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mx23_map_io,
+	.init_irq       = mx23_init_irq,
+	.init_machine   = mx23evk_init,
+	.timer          = &mx23evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 14/15] ARM: mxs: Add initial mx28evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (12 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 20:06   ` Uwe Kleine-König
  2010-11-26  6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
                   ` (32 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx28evk support with duart and fec0.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-mxs/mach-mx28evk.c |  108 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 108 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..901e6b1
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+
+#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+
+static iomux_cfg_t mx28evk_pads[] = {
+	/* duart */
+	MX28_PAD_PWM0__DUART_RX,
+	MX28_PAD_PWM1__DUART_TX,
+
+	/* fec0 */
+	MX28_PAD_ENET0_MDC__ENET0_MDC,
+	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
+	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
+	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
+	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
+	MX28_PAD_ENET_CLK__ENET_CLK,
+	/* phy power line */
+	MX28_PAD_SSP1_DATA3__GPIO_2_15,
+	/* phy reset line */
+	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
+};
+
+/* fec */
+static inline void mx28evk_fec_reset(void)
+{
+	int ret;
+
+	/* Power up fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+	if (ret) {
+		pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
+		return;
+	}
+	gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+
+	/* Reset fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+	if (ret) {
+		pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
+		return;
+	}
+	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+	mdelay(1);
+	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+        .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+	mx28_add_duart();
+
+	mx28evk_fec_reset();
+	mx28_add_fec0(&mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+	mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+	.init	= mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.boot_params    = PHYS_OFFSET + 0x100,
+	.map_io         = mx28_map_io,
+	.init_irq       = mx28_init_irq,
+	.init_machine   = mx28evk_init,
+	.timer          = &mx28evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 15/15] ARM: mxs: Add build configuration for mxs
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (13 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-11-26  6:49 ` Shawn Guo
  2010-11-30 20:08   ` Uwe Kleine-König
  2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
                   ` (31 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26  6:49 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/Kconfig                   |   10 ++++++++++
 arch/arm/Makefile                  |    1 +
 arch/arm/mach-mxs/Kconfig          |   34 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/Makefile         |   14 ++++++++++++++
 arch/arm/mach-mxs/Makefile.boot    |    3 +++
 arch/arm/mach-mxs/devices/Kconfig  |    5 +++++
 arch/arm/mach-mxs/devices/Makefile |    2 ++
 7 files changed, 69 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/Kconfig
 create mode 100644 arch/arm/mach-mxs/Makefile
 create mode 100644 arch/arm/mach-mxs/Makefile.boot
 create mode 100644 arch/arm/mach-mxs/devices/Kconfig
 create mode 100644 arch/arm/mach-mxs/devices/Makefile

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..b0a5130 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
+config ARCH_MXS
+	bool "Freescale MXS-based"
+	select GENERIC_CLOCKEVENTS
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLKDEV
+	help
+	  Support for Freescale MXS-based family of processors
+
 config ARCH_STMP3XXX
 	bool "Freescale STMP3xxx"
 	select CPU_ARM926T
@@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
 
 source "arch/arm/mach-mmp/Kconfig"
 
+source "arch/arm/mach-mxs/Kconfig"
+
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25)		:= imx
 machine-$(CONFIG_ARCH_MX3)		:= mx3
 machine-$(CONFIG_ARCH_MX5)		:= mx5
 machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
+machine-$(CONFIG_ARCH_MXS)		:= mxs
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+	bool
+	select CPU_ARM926T
+
+config SOC_IMX28
+	bool
+	select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+	bool "Support MX23EVK Platform"
+	select SOC_IMX23
+	select MXS_HAVE_PLATFORM_DUART
+	default y
+	help
+	  Include support for MX23EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+	bool "Support MX28EVK Platform"
+	select SOC_IMX28
+	select MXS_HAVE_PLATFORM_DUART
+	select MXS_HAVE_PLATFORM_FEC
+	default y
+	help
+	  Include support for MX28EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..0b24b0d
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..1568ad4
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x40008000
+params_phys-y	:= 0x40000100
+initrd_phys-y	:= 0x40800000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+	bool
+
+config MXS_HAVE_PLATFORM_FEC
+	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26  6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-26  9:31   ` Lothar Waßmann
  2010-11-26  9:57     ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26  9:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
[...]
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..de33c66
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; 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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG	0x50
> +#define MXS_WATCHDOG_EN		(1 << 4)
> +
> +#define MXS_MODULE_CLKGATE	(1 << 30)
> +#define MXS_MODULE_SFTRST	(1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> +	struct clk *clk;
> +
> +	clk = clk_get_sys("rtc", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
> +
>
Since arch_reset() may be called from interrupt context (e.g. due to
SYSRQ-B) it must not call any functions that may sleep like clk_get*()
or clk_enable(). The clock should be acquired and enabled in the init
routine.

> +void mxs_arch_reset_init(void __iomem *base)
> +{
> +	wdog_base = base;
> +}
> +

Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26  9:31   ` Lothar Waßmann
@ 2010-11-26  9:57     ` Uwe Kleine-König
  2010-11-26 10:38       ` Lothar Waßmann
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Lothar,

On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> Shawn Guo writes:
> [...]
> > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> > new file mode 100644
> > index 0000000..de33c66
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/system.c
> > @@ -0,0 +1,152 @@
> > +/*
> > + * Copyright (C) 1999 ARM Limited
> > + * Copyright (C) 2000 Deep Blue Solutions Ltd
> > + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> > + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> > + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; 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.
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/err.h>
> > +#include <linux/delay.h>
> > +
> > +#include <asm/proc-fns.h>
> > +#include <asm/system.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +
> > +#define MXS_RTC_WATCHDOG	0x50
> > +#define MXS_WATCHDOG_EN		(1 << 4)
> > +
> > +#define MXS_MODULE_CLKGATE	(1 << 30)
> > +#define MXS_MODULE_SFTRST	(1 << 31)
> > +
> > +static void __iomem *wdog_base;
> > +
> > +/*
> > + * Reset the system. It is called by machine_restart().
> > + */
> > +void arch_reset(char mode, const char *cmd)
> > +{
> > +	struct clk *clk;
> > +
> > +	clk = clk_get_sys("rtc", NULL);
> > +	if (!IS_ERR(clk))
> > +		clk_enable(clk);
> > +
> >
> Since arch_reset() may be called from interrupt context (e.g. due to
> SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> or clk_enable(). The clock should be acquired and enabled in the init
> routine.
This is a problem that also exist in arch/arm/plat-mxc/system.c's
arch_reset.

Did you already verify that this is indeed a problem?  I guess there are
more architectures that use clk_get in arch_reset, aren't there?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26  9:57     ` Uwe Kleine-König
@ 2010-11-26 10:38       ` Lothar Waßmann
  2010-11-26 11:32         ` Uwe Kleine-König
  2010-11-26 14:16         ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
  0 siblings, 2 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 10:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Uwe Kleine-K?nig writes:
> On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > Shawn Guo writes:
> > [...]
> > > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> > > new file mode 100644
> > > index 0000000..de33c66
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mxs/system.c
> > > @@ -0,0 +1,152 @@
> > > +/*
> > > + * Copyright (C) 1999 ARM Limited
> > > + * Copyright (C) 2000 Deep Blue Solutions Ltd
> > > + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> > > + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> > > + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> > > + *
> > > + * This program is free software; you can redistribute it and/or modify
> > > + * it under the terms of the GNU General Public License as published by
> > > + * the Free Software Foundation; 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.
> > > + */
> > > +
> > > +#include <linux/kernel.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/io.h>
> > > +#include <linux/err.h>
> > > +#include <linux/delay.h>
> > > +
> > > +#include <asm/proc-fns.h>
> > > +#include <asm/system.h>
> > > +
> > > +#include <mach/hardware.h>
> > > +#include <mach/common.h>
> > > +
> > > +#define MXS_RTC_WATCHDOG	0x50
> > > +#define MXS_WATCHDOG_EN		(1 << 4)
> > > +
> > > +#define MXS_MODULE_CLKGATE	(1 << 30)
> > > +#define MXS_MODULE_SFTRST	(1 << 31)
> > > +
> > > +static void __iomem *wdog_base;
> > > +
> > > +/*
> > > + * Reset the system. It is called by machine_restart().
> > > + */
> > > +void arch_reset(char mode, const char *cmd)
> > > +{
> > > +	struct clk *clk;
> > > +
> > > +	clk = clk_get_sys("rtc", NULL);
> > > +	if (!IS_ERR(clk))
> > > +		clk_enable(clk);
> > > +
> > >
> > Since arch_reset() may be called from interrupt context (e.g. due to
> > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > or clk_enable(). The clock should be acquired and enabled in the init
> > routine.
> This is a problem that also exist in arch/arm/plat-mxc/system.c's
> arch_reset.
> 
> Did you already verify that this is indeed a problem?  I guess there are
> more architectures that use clk_get in arch_reset, aren't there?
> 
If you consider this a problem:
BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
280
in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
2 locks held by swapper/0:
 #0:  (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
 #1:  (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
irq event stamp: 130658
hardirqs last  enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
softirqs last  enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
Backtrace: 
[<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
 r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
[<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
[<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
 r4:c032afd4
[<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
[<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
[<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
 r5:00000000 r4:00000068
[<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
 r5:d186b9c0 r4:00000062
[<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
[<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
[<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
[<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
[<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
[<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
[<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
 r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
[<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
 r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
[<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
 r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
[<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
Exception stack(0xc0327f48 to 0xc0327f90)
7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
7f80: c006c620 c0027f8c 20000013 ffffffff                                     
 r5:fc400000 r4:0000001f
[<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
[<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
 r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
[<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
[<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
 r5:c0354284 r4:00053175
------------[ cut here ]------------
WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
Modules linked in:
Backtrace: 
[<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
 r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
[<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
[<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
 r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
[<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
[<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
[<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
[<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
 r5:00000000 r4:00000068
[<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
 r5:d186b9c0 r4:00000062
[<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
[<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
[<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
[<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
[<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
[<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
[<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
 r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
[<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
 r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
[<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
 r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
[<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
Exception stack(0xc0327f48 to 0xc0327f90)
7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
7f80: c006c620 c0027f8c 20000013 ffffffff                                     
 r5:fc400000 r4:0000001f
[<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
[<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
 r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
[<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
[<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
 r5:c0354284 r4:00053175
---[ end trace b484fc13651ee6f1 ]---


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 01/15] ARM: mxs: Add core definitions
  2010-11-26  6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-26 11:30   ` Uwe Kleine-König
  2010-11-29  7:21     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26 11:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Fri, Nov 26, 2010 at 02:49:00PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/include/mach/hardware.h |   66 +++++++++
>  arch/arm/mach-mxs/include/mach/irqs.h     |   32 ++++
>  arch/arm/mach-mxs/include/mach/memory.h   |   24 +++
>  arch/arm/mach-mxs/include/mach/mx23.h     |  147 +++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mx28.h     |  227 +++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mxs.h      |   60 ++++++++
>  6 files changed, 556 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..5edccd5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,66 @@
> +/*
> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA  02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr)	(addr)
> +#else
> +#define IOMEM(addr)	((void __force __iomem *)(addr))
> +#endif
> +
> +#define MXS_IO_P2V_MODULE(addr, module)					\
> +	(((addr) - module ## _BASE_ADDR) < module ## _SIZE ?		\
> +	 (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
Do you need this?  On imx this is only used in
arch/arm/mach-mx3/mach-kzm_arm11_01.c that uses it to map chip selects.
IMHO it should better use a dynamic mapping for that which would allow
to let IMX_IO_P2V_MODULE die.

> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
> + *
> + *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
> + *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
> + */
> +#define MXS_IO_P2V(x)	(						\
> +			0xf4000000 + 					\
> +			(((x) & 0x50000000) >> 6) +			\
> +			(((x) & 0x0b000000) >> 4) +			\
> +			(((x) & 0x000fffff)))
Did you test this?  For me MXS_IO_P2V(0x80000000) ==
MXS_IO_P2V(0x00000000).  You should be able to choose a much simpler
function, e.g.

		(0xf4000000 + (((x) & 0x80000000) >> 6) + (((x) & 0x000fffff))))

should work for the two areas above

> +
> +#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
> +
> +#ifdef CONFIG_SOC_IMX23
You don't need to protect inclusion of mach/mx23 if all symbols defined
in it are properly namespaced.

> +# include <mach/mx23.h>
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# include <mach/mx28.h>
> +#endif
> +
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type)	{				\
> +	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
> +	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
> +	.length = soc ## _ ## name ## _SIZE,				\
> +	.type = _type,							\
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + *  Copyright 2004-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 version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS	128
> +
> +#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS		(32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes.  Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS		16
> +
> +#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET		UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..27a11ee
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR		0x00000000
> +#define MX23_OCRAM_SIZE			SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR		0x80000000
> +#define MX23_IO_SIZE			SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART			0
> +#define MX23_INT_COMMS_RX		1
> +#define MX23_INT_COMMS_TX		1
really two names for irq 1?

> +#define MX23_INT_SSP2_ERROR		2
> +#define MX23_INT_VDD5V			3
> +#define MX23_INT_HEADPHONE_SHORT	4
> +#define MX23_INT_DAC_DMA		5
> +#define MX23_INT_DAC_ERROR		6
> +#define MX23_INT_ADC_DMA		7
> +#define MX23_INT_ADC_ERROR		8
> +#define MX23_INT_SPDIF_DMA		9
> +#define MX23_INT_SAIF2_DMA		9
ditto

> +#define MX23_INT_SPDIF_ERROR		10
> +#define MX23_INT_SAIF1_IRQ		10
> +#define MX23_INT_SAIF2_IRQ		10
ditto (3 that is)
> +#define MX23_INT_USB_CTRL		11
> +#define MX23_INT_USB_WAKEUP		12
> +#define MX23_INT_GPMI_DMA		13
> +#define MX23_INT_SSP1_DMA		14
> +#define MX23_INT_SSP_ERROR		15
> +#define MX23_INT_GPIO0			16
> +#define MX23_INT_GPIO1			17
> +#define MX23_INT_GPIO2			18
> +#define MX23_INT_SAIF1_DMA		19
> +#define MX23_INT_SSP2_DMA		20
> +#define MX23_INT_ECC8_IRQ		21
> +#define MX23_INT_RTC_ALARM		22
> +#define MX23_INT_UARTAPP_TX_DMA		23
> +#define MX23_INT_UARTAPP_INTERNAL	24
> +#define MX23_INT_UARTAPP_RX_DMA		25
> +#define MX23_INT_I2C_DMA		26
> +#define MX23_INT_I2C_ERROR		27
> +#define MX23_INT_TIMER0			28
> +#define MX23_INT_TIMER1			29
> +#define MX23_INT_TIMER2			30
> +#define MX23_INT_TIMER3			31
> +#define MX23_INT_BATT_BRNOUT		32
> +#define MX23_INT_VDDD_BRNOUT		33
> +#define MX23_INT_VDDIO_BRNOUT		34
> +#define MX23_INT_VDD18_BRNOUT		35
> +#define MX23_INT_TOUCH_DETECT		36
> +#define MX23_INT_LRADC_CH0		37
> +#define MX23_INT_LRADC_CH1		38
> +#define MX23_INT_LRADC_CH2		39
> +#define MX23_INT_LRADC_CH3		40
> +#define MX23_INT_LRADC_CH4		41
> +#define MX23_INT_LRADC_CH5		42
> +#define MX23_INT_LRADC_CH6		43
> +#define MX23_INT_LRADC_CH7		44
> +#define MX23_INT_LCDIF_DMA		45
> +#define MX23_INT_LCDIF_ERROR		46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP	47
> +#define MX23_INT_RTC_1MSEC		48
> +#define MX23_INT_DRI_DMA		49
> +#define MX23_INT_DRI_ATTENTION		50
> +#define MX23_INT_GPMI_ATTENTION		51
> +#define MX23_INT_IR			52
> +#define MX23_INT_DCP_VMI		53
> +#define MX23_INT_DCP			54
> +#define MX23_INT_BCH			56
> +#define MX23_INT_PXP			57
> +#define MX23_INT_UARTAPP2_TX_DMA	58
> +#define MX23_INT_UARTAPP2_INTERNAL	59
> +#define MX23_INT_UARTAPP2_RX_DMA	60
> +#define MX23_INT_VDAC_DETECT		61
> +#define MX23_INT_VDD5V_DROOP		64
> +#define MX23_INT_DCDC4P2_BO		65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..836d807
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,227 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR		0x00000000
> +#define MX28_OCRAM_SIZE			SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR		0x80000000
> +#define MX28_IO_SIZE			SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT		0
> +#define MX28_INT_VDDD_BRNOUT		1
> +#define MX28_INT_VDDIO_BRNOUT		2
> +#define MX28_INT_VDDA_BRNOUT		3
> +#define MX28_INT_VDD5V_DROOP		4
> +#define MX28_INT_DCDC4P2_BRNOUT		5
> +#define MX28_INT_VDD5V			6
> +#define MX28_INT_RESV7			7
> +#define MX28_INT_CAN0			8
> +#define MX28_INT_CAN1			9
> +#define MX28_INT_LRADC_TOUCH		10
> +#define MX28_INT_RESV11			11
> +#define MX28_INT_RESV12			12
> +#define MX28_INT_HSADC			13
> +#define MX28_INT_IRADC_THRESH0		14
> +#define MX28_INT_IRADC_THRESH1		15
> +#define MX28_INT_LRADC_CH0		16
> +#define MX28_INT_LRADC_CH1		17
> +#define MX28_INT_LRADC_CH2		18
> +#define MX28_INT_LRADC_CH3		19
> +#define MX28_INT_LRADC_CH4		20
> +#define MX28_INT_LRADC_CH5		21
> +#define MX28_INT_LRADC_CH6		22
> +#define MX28_INT_LRADC_CH7		23
> +#define MX28_INT_LRADC_BUTTON0		24
> +#define MX28_INT_LRADC_BUTTON1		25
> +#define MX28_INT_RESV26			26
> +#define MX28_INT_PERFMON		27
> +#define MX28_INT_RTC_1MSEC		28
> +#define MX28_INT_RTC_ALARM		29
> +#define MX28_INT_RESV30			30
> +#define MX28_INT_COMMS			31
> +#define MX28_INT_EMI_ERR		32
> +#define MX28_INT_RESV33			33
> +#define MX28_INT_RESV34			34
> +#define MX28_INT_RESV35			35
> +#define MX28_INT_RESV36			36
> +#define MX28_INT_RESV37			37
> +#define MX28_INT_LCDIF			38
> +#define MX28_INT_PXP			39
> +#define MX28_INT_RESV40			40
> +#define MX28_INT_BCH			41
> +#define MX28_INT_GPMI			42
> +#define MX28_INT_RESV43			43
> +#define MX28_INT_RESV44			44
> +#define MX28_INT_SPDIF_ERROR		45
> +#define MX28_INT_RESV46			46
> +#define MX28_INT_DUART			47
> +#define MX28_INT_TIMER0			48
> +#define MX28_INT_TIMER1			49
> +#define MX28_INT_TIMER2			50
> +#define MX28_INT_TIMER3			51
> +#define MX28_INT_DCP_VMI		52
> +#define MX28_INT_DCP			53
> +#define MX28_INT_DCP_SECURE		54
> +#define MX28_INT_RESV55			55
> +#define MX28_INT_RESV56			56
> +#define MX28_INT_RESV57			57
> +#define MX28_INT_SAIF1			58
> +#define MX28_INT_SAIF0			59
> +#define MX28_INT_RESV60			60
> +#define MX28_INT_RESV61			61
> +#define MX28_INT_RESV62			62
> +#define MX28_INT_RESV63			63
> +#define MX28_INT_RESV64			64
> +#define MX28_INT_RESV65			65
> +#define MX28_INT_SPDIF_DMA		66
> +#define MX28_INT_RESV67			67
> +#define MX28_INT_I2C0_DMA		68
> +#define MX28_INT_I2C1_DMA		69
> +#define MX28_INT_AUART0_RX_DMA		70
> +#define MX28_INT_AUART0_TX_DMA		71
> +#define MX28_INT_AUART1_RX_DMA		72
> +#define MX28_INT_AUART1_TX_DMA		73
> +#define MX28_INT_AUART2_RX_DMA		74
> +#define MX28_INT_AUART2_TX_DMA		75
> +#define MX28_INT_AUART3_RX_DMA		76
> +#define MX28_INT_AUART3_TX_DMA		77
> +#define MX28_INT_AUART4_RX_DMA		78
> +#define MX28_INT_AUART4_TX_DMA		79
> +#define MX28_INT_SAIF0_DMA		80
> +#define MX28_INT_SAIF1_DMA		81
> +#define MX28_INT_SSP0_DMA		82
> +#define MX28_INT_SSP1_DMA		83
> +#define MX28_INT_SSP2_DMA		84
> +#define MX28_INT_SSP3_DMA		85
> +#define MX28_INT_LCDIF_DMA		86
> +#define MX28_INT_HSADC_DMA		87
> +#define MX28_INT_GPMI_DMA		88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP	89
> +#define MX28_INT_RESV90			90
> +#define MX28_INT_RESV91			91
> +#define MX28_INT_USB1			92
> +#define MX28_INT_USB0			93
> +#define MX28_INT_USB1_WAKEUP		94
> +#define MX28_INT_USB0_WAKEUP		95
> +#define MX28_INT_SSP0			96
> +#define MX28_INT_SSP1			97
> +#define MX28_INT_SSP2			98
> +#define MX28_INT_SSP3			99
> +#define MX28_INT_ENET_SWI		100
> +#define MX28_INT_ENET_MAC0		101
> +#define MX28_INT_ENET_MAC1		102
> +#define MX28_INT_ENET_MAC0_1588		103
> +#define MX28_INT_ENET_MAC1_1588		104
> +#define MX28_INT_RESV105		105
> +#define MX28_INT_RESV106		106
> +#define MX28_INT_RESV107		107
> +#define MX28_INT_RESV108		108
> +#define MX28_INT_RESV109		109
> +#define MX28_INT_I2C1_ERROR		110
> +#define MX28_INT_I2C0_ERROR		111
> +#define MX28_INT_AUART0			112
> +#define MX28_INT_AUART1			113
> +#define MX28_INT_AUART2			114
> +#define MX28_INT_AUART3			115
> +#define MX28_INT_AUART4			116
> +#define MX28_INT_RESV117		117
> +#define MX28_INT_RESV118		118
> +#define MX28_INT_RESV119		119
> +#define MX28_INT_RESV120		120
> +#define MX28_INT_RESV121		121
> +#define MX28_INT_RESV122		122
> +#define MX28_INT_GPIO4			123
> +#define MX28_INT_GPIO3			124
> +#define MX28_INT_GPIO2			125
> +#define MX28_INT_GPIO1			126
> +#define MX28_INT_GPIO0			127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..128c114
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#define MXS_SET_ADDR		0x4
> +#define MXS_CLR_ADDR		0x8
> +#define MXS_TOG_ADDR		0xc
> +
> +/*
> + * MXS CPU types
> + */
> +#define MXS_CPU_MX23		23
> +#define MXS_CPU_MX28		28
> +
> +#ifndef __ASSEMBLY__
> +extern unsigned int __mxs_cpu_type;
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX23
> +# ifdef mxs_cpu_type
> +#  undef mxs_cpu_type
> +#  define mxs_cpu_type __mxs_cpu_type
> +# else
> +#  define mxs_cpu_type MXS_CPU_MX23
> +# endif
> +# define cpu_is_mx23()		(mxs_cpu_type == MXS_CPU_MX23)
> +#else
> +# define cpu_is_mx23()		(0)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# ifdef mxs_cpu_type
> +#  undef mxs_cpu_type
> +#  define mxs_cpu_type __mxs_cpu_type
> +# else
> +#  define mxs_cpu_type MXS_CPU_MX28
> +# endif
> +# define cpu_is_mx28()		(mxs_cpu_type == MXS_CPU_MX28)
> +#else
> +# define cpu_is_mx28()		(0)
> +#endif
For imx I wondered if this is overkill.  When I started mainlining
ns9xxx I just did:

	#define cpu_is_xyz() (machine_is_abc() || ...)

It's much easier and the generated code probably is not much worse.
(Better try to reduce the number of usages of these macros.)

(Note, if you're convinced this is good, go ahead, just my personal
opinion.)

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26 10:38       ` Lothar Waßmann
@ 2010-11-26 11:32         ` Uwe Kleine-König
  2010-11-26 12:53           ` Lothar Waßmann
  2010-11-29  9:25           ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
  2010-11-26 14:16         ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
  1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Lothar,

On Fri, Nov 26, 2010 at 11:38:47AM +0100, Lothar Wa?mann wrote:
> Uwe Kleine-K?nig writes:
> > On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > > Since arch_reset() may be called from interrupt context (e.g. due to
> > > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > > or clk_enable(). The clock should be acquired and enabled in the init
> > > routine.
> > This is a problem that also exist in arch/arm/plat-mxc/system.c's
> > arch_reset.
> > 
> > Did you already verify that this is indeed a problem?  I guess there are
> > more architectures that use clk_get in arch_reset, aren't there?
> > 
> If you consider this a problem:
> BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> 280
> in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> 2 locks held by swapper/0:
>  #0:  (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
>  #1:  (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> irq event stamp: 130658
> hardirqs last  enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> softirqs last  enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> Backtrace: 
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
>  r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
>  r4:c032afd4
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
>  r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
>  r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
>  r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
>  r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
>  r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
> 7f80: c006c620 c0027f8c 20000013 ffffffff                                     
>  r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
>  r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
>  r5:c0354284 r4:00053175
> ------------[ cut here ]------------
> WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> Modules linked in:
> Backtrace: 
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
>  r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
>  r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
>  r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
>  r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
>  r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
>  r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
>  r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
> 7f80: c006c620 c0027f8c 20000013 ffffffff                                     
>  r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
>  r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
>  r5:c0354284 r4:00053175
> ---[ end trace b484fc13651ee6f1 ]---
do you care enough to send a patch?  If not I can set it on my agenda.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26 11:32         ` Uwe Kleine-König
@ 2010-11-26 12:53           ` Lothar Waßmann
  2010-11-29  9:25           ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
  1 sibling, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 12:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Uwe Kleine-K?nig writes:
> Hello Lothar,
> 
> On Fri, Nov 26, 2010 at 11:38:47AM +0100, Lothar Wa?mann wrote:
> > Uwe Kleine-K?nig writes:
> > > On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > > > Since arch_reset() may be called from interrupt context (e.g. due to
> > > > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > > > or clk_enable(). The clock should be acquired and enabled in the init
> > > > routine.
> > > This is a problem that also exist in arch/arm/plat-mxc/system.c's
> > > arch_reset.
> > > 
> > > Did you already verify that this is indeed a problem?  I guess there are
> > > more architectures that use clk_get in arch_reset, aren't there?
> > > 
> > If you consider this a problem:
> > BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> > 280
> > in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> > 2 locks held by swapper/0:
> >  #0:  (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> >  #1:  (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> > irq event stamp: 130658
> > hardirqs last  enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> > hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> > softirqs last  enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> > softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> > Backtrace: 
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> >  r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> > [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> >  r4:c032afd4
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> >  r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> >  r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> >  r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> >  r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> >  r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
> > 7f80: c006c620 c0027f8c 20000013 ffffffff                                     
> >  r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> >  r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> >  r5:c0354284 r4:00053175
> > ------------[ cut here ]------------
> > WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> > Modules linked in:
> > Backtrace: 
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> >  r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> > [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> >  r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> > [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> >  r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> >  r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> >  r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> >  r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> >  r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40:                   00000001 0016e240 20000093 20000013 c0326000 c032aaa8 
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90 
> > 7f80: c006c620 c0027f8c 20000013 ffffffff                                     
> >  r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> >  r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> >  r5:c0354284 r4:00053175
> > ---[ end trace b484fc13651ee6f1 ]---
> do you care enough to send a patch?  If not I can set it on my agenda.
> 
I have it on my to-do list for quite some time. I'll finally try to
get it out soon.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26 10:38       ` Lothar Waßmann
  2010-11-26 11:32         ` Uwe Kleine-König
@ 2010-11-26 14:16         ` Xinyu Chen
  2010-11-26 14:38           ` Lothar Waßmann
  1 sibling, 1 reply; 146+ messages in thread
From: Xinyu Chen @ 2010-11-26 14:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar

2010/11/26 Lothar Wa?mann <LW@karo-electronics.de>:
> Hi,
>
> Uwe Kleine-K?nig writes:
>> On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
>> > Shawn Guo writes:
>> > [...]
>> > > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
>> > > new file mode 100644
>> > > index 0000000..de33c66
>> > > --- /dev/null
>> > > +++ b/arch/arm/mach-mxs/system.c
>> > > @@ -0,0 +1,152 @@
>> > > +/*
>> > > + * Copyright (C) 1999 ARM Limited
>> > > + * Copyright (C) 2000 Deep Blue Solutions Ltd
>> > > + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
>> > > + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>> > > + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
>> > > + *
>> > > + * This program is free software; you can redistribute it and/or modify
>> > > + * it under the terms of the GNU General Public License as published by
>> > > + * the Free Software Foundation; 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.
>> > > + */
>> > > +
>> > > +#include <linux/kernel.h>
>> > > +#include <linux/clk.h>
>> > > +#include <linux/io.h>
>> > > +#include <linux/err.h>
>> > > +#include <linux/delay.h>
>> > > +
>> > > +#include <asm/proc-fns.h>
>> > > +#include <asm/system.h>
>> > > +
>> > > +#include <mach/hardware.h>
>> > > +#include <mach/common.h>
>> > > +
>> > > +#define MXS_RTC_WATCHDOG 0x50
>> > > +#define MXS_WATCHDOG_EN ? ? ? ? ?(1 << 4)
>> > > +
>> > > +#define MXS_MODULE_CLKGATE ? ? ? (1 << 30)
>> > > +#define MXS_MODULE_SFTRST ? ? ? ?(1 << 31)
>> > > +
>> > > +static void __iomem *wdog_base;
>> > > +
>> > > +/*
>> > > + * Reset the system. It is called by machine_restart().
>> > > + */
>> > > +void arch_reset(char mode, const char *cmd)
>> > > +{
>> > > + struct clk *clk;
>> > > +
>> > > + clk = clk_get_sys("rtc", NULL);
>> > > + if (!IS_ERR(clk))
>> > > + ? ? ? ? clk_enable(clk);
>> > > +
>> > >
>> > Since arch_reset() may be called from interrupt context (e.g. due to
>> > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
>> > or clk_enable(). The clock should be acquired and enabled in the init
>> > routine.
>> This is a problem that also exist in arch/arm/plat-mxc/system.c's
>> arch_reset.
>>
>> Did you already verify that this is indeed a problem? ?I guess there are
>> more architectures that use clk_get in arch_reset, aren't there?
>>
> If you consider this a problem:
> BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> 280
> in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> 2 locks held by swapper/0:
> ?#0: ?(&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> ?#1: ?(sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> irq event stamp: 130658
> hardirqs last ?enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> softirqs last ?enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> ?r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> ?r4:c032afd4
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> ?r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> ?r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> ?r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> ?r5:c0354284 r4:00053175
> ------------[ cut here ]------------
> WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> Modules linked in:
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> ?r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> ?r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> ?r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> ?r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> ?r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> ?r5:c0354284 r4:00053175
> ---[ end trace b484fc13651ee6f1 ]---

could we use spin_lock but not mutex_lock in the clk_enable/disable?
I'm considering there may have drivers call clk enable/disable in the
irq context to done feature or save power.


-- 
Best Regards
Xinyu Chen
Freescale Semiconductor, MAD Linux

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 03/15] ARM: mxs: Add reset routines
  2010-11-26 14:16         ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
@ 2010-11-26 14:38           ` Lothar Waßmann
  0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Xinyu Chen writes:
> Hi Lothar
> 
> 2010/11/26 Lothar Wa?mann <LW@karo-electronics.de>:
> > If you consider this a problem:
> > BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> > 280
> > in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> > 2 locks held by swapper/0:
> > ?#0: ?(&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> > ?#1: ?(sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> > irq event stamp: 130658
> > hardirqs last ?enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> > hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> > softirqs last ?enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> > softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > ?r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> > [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> > ?r4:c032afd4
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > ?r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > ?r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > ?r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > ?r5:c0354284 r4:00053175
> > ------------[ cut here ]------------
> > WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> > Modules linked in:
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > ?r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> > [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> > ?r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> > [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > ?r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > ?r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > ?r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > ?r5:c0354284 r4:00053175
> > ---[ end trace b484fc13651ee6f1 ]---
> 
> could we use spin_lock but not mutex_lock in the clk_enable/disable?
> I'm considering there may have drivers call clk enable/disable in the
> irq context to done feature or save power.
> 
This has already been discussed in June this year and rejected:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017758.html

Anyway the offending code in this case is the clk_get_sys() function.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 01/15] ARM: mxs: Add core definitions
  2010-11-26 11:30   ` Uwe Kleine-König
@ 2010-11-29  7:21     ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29  7:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

Thanks for the review.

2010/11/26 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:00PM +0800, Shawn Guo wrote:
>> Add core definitions for MXS-based SoC MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> ?arch/arm/mach-mxs/include/mach/hardware.h | ? 66 +++++++++
>> ?arch/arm/mach-mxs/include/mach/irqs.h ? ? | ? 32 ++++
>> ?arch/arm/mach-mxs/include/mach/memory.h ? | ? 24 +++
>> ?arch/arm/mach-mxs/include/mach/mx23.h ? ? | ?147 +++++++++++++++++++
>> ?arch/arm/mach-mxs/include/mach/mx28.h ? ? | ?227 +++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/include/mach/mxs.h ? ? ?| ? 60 ++++++++
>> ?6 files changed, 556 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>>
>> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
>> new file mode 100644
>> index 0000000..5edccd5
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
>> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>> + *
>> + * 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., 51 Franklin Street, Fifth Floor, Boston,
>> + * MA ?02110-1301, USA.
>> + */
>> +
>> +#ifndef __MACH_MXS_HARDWARE_H__
>> +#define __MACH_MXS_HARDWARE_H__
>> +
>> +#include <asm/sizes.h>
>> +
>> +#ifdef __ASSEMBLER__
>> +#define IOMEM(addr) ?(addr)
>> +#else
>> +#define IOMEM(addr) ?((void __force __iomem *)(addr))
>> +#endif
>> +
>> +#define MXS_IO_P2V_MODULE(addr, module) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? ? ? ? ? ? ?\
>> + ? ? ?(addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
> Do you need this? ?On imx this is only used in
> arch/arm/mach-mx3/mach-kzm_arm11_01.c that uses it to map chip selects.
> IMHO it should better use a dynamic mapping for that which would allow
> to let IMX_IO_P2V_MODULE die.
>
Will remove it.

>> +/*
>> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
>> + *
>> + * ? OCRAM ? 0x00000000+0x020000 ? ? -> ? ? ?0xf4000000+0x020000
>> + * ? IO ? ? ?0x80000000+0x100000 ? ? -> ? ? ?0xf4400000+0x100000
>> + */
>> +#define MXS_IO_P2V(x) ? ? ? ?( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? 0xf4000000 + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x50000000) >> 6) + ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x0b000000) >> 4) + ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x000fffff)))
> Did you test this? ?For me MXS_IO_P2V(0x80000000) ==
> MXS_IO_P2V(0x00000000). ?You should be able to choose a much simpler
> function, e.g.
>
> ? ? ? ? ? ? ? ?(0xf4000000 + (((x) & 0x80000000) >> 6) + (((x) & 0x000fffff))))
>
> should work for the two areas above
>
I tested it with limited modules.  But I would take your suggestion to
simplify the definition.

>> +
>> +#define MXS_IO_ADDRESS(x) ? ?IOMEM(MXS_IO_P2V(x))
>> +
>> +#ifdef CONFIG_SOC_IMX23
> You don't need to protect inclusion of mach/mx23 if all symbols defined
> in it are properly namespaced.
>
Will remove them.

>> +# include <mach/mx23.h>
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX28
>> +# include <mach/mx28.h>
>> +#endif
>> +
>> +#include <mach/mxs.h>
>> +
>> +#define mxs_map_entry(soc, name, _type) ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), ? ? ?\
>> + ? ? .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), ? ? ? ? ? \
>> + ? ? .length = soc ## _ ## name ## _SIZE, ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? .type = _type, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +}
>> +
>> +#endif /* __MACH_MXS_HARDWARE_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
>> new file mode 100644
>> index 0000000..f771039
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + * ?Copyright 2004-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 version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#ifndef __MACH_MXS_IRQS_H__
>> +#define __MACH_MXS_IRQS_H__
>> +
>> +#define MXS_INTERNAL_IRQS ? ?128
>> +
>> +#define MXS_GPIO_IRQ_START ? MXS_INTERNAL_IRQS
>> +
>> +/* the maximum for MXS-based */
>> +#define MXS_GPIO_IRQS ? ? ? ? ? ? ? ?(32 * 5)
>> +
>> +/*
>> + * The next 16 interrupts are for board specific purposes. ?Since
>> + * the kernel can only run on one machine at a time, we can re-use
>> + * these. ?If you need more, increase MXS_BOARD_IRQS, but keep it
>> + * within sensible limits.
>> + */
>> +#define MXS_BOARD_IRQ_START ?(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
>> +#define MXS_BOARD_IRQS ? ? ? ? ? ? ? 16
>> +
>> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ?(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
>> +
>> +#endif /* __MACH_MXS_IRQS_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
>> new file mode 100644
>> index 0000000..b5420a5
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/memory.h
>> @@ -0,0 +1,24 @@
>> +/*
>> + * Copyright (C) 2009-2010 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef __MACH_MXS_MEMORY_H__
>> +#define __MACH_MXS_MEMORY_H__
>> +
>> +#define PHYS_OFFSET ? ? ? ? ?UL(0x40000000)
>> +
>> +#endif /* __MACH_MXS_MEMORY_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
>> new file mode 100644
>> index 0000000..27a11ee
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
>> @@ -0,0 +1,147 @@
>> +/*
>> + * Copyright (C) 2009-2010 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef __MACH_MX23_H__
>> +#define __MACH_MX23_H__
>> +
>> +#ifndef __ASSEMBLER__
>> +#include <linux/io.h>
>> +#endif
>> +
>> +/*
>> + * OCRAM
>> + */
>> +#define MX23_OCRAM_BASE_ADDR ? ? ? ? 0x00000000
>> +#define MX23_OCRAM_SIZE ? ? ? ? ? ? ? ? ? ? ?SZ_32K
>> +
>> +/*
>> + * IO
>> + */
>> +#define MX23_IO_BASE_ADDR ? ? ? ? ? ?0x80000000
>> +#define MX23_IO_SIZE ? ? ? ? ? ? ? ? SZ_1M
>> +
>> +#define MX23_ICOLL_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x000000)
>> +#define MX23_APBH_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x004000)
>> +#define MX23_BCH_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x00a000)
>> +#define MX23_GPMI_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x00c000)
>> +#define MX23_SSP1_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x010000)
>> +#define MX23_SSP2_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x034000)
>> +#define MX23_PINCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x018000)
>> +#define MX23_DIGCTL_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x01c000)
>> +#define MX23_ETM_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x020000)
>> +#define MX23_APBX_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x024000)
>> +#define MX23_DCP_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x028000)
>> +#define MX23_PXP_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x02a000)
>> +#define MX23_OCOTP_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x02c000)
>> +#define MX23_AXI_AHB0_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x02e000)
>> +#define MX23_LCDIF_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x030000)
>> +#define MX23_TVENC_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x038000)
>> +#define MX23_CLKCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x040000)
>> +#define MX23_SAIF0_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x042000)
>> +#define MX23_POWER_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x044000)
>> +#define MX23_SAIF1_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x046000)
>> +#define MX23_AUDIOOUT_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x048000)
>> +#define MX23_AUDIOIN_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x04c000)
>> +#define MX23_LRADC_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x050000)
>> +#define MX23_SPDIF_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x054000)
>> +#define MX23_RTC_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x05c000)
>> +#define MX23_I2C0_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x058000)
>> +#define MX23_PWM_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x064000)
>> +#define MX23_TIMROT_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x068000)
>> +#define MX23_AUART1_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x06c000)
>> +#define MX23_AUART2_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x06e000)
>> +#define MX23_DUART_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x070000)
>> +#define MX23_USBPHY_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x07c000)
>> +#define MX23_USBCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x080000)
>> +#define MX23_DRAM_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x0e0000)
>> +
>> +#define MX23_IO_P2V(x) ? ? ? ? ? ? ? ? ? ? ? MXS_IO_P2V(x)
>> +#define MX23_IO_ADDRESS(x) ? ? ? ? ? IOMEM(MX23_IO_P2V(x))
>> +
>> +/*
>> + * IRQ
>> + */
>> +#define MX23_INT_DUART ? ? ? ? ? ? ? ? ? ? ? 0
>> +#define MX23_INT_COMMS_RX ? ? ? ? ? ?1
>> +#define MX23_INT_COMMS_TX ? ? ? ? ? ?1
> really two names for irq 1?
>
i.MX23 Application Processor Reference Manual, section 5.2.3 Interrupt Sources.

>> +#define MX23_INT_SSP2_ERROR ? ? ? ? ?2
>> +#define MX23_INT_VDD5V ? ? ? ? ? ? ? ? ? ? ? 3
>> +#define MX23_INT_HEADPHONE_SHORT ? ? 4
>> +#define MX23_INT_DAC_DMA ? ? ? ? ? ? 5
>> +#define MX23_INT_DAC_ERROR ? ? ? ? ? 6
>> +#define MX23_INT_ADC_DMA ? ? ? ? ? ? 7
>> +#define MX23_INT_ADC_ERROR ? ? ? ? ? 8
>> +#define MX23_INT_SPDIF_DMA ? ? ? ? ? 9
>> +#define MX23_INT_SAIF2_DMA ? ? ? ? ? 9
> ditto
>
>> +#define MX23_INT_SPDIF_ERROR ? ? ? ? 10
>> +#define MX23_INT_SAIF1_IRQ ? ? ? ? ? 10
>> +#define MX23_INT_SAIF2_IRQ ? ? ? ? ? 10
> ditto (3 that is)
>> +#define MX23_INT_USB_CTRL ? ? ? ? ? ?11
>> +#define MX23_INT_USB_WAKEUP ? ? ? ? ?12
>> +#define MX23_INT_GPMI_DMA ? ? ? ? ? ?13
>> +#define MX23_INT_SSP1_DMA ? ? ? ? ? ?14
>> +#define MX23_INT_SSP_ERROR ? ? ? ? ? 15
>> +#define MX23_INT_GPIO0 ? ? ? ? ? ? ? ? ? ? ? 16
>> +#define MX23_INT_GPIO1 ? ? ? ? ? ? ? ? ? ? ? 17
>> +#define MX23_INT_GPIO2 ? ? ? ? ? ? ? ? ? ? ? 18
>> +#define MX23_INT_SAIF1_DMA ? ? ? ? ? 19
>> +#define MX23_INT_SSP2_DMA ? ? ? ? ? ?20
>> +#define MX23_INT_ECC8_IRQ ? ? ? ? ? ?21
>> +#define MX23_INT_RTC_ALARM ? ? ? ? ? 22
>> +#define MX23_INT_UARTAPP_TX_DMA ? ? ? ? ? ? ?23
>> +#define MX23_INT_UARTAPP_INTERNAL ? ?24
>> +#define MX23_INT_UARTAPP_RX_DMA ? ? ? ? ? ? ?25
>> +#define MX23_INT_I2C_DMA ? ? ? ? ? ? 26
>> +#define MX23_INT_I2C_ERROR ? ? ? ? ? 27
>> +#define MX23_INT_TIMER0 ? ? ? ? ? ? ? ? ? ? ?28
>> +#define MX23_INT_TIMER1 ? ? ? ? ? ? ? ? ? ? ?29
>> +#define MX23_INT_TIMER2 ? ? ? ? ? ? ? ? ? ? ?30
>> +#define MX23_INT_TIMER3 ? ? ? ? ? ? ? ? ? ? ?31
>> +#define MX23_INT_BATT_BRNOUT ? ? ? ? 32
>> +#define MX23_INT_VDDD_BRNOUT ? ? ? ? 33
>> +#define MX23_INT_VDDIO_BRNOUT ? ? ? ? ? ? ? ?34
>> +#define MX23_INT_VDD18_BRNOUT ? ? ? ? ? ? ? ?35
>> +#define MX23_INT_TOUCH_DETECT ? ? ? ? ? ? ? ?36
>> +#define MX23_INT_LRADC_CH0 ? ? ? ? ? 37
>> +#define MX23_INT_LRADC_CH1 ? ? ? ? ? 38
>> +#define MX23_INT_LRADC_CH2 ? ? ? ? ? 39
>> +#define MX23_INT_LRADC_CH3 ? ? ? ? ? 40
>> +#define MX23_INT_LRADC_CH4 ? ? ? ? ? 41
>> +#define MX23_INT_LRADC_CH5 ? ? ? ? ? 42
>> +#define MX23_INT_LRADC_CH6 ? ? ? ? ? 43
>> +#define MX23_INT_LRADC_CH7 ? ? ? ? ? 44
>> +#define MX23_INT_LCDIF_DMA ? ? ? ? ? 45
>> +#define MX23_INT_LCDIF_ERROR ? ? ? ? 46
>> +#define MX23_INT_DIGCTL_DEBUG_TRAP ? 47
>> +#define MX23_INT_RTC_1MSEC ? ? ? ? ? 48
>> +#define MX23_INT_DRI_DMA ? ? ? ? ? ? 49
>> +#define MX23_INT_DRI_ATTENTION ? ? ? ? ? ? ? 50
>> +#define MX23_INT_GPMI_ATTENTION ? ? ? ? ? ? ?51
>> +#define MX23_INT_IR ? ? ? ? ? ? ? ? ?52
>> +#define MX23_INT_DCP_VMI ? ? ? ? ? ? 53
>> +#define MX23_INT_DCP ? ? ? ? ? ? ? ? 54
>> +#define MX23_INT_BCH ? ? ? ? ? ? ? ? 56
>> +#define MX23_INT_PXP ? ? ? ? ? ? ? ? 57
>> +#define MX23_INT_UARTAPP2_TX_DMA ? ? 58
>> +#define MX23_INT_UARTAPP2_INTERNAL ? 59
>> +#define MX23_INT_UARTAPP2_RX_DMA ? ? 60
>> +#define MX23_INT_VDAC_DETECT ? ? ? ? 61
>> +#define MX23_INT_VDD5V_DROOP ? ? ? ? 64
>> +#define MX23_INT_DCDC4P2_BO ? ? ? ? ?65
>> +
>> +#endif /* __MACH_MX23_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
>> new file mode 100644
>> index 0000000..836d807
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
>> @@ -0,0 +1,227 @@
>> +/*
>> + * Copyright (C) 2009-2010 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef __MACH_MX28_H__
>> +#define __MACH_MX28_H__
>> +
>> +#ifndef __ASSEMBLER__
>> +#include <linux/io.h>
>> +#endif
>> +
>> +/*
>> + * OCRAM
>> + */
>> +#define MX28_OCRAM_BASE_ADDR ? ? ? ? 0x00000000
>> +#define MX28_OCRAM_SIZE ? ? ? ? ? ? ? ? ? ? ?SZ_128K
>> +
>> +/*
>> + * IO
>> + */
>> +#define MX28_IO_BASE_ADDR ? ? ? ? ? ?0x80000000
>> +#define MX28_IO_SIZE ? ? ? ? ? ? ? ? SZ_1M
>> +
>> +#define MX28_ICOLL_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x000000)
>> +#define MX28_HSADC_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x002000)
>> +#define MX28_APBH_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x004000)
>> +#define MX28_PERFMON_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x006000)
>> +#define MX28_BCH_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x00a000)
>> +#define MX28_GPMI_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x00c000)
>> +#define MX28_SSP0_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x010000)
>> +#define MX28_SSP1_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x012000)
>> +#define MX28_SSP2_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x014000)
>> +#define MX28_SSP3_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x016000)
>> +#define MX28_PINCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x018000)
>> +#define MX28_DIGCTL_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x01c000)
>> +#define MX28_ETM_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x022000)
>> +#define MX28_APBX_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x024000)
>> +#define MX28_DCP_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x028000)
>> +#define MX28_PXP_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x02a000)
>> +#define MX28_OCOTP_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x02c000)
>> +#define MX28_AXI_AHB0_BASE_ADDR ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x02e000)
>> +#define MX28_LCDIF_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x030000)
>> +#define MX28_CAN0_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x032000)
>> +#define MX28_CAN1_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x034000)
>> +#define MX28_SIMDBG_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x03c000)
>> +#define MX28_SIMGPMISEL_BASE_ADDR ? ?(MX28_IO_BASE_ADDR + 0x03c200)
>> +#define MX28_SIMSSPSEL_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x03c300)
>> +#define MX28_SIMMEMSEL_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x03c400)
>> +#define MX28_GPIOMON_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x03c500)
>> +#define MX28_SIMENET_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x03c700)
>> +#define MX28_ARMJTAG_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x03c800)
>> +#define MX28_CLKCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x040000)
>> +#define MX28_SAIF0_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x042000)
>> +#define MX28_POWER_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x044000)
>> +#define MX28_SAIF1_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x046000)
>> +#define MX28_LRADC_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x050000)
>> +#define MX28_SPDIF_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x054000)
>> +#define MX28_RTC_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x056000)
>> +#define MX28_I2C0_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x058000)
>> +#define MX28_I2C1_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x05a000)
>> +#define MX28_PWM_BASE_ADDR ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x064000)
>> +#define MX28_TIMROT_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x068000)
>> +#define MX28_AUART0_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x06a000)
>> +#define MX28_AUART1_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x06c000)
>> +#define MX28_AUART2_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x06e000)
>> +#define MX28_AUART3_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x070000)
>> +#define MX28_AUART4_BASE_ADDR ? ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x072000)
>> +#define MX28_DUART_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x074000)
>> +#define MX28_USBPHY0_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x07C000)
>> +#define MX28_USBPHY1_BASE_ADDR ? ? ? ? ? ? ? (MX28_IO_BASE_ADDR + 0x07e000)
>> +#define MX28_USBCTRL0_BASE_ADDR ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x080000)
>> +#define MX28_USBCTRL1_BASE_ADDR ? ? ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x090000)
>> +#define MX28_DFLPT_BASE_ADDR ? ? ? ? (MX28_IO_BASE_ADDR + 0x0c0000)
>> +#define MX28_DRAM_BASE_ADDR ? ? ? ? ?(MX28_IO_BASE_ADDR + 0x0e0000)
>> +#define MX28_ENET_MAC0_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x0f0000)
>> +#define MX28_ENET_MAC1_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x0f4000)
>> +
>> +#define MX28_IO_P2V(x) ? ? ? ? ? ? ? ? ? ? ? MXS_IO_P2V(x)
>> +#define MX28_IO_ADDRESS(x) ? ? ? ? ? IOMEM(MX28_IO_P2V(x))
>> +
>> +/*
>> + * IRQ
>> + */
>> +#define MX28_INT_BATT_BRNOUT ? ? ? ? 0
>> +#define MX28_INT_VDDD_BRNOUT ? ? ? ? 1
>> +#define MX28_INT_VDDIO_BRNOUT ? ? ? ? ? ? ? ?2
>> +#define MX28_INT_VDDA_BRNOUT ? ? ? ? 3
>> +#define MX28_INT_VDD5V_DROOP ? ? ? ? 4
>> +#define MX28_INT_DCDC4P2_BRNOUT ? ? ? ? ? ? ?5
>> +#define MX28_INT_VDD5V ? ? ? ? ? ? ? ? ? ? ? 6
>> +#define MX28_INT_RESV7 ? ? ? ? ? ? ? ? ? ? ? 7
>> +#define MX28_INT_CAN0 ? ? ? ? ? ? ? ? ? ? ? ?8
>> +#define MX28_INT_CAN1 ? ? ? ? ? ? ? ? ? ? ? ?9
>> +#define MX28_INT_LRADC_TOUCH ? ? ? ? 10
>> +#define MX28_INT_RESV11 ? ? ? ? ? ? ? ? ? ? ?11
>> +#define MX28_INT_RESV12 ? ? ? ? ? ? ? ? ? ? ?12
>> +#define MX28_INT_HSADC ? ? ? ? ? ? ? ? ? ? ? 13
>> +#define MX28_INT_IRADC_THRESH0 ? ? ? ? ? ? ? 14
>> +#define MX28_INT_IRADC_THRESH1 ? ? ? ? ? ? ? 15
>> +#define MX28_INT_LRADC_CH0 ? ? ? ? ? 16
>> +#define MX28_INT_LRADC_CH1 ? ? ? ? ? 17
>> +#define MX28_INT_LRADC_CH2 ? ? ? ? ? 18
>> +#define MX28_INT_LRADC_CH3 ? ? ? ? ? 19
>> +#define MX28_INT_LRADC_CH4 ? ? ? ? ? 20
>> +#define MX28_INT_LRADC_CH5 ? ? ? ? ? 21
>> +#define MX28_INT_LRADC_CH6 ? ? ? ? ? 22
>> +#define MX28_INT_LRADC_CH7 ? ? ? ? ? 23
>> +#define MX28_INT_LRADC_BUTTON0 ? ? ? ? ? ? ? 24
>> +#define MX28_INT_LRADC_BUTTON1 ? ? ? ? ? ? ? 25
>> +#define MX28_INT_RESV26 ? ? ? ? ? ? ? ? ? ? ?26
>> +#define MX28_INT_PERFMON ? ? ? ? ? ? 27
>> +#define MX28_INT_RTC_1MSEC ? ? ? ? ? 28
>> +#define MX28_INT_RTC_ALARM ? ? ? ? ? 29
>> +#define MX28_INT_RESV30 ? ? ? ? ? ? ? ? ? ? ?30
>> +#define MX28_INT_COMMS ? ? ? ? ? ? ? ? ? ? ? 31
>> +#define MX28_INT_EMI_ERR ? ? ? ? ? ? 32
>> +#define MX28_INT_RESV33 ? ? ? ? ? ? ? ? ? ? ?33
>> +#define MX28_INT_RESV34 ? ? ? ? ? ? ? ? ? ? ?34
>> +#define MX28_INT_RESV35 ? ? ? ? ? ? ? ? ? ? ?35
>> +#define MX28_INT_RESV36 ? ? ? ? ? ? ? ? ? ? ?36
>> +#define MX28_INT_RESV37 ? ? ? ? ? ? ? ? ? ? ?37
>> +#define MX28_INT_LCDIF ? ? ? ? ? ? ? ? ? ? ? 38
>> +#define MX28_INT_PXP ? ? ? ? ? ? ? ? 39
>> +#define MX28_INT_RESV40 ? ? ? ? ? ? ? ? ? ? ?40
>> +#define MX28_INT_BCH ? ? ? ? ? ? ? ? 41
>> +#define MX28_INT_GPMI ? ? ? ? ? ? ? ? ? ? ? ?42
>> +#define MX28_INT_RESV43 ? ? ? ? ? ? ? ? ? ? ?43
>> +#define MX28_INT_RESV44 ? ? ? ? ? ? ? ? ? ? ?44
>> +#define MX28_INT_SPDIF_ERROR ? ? ? ? 45
>> +#define MX28_INT_RESV46 ? ? ? ? ? ? ? ? ? ? ?46
>> +#define MX28_INT_DUART ? ? ? ? ? ? ? ? ? ? ? 47
>> +#define MX28_INT_TIMER0 ? ? ? ? ? ? ? ? ? ? ?48
>> +#define MX28_INT_TIMER1 ? ? ? ? ? ? ? ? ? ? ?49
>> +#define MX28_INT_TIMER2 ? ? ? ? ? ? ? ? ? ? ?50
>> +#define MX28_INT_TIMER3 ? ? ? ? ? ? ? ? ? ? ?51
>> +#define MX28_INT_DCP_VMI ? ? ? ? ? ? 52
>> +#define MX28_INT_DCP ? ? ? ? ? ? ? ? 53
>> +#define MX28_INT_DCP_SECURE ? ? ? ? ?54
>> +#define MX28_INT_RESV55 ? ? ? ? ? ? ? ? ? ? ?55
>> +#define MX28_INT_RESV56 ? ? ? ? ? ? ? ? ? ? ?56
>> +#define MX28_INT_RESV57 ? ? ? ? ? ? ? ? ? ? ?57
>> +#define MX28_INT_SAIF1 ? ? ? ? ? ? ? ? ? ? ? 58
>> +#define MX28_INT_SAIF0 ? ? ? ? ? ? ? ? ? ? ? 59
>> +#define MX28_INT_RESV60 ? ? ? ? ? ? ? ? ? ? ?60
>> +#define MX28_INT_RESV61 ? ? ? ? ? ? ? ? ? ? ?61
>> +#define MX28_INT_RESV62 ? ? ? ? ? ? ? ? ? ? ?62
>> +#define MX28_INT_RESV63 ? ? ? ? ? ? ? ? ? ? ?63
>> +#define MX28_INT_RESV64 ? ? ? ? ? ? ? ? ? ? ?64
>> +#define MX28_INT_RESV65 ? ? ? ? ? ? ? ? ? ? ?65
>> +#define MX28_INT_SPDIF_DMA ? ? ? ? ? 66
>> +#define MX28_INT_RESV67 ? ? ? ? ? ? ? ? ? ? ?67
>> +#define MX28_INT_I2C0_DMA ? ? ? ? ? ?68
>> +#define MX28_INT_I2C1_DMA ? ? ? ? ? ?69
>> +#define MX28_INT_AUART0_RX_DMA ? ? ? ? ? ? ? 70
>> +#define MX28_INT_AUART0_TX_DMA ? ? ? ? ? ? ? 71
>> +#define MX28_INT_AUART1_RX_DMA ? ? ? ? ? ? ? 72
>> +#define MX28_INT_AUART1_TX_DMA ? ? ? ? ? ? ? 73
>> +#define MX28_INT_AUART2_RX_DMA ? ? ? ? ? ? ? 74
>> +#define MX28_INT_AUART2_TX_DMA ? ? ? ? ? ? ? 75
>> +#define MX28_INT_AUART3_RX_DMA ? ? ? ? ? ? ? 76
>> +#define MX28_INT_AUART3_TX_DMA ? ? ? ? ? ? ? 77
>> +#define MX28_INT_AUART4_RX_DMA ? ? ? ? ? ? ? 78
>> +#define MX28_INT_AUART4_TX_DMA ? ? ? ? ? ? ? 79
>> +#define MX28_INT_SAIF0_DMA ? ? ? ? ? 80
>> +#define MX28_INT_SAIF1_DMA ? ? ? ? ? 81
>> +#define MX28_INT_SSP0_DMA ? ? ? ? ? ?82
>> +#define MX28_INT_SSP1_DMA ? ? ? ? ? ?83
>> +#define MX28_INT_SSP2_DMA ? ? ? ? ? ?84
>> +#define MX28_INT_SSP3_DMA ? ? ? ? ? ?85
>> +#define MX28_INT_LCDIF_DMA ? ? ? ? ? 86
>> +#define MX28_INT_HSADC_DMA ? ? ? ? ? 87
>> +#define MX28_INT_GPMI_DMA ? ? ? ? ? ?88
>> +#define MX28_INT_DIGCTL_DEBUG_TRAP ? 89
>> +#define MX28_INT_RESV90 ? ? ? ? ? ? ? ? ? ? ?90
>> +#define MX28_INT_RESV91 ? ? ? ? ? ? ? ? ? ? ?91
>> +#define MX28_INT_USB1 ? ? ? ? ? ? ? ? ? ? ? ?92
>> +#define MX28_INT_USB0 ? ? ? ? ? ? ? ? ? ? ? ?93
>> +#define MX28_INT_USB1_WAKEUP ? ? ? ? 94
>> +#define MX28_INT_USB0_WAKEUP ? ? ? ? 95
>> +#define MX28_INT_SSP0 ? ? ? ? ? ? ? ? ? ? ? ?96
>> +#define MX28_INT_SSP1 ? ? ? ? ? ? ? ? ? ? ? ?97
>> +#define MX28_INT_SSP2 ? ? ? ? ? ? ? ? ? ? ? ?98
>> +#define MX28_INT_SSP3 ? ? ? ? ? ? ? ? ? ? ? ?99
>> +#define MX28_INT_ENET_SWI ? ? ? ? ? ?100
>> +#define MX28_INT_ENET_MAC0 ? ? ? ? ? 101
>> +#define MX28_INT_ENET_MAC1 ? ? ? ? ? 102
>> +#define MX28_INT_ENET_MAC0_1588 ? ? ? ? ? ? ?103
>> +#define MX28_INT_ENET_MAC1_1588 ? ? ? ? ? ? ?104
>> +#define MX28_INT_RESV105 ? ? ? ? ? ? 105
>> +#define MX28_INT_RESV106 ? ? ? ? ? ? 106
>> +#define MX28_INT_RESV107 ? ? ? ? ? ? 107
>> +#define MX28_INT_RESV108 ? ? ? ? ? ? 108
>> +#define MX28_INT_RESV109 ? ? ? ? ? ? 109
>> +#define MX28_INT_I2C1_ERROR ? ? ? ? ?110
>> +#define MX28_INT_I2C0_ERROR ? ? ? ? ?111
>> +#define MX28_INT_AUART0 ? ? ? ? ? ? ? ? ? ? ?112
>> +#define MX28_INT_AUART1 ? ? ? ? ? ? ? ? ? ? ?113
>> +#define MX28_INT_AUART2 ? ? ? ? ? ? ? ? ? ? ?114
>> +#define MX28_INT_AUART3 ? ? ? ? ? ? ? ? ? ? ?115
>> +#define MX28_INT_AUART4 ? ? ? ? ? ? ? ? ? ? ?116
>> +#define MX28_INT_RESV117 ? ? ? ? ? ? 117
>> +#define MX28_INT_RESV118 ? ? ? ? ? ? 118
>> +#define MX28_INT_RESV119 ? ? ? ? ? ? 119
>> +#define MX28_INT_RESV120 ? ? ? ? ? ? 120
>> +#define MX28_INT_RESV121 ? ? ? ? ? ? 121
>> +#define MX28_INT_RESV122 ? ? ? ? ? ? 122
>> +#define MX28_INT_GPIO4 ? ? ? ? ? ? ? ? ? ? ? 123
>> +#define MX28_INT_GPIO3 ? ? ? ? ? ? ? ? ? ? ? 124
>> +#define MX28_INT_GPIO2 ? ? ? ? ? ? ? ? ? ? ? 125
>> +#define MX28_INT_GPIO1 ? ? ? ? ? ? ? ? ? ? ? 126
>> +#define MX28_INT_GPIO0 ? ? ? ? ? ? ? ? ? ? ? 127
>> +
>> +#endif /* __MACH_MX28_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
>> new file mode 100644
>> index 0000000..128c114
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
>> @@ -0,0 +1,60 @@
>> +/*
>> + * Copyright (C) 2009-2010 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#ifndef __MACH_MXS_H__
>> +#define __MACH_MXS_H__
>> +
>> +#define MXS_SET_ADDR ? ? ? ? 0x4
>> +#define MXS_CLR_ADDR ? ? ? ? 0x8
>> +#define MXS_TOG_ADDR ? ? ? ? 0xc
>> +
>> +/*
>> + * MXS CPU types
>> + */
>> +#define MXS_CPU_MX23 ? ? ? ? 23
>> +#define MXS_CPU_MX28 ? ? ? ? 28
>> +
>> +#ifndef __ASSEMBLY__
>> +extern unsigned int __mxs_cpu_type;
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX23
>> +# ifdef mxs_cpu_type
>> +# ?undef mxs_cpu_type
>> +# ?define mxs_cpu_type __mxs_cpu_type
>> +# else
>> +# ?define mxs_cpu_type MXS_CPU_MX23
>> +# endif
>> +# define cpu_is_mx23() ? ? ? ? ? ? ? (mxs_cpu_type == MXS_CPU_MX23)
>> +#else
>> +# define cpu_is_mx23() ? ? ? ? ? ? ? (0)
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX28
>> +# ifdef mxs_cpu_type
>> +# ?undef mxs_cpu_type
>> +# ?define mxs_cpu_type __mxs_cpu_type
>> +# else
>> +# ?define mxs_cpu_type MXS_CPU_MX28
>> +# endif
>> +# define cpu_is_mx28() ? ? ? ? ? ? ? (mxs_cpu_type == MXS_CPU_MX28)
>> +#else
>> +# define cpu_is_mx28() ? ? ? ? ? ? ? (0)
>> +#endif
> For imx I wondered if this is overkill. ?When I started mainlining
> ns9xxx I just did:
>
> ? ? ? ?#define cpu_is_xyz() (machine_is_abc() || ...)
>
> It's much easier and the generated code probably is not much worse.
> (Better try to reduce the number of usages of these macros.)
>
> (Note, if you're convinced this is good, go ahead, just my personal
> opinion.)
>
Your suggestion make sense to me.  I will take it.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
  2010-11-26 11:32         ` Uwe Kleine-König
  2010-11-26 12:53           ` Lothar Waßmann
@ 2010-11-29  9:25           ` Lothar Waßmann
  2010-11-29  9:58             ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-29  9:25 UTC (permalink / raw)
  To: linux-arm-kernel

arch_reset() may be called from interrupt context (e.g. induced by
SYSRQ-B), thus clk_get() and clk_enable() must not be called from
within arch_reset(). Move these calls to mxc_arch_reset_init().

Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
---
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index c3972c5..9b02251 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -53,11 +53,6 @@ void arch_reset(char mode, const char *cmd)
 	if (cpu_is_mx1()) {
 		wcr_enable = (1 << 0);
 	} else {
-		struct clk *clk;
-
-		clk = clk_get_sys("imx-wdt.0", NULL);
-		if (!IS_ERR(clk))
-			clk_enable(clk);
 		wcr_enable = (1 << 2);
 	}
 
@@ -78,5 +73,14 @@ void arch_reset(char mode, const char *cmd)
 
 void mxc_arch_reset_init(void __iomem *base)
 {
+	struct clk *clk;
+
 	wdog_base = base;
+
+	if (cpu_is_mx1())
+		return;
+
+	clk = clk_get_sys("imx-wdt.0", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
 }


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
  2010-11-29  9:25           ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
@ 2010-11-29  9:58             ` Uwe Kleine-König
  2010-12-06 16:13               ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-29  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Lothar,

On Mon, Nov 29, 2010 at 10:25:34AM +0100, Lothar Wa?mann wrote:
> arch_reset() may be called from interrupt context (e.g. induced by
> SYSRQ-B), thus clk_get() and clk_enable() must not be called from
> within arch_reset(). Move these calls to mxc_arch_reset_init().
I wonder if SYSRQ-B is the only way to trigger that.  And if yes if that
could be "fixed" to allow sleeping?!

> Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
> ---
> diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
> index c3972c5..9b02251 100644
> --- a/arch/arm/plat-mxc/system.c
> +++ b/arch/arm/plat-mxc/system.c
> @@ -53,11 +53,6 @@ void arch_reset(char mode, const char *cmd)
>  	if (cpu_is_mx1()) {
>  		wcr_enable = (1 << 0);
>  	} else {
> -		struct clk *clk;
> -
> -		clk = clk_get_sys("imx-wdt.0", NULL);
> -		if (!IS_ERR(clk))
> -			clk_enable(clk);
>  		wcr_enable = (1 << 2);
>  	}
>  
> @@ -78,5 +73,14 @@ void arch_reset(char mode, const char *cmd)
>  
>  void mxc_arch_reset_init(void __iomem *base)
>  {
> +	struct clk *clk;
> +
>  	wdog_base = base;
> +
> +	if (cpu_is_mx1())
> +		return;
> +
> +	clk = clk_get_sys("imx-wdt.0", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
>  }
Unrelated to this patch, I wonder why this isn't named "imx2-wdt.0".  I
just checked, the driver (drivers/watchdog/imx2_wdt.c) uses clk_get_sys,
too.  IMHO we should rename that.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 01/15] ARM: mxs: Add core definitions
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (14 preceding siblings ...)
  2010-11-26  6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-11-30  9:21   ` Uwe Kleine-König
  2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
                   ` (30 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Add core definitions for MXS-based SoC MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
 - Simplify MXS_IO_P2V_MODULE definition in hardware.h
 - Remove unnecessary inclusion protection from hardware.h
 - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx

 arch/arm/mach-mxs/include/mach/hardware.h |   55 +++++++
 arch/arm/mach-mxs/include/mach/irqs.h     |   32 ++++
 arch/arm/mach-mxs/include/mach/memory.h   |   24 +++
 arch/arm/mach-mxs/include/mach/mx23.h     |  147 +++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mx28.h     |  227 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mxs.h      |   43 ++++++
 6 files changed, 528 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h

diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..9e757e0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr)	(addr)
+#else
+#define IOMEM(addr)	((void __force __iomem *)(addr))
+#endif
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
+ *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
+ */
+#define MXS_IO_P2V(x)	(0xf4000000 +					\
+			(((x) & 0x80000000) >> 6) +			\
+			(((x) & 0x000fffff)))
+
+
+#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type)	{				\
+	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
+	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
+	.length = soc ## _ ## name ## _SIZE,				\
+	.type = _type,							\
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS	128
+
+#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS		(32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS		16
+
+#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET		UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..27a11ee
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR		0x00000000
+#define MX23_OCRAM_SIZE			SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR		0x80000000
+#define MX23_IO_SIZE			SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART			0
+#define MX23_INT_COMMS_RX		1
+#define MX23_INT_COMMS_TX		1
+#define MX23_INT_SSP2_ERROR		2
+#define MX23_INT_VDD5V			3
+#define MX23_INT_HEADPHONE_SHORT	4
+#define MX23_INT_DAC_DMA		5
+#define MX23_INT_DAC_ERROR		6
+#define MX23_INT_ADC_DMA		7
+#define MX23_INT_ADC_ERROR		8
+#define MX23_INT_SPDIF_DMA		9
+#define MX23_INT_SAIF2_DMA		9
+#define MX23_INT_SPDIF_ERROR		10
+#define MX23_INT_SAIF1_IRQ		10
+#define MX23_INT_SAIF2_IRQ		10
+#define MX23_INT_USB_CTRL		11
+#define MX23_INT_USB_WAKEUP		12
+#define MX23_INT_GPMI_DMA		13
+#define MX23_INT_SSP1_DMA		14
+#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_GPIO0			16
+#define MX23_INT_GPIO1			17
+#define MX23_INT_GPIO2			18
+#define MX23_INT_SAIF1_DMA		19
+#define MX23_INT_SSP2_DMA		20
+#define MX23_INT_ECC8_IRQ		21
+#define MX23_INT_RTC_ALARM		22
+#define MX23_INT_UARTAPP_TX_DMA		23
+#define MX23_INT_UARTAPP_INTERNAL	24
+#define MX23_INT_UARTAPP_RX_DMA		25
+#define MX23_INT_I2C_DMA		26
+#define MX23_INT_I2C_ERROR		27
+#define MX23_INT_TIMER0			28
+#define MX23_INT_TIMER1			29
+#define MX23_INT_TIMER2			30
+#define MX23_INT_TIMER3			31
+#define MX23_INT_BATT_BRNOUT		32
+#define MX23_INT_VDDD_BRNOUT		33
+#define MX23_INT_VDDIO_BRNOUT		34
+#define MX23_INT_VDD18_BRNOUT		35
+#define MX23_INT_TOUCH_DETECT		36
+#define MX23_INT_LRADC_CH0		37
+#define MX23_INT_LRADC_CH1		38
+#define MX23_INT_LRADC_CH2		39
+#define MX23_INT_LRADC_CH3		40
+#define MX23_INT_LRADC_CH4		41
+#define MX23_INT_LRADC_CH5		42
+#define MX23_INT_LRADC_CH6		43
+#define MX23_INT_LRADC_CH7		44
+#define MX23_INT_LCDIF_DMA		45
+#define MX23_INT_LCDIF_ERROR		46
+#define MX23_INT_DIGCTL_DEBUG_TRAP	47
+#define MX23_INT_RTC_1MSEC		48
+#define MX23_INT_DRI_DMA		49
+#define MX23_INT_DRI_ATTENTION		50
+#define MX23_INT_GPMI_ATTENTION		51
+#define MX23_INT_IR			52
+#define MX23_INT_DCP_VMI		53
+#define MX23_INT_DCP			54
+#define MX23_INT_BCH			56
+#define MX23_INT_PXP			57
+#define MX23_INT_UARTAPP2_TX_DMA	58
+#define MX23_INT_UARTAPP2_INTERNAL	59
+#define MX23_INT_UARTAPP2_RX_DMA	60
+#define MX23_INT_VDAC_DETECT		61
+#define MX23_INT_VDD5V_DROOP		64
+#define MX23_INT_DCDC4P2_BO		65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..836d807
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR		0x00000000
+#define MX28_OCRAM_SIZE			SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR		0x80000000
+#define MX28_IO_SIZE			SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT		0
+#define MX28_INT_VDDD_BRNOUT		1
+#define MX28_INT_VDDIO_BRNOUT		2
+#define MX28_INT_VDDA_BRNOUT		3
+#define MX28_INT_VDD5V_DROOP		4
+#define MX28_INT_DCDC4P2_BRNOUT		5
+#define MX28_INT_VDD5V			6
+#define MX28_INT_RESV7			7
+#define MX28_INT_CAN0			8
+#define MX28_INT_CAN1			9
+#define MX28_INT_LRADC_TOUCH		10
+#define MX28_INT_RESV11			11
+#define MX28_INT_RESV12			12
+#define MX28_INT_HSADC			13
+#define MX28_INT_IRADC_THRESH0		14
+#define MX28_INT_IRADC_THRESH1		15
+#define MX28_INT_LRADC_CH0		16
+#define MX28_INT_LRADC_CH1		17
+#define MX28_INT_LRADC_CH2		18
+#define MX28_INT_LRADC_CH3		19
+#define MX28_INT_LRADC_CH4		20
+#define MX28_INT_LRADC_CH5		21
+#define MX28_INT_LRADC_CH6		22
+#define MX28_INT_LRADC_CH7		23
+#define MX28_INT_LRADC_BUTTON0		24
+#define MX28_INT_LRADC_BUTTON1		25
+#define MX28_INT_RESV26			26
+#define MX28_INT_PERFMON		27
+#define MX28_INT_RTC_1MSEC		28
+#define MX28_INT_RTC_ALARM		29
+#define MX28_INT_RESV30			30
+#define MX28_INT_COMMS			31
+#define MX28_INT_EMI_ERR		32
+#define MX28_INT_RESV33			33
+#define MX28_INT_RESV34			34
+#define MX28_INT_RESV35			35
+#define MX28_INT_RESV36			36
+#define MX28_INT_RESV37			37
+#define MX28_INT_LCDIF			38
+#define MX28_INT_PXP			39
+#define MX28_INT_RESV40			40
+#define MX28_INT_BCH			41
+#define MX28_INT_GPMI			42
+#define MX28_INT_RESV43			43
+#define MX28_INT_RESV44			44
+#define MX28_INT_SPDIF_ERROR		45
+#define MX28_INT_RESV46			46
+#define MX28_INT_DUART			47
+#define MX28_INT_TIMER0			48
+#define MX28_INT_TIMER1			49
+#define MX28_INT_TIMER2			50
+#define MX28_INT_TIMER3			51
+#define MX28_INT_DCP_VMI		52
+#define MX28_INT_DCP			53
+#define MX28_INT_DCP_SECURE		54
+#define MX28_INT_RESV55			55
+#define MX28_INT_RESV56			56
+#define MX28_INT_RESV57			57
+#define MX28_INT_SAIF1			58
+#define MX28_INT_SAIF0			59
+#define MX28_INT_RESV60			60
+#define MX28_INT_RESV61			61
+#define MX28_INT_RESV62			62
+#define MX28_INT_RESV63			63
+#define MX28_INT_RESV64			64
+#define MX28_INT_RESV65			65
+#define MX28_INT_SPDIF_DMA		66
+#define MX28_INT_RESV67			67
+#define MX28_INT_I2C0_DMA		68
+#define MX28_INT_I2C1_DMA		69
+#define MX28_INT_AUART0_RX_DMA		70
+#define MX28_INT_AUART0_TX_DMA		71
+#define MX28_INT_AUART1_RX_DMA		72
+#define MX28_INT_AUART1_TX_DMA		73
+#define MX28_INT_AUART2_RX_DMA		74
+#define MX28_INT_AUART2_TX_DMA		75
+#define MX28_INT_AUART3_RX_DMA		76
+#define MX28_INT_AUART3_TX_DMA		77
+#define MX28_INT_AUART4_RX_DMA		78
+#define MX28_INT_AUART4_TX_DMA		79
+#define MX28_INT_SAIF0_DMA		80
+#define MX28_INT_SAIF1_DMA		81
+#define MX28_INT_SSP0_DMA		82
+#define MX28_INT_SSP1_DMA		83
+#define MX28_INT_SSP2_DMA		84
+#define MX28_INT_SSP3_DMA		85
+#define MX28_INT_LCDIF_DMA		86
+#define MX28_INT_HSADC_DMA		87
+#define MX28_INT_GPMI_DMA		88
+#define MX28_INT_DIGCTL_DEBUG_TRAP	89
+#define MX28_INT_RESV90			90
+#define MX28_INT_RESV91			91
+#define MX28_INT_USB1			92
+#define MX28_INT_USB0			93
+#define MX28_INT_USB1_WAKEUP		94
+#define MX28_INT_USB0_WAKEUP		95
+#define MX28_INT_SSP0			96
+#define MX28_INT_SSP1			97
+#define MX28_INT_SSP2			98
+#define MX28_INT_SSP3			99
+#define MX28_INT_ENET_SWI		100
+#define MX28_INT_ENET_MAC0		101
+#define MX28_INT_ENET_MAC1		102
+#define MX28_INT_ENET_MAC0_1588		103
+#define MX28_INT_ENET_MAC1_1588		104
+#define MX28_INT_RESV105		105
+#define MX28_INT_RESV106		106
+#define MX28_INT_RESV107		107
+#define MX28_INT_RESV108		108
+#define MX28_INT_RESV109		109
+#define MX28_INT_I2C1_ERROR		110
+#define MX28_INT_I2C0_ERROR		111
+#define MX28_INT_AUART0			112
+#define MX28_INT_AUART1			113
+#define MX28_INT_AUART2			114
+#define MX28_INT_AUART3			115
+#define MX28_INT_AUART4			116
+#define MX28_INT_RESV117		117
+#define MX28_INT_RESV118		118
+#define MX28_INT_RESV119		119
+#define MX28_INT_RESV120		120
+#define MX28_INT_RESV121		121
+#define MX28_INT_RESV122		122
+#define MX28_INT_GPIO4			123
+#define MX28_INT_GPIO3			124
+#define MX28_INT_GPIO2			125
+#define MX28_INT_GPIO1			126
+#define MX28_INT_GPIO0			127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..b691c34
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+
+#define MXS_SET_ADDR		0x4
+#define MXS_CLR_ADDR		0x8
+#define MXS_TOG_ADDR		0xc
+
+/*
+ * MXS CPU types
+ */
+#ifdef CONFIG_SOC_IMX23
+# define cpu_is_mx23()		(machine_is_mx23evk())
+#else
+# define cpu_is_mx23()		(0)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# define cpu_is_mx28()		(machine_is_mx28evk())
+#else
+# define cpu_is_mx28()		(0)
+#endif
+
+#endif /* __MACH_MXS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 02/15] ARM: mxs: Add helper definition and function
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (15 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
                   ` (29 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Add helper definition and function for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove cpu.c and reference to mxs_set_cpu_type() from common.h

 arch/arm/mach-mxs/include/mach/common.h  |   32 ++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/io.h      |   22 ++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/timex.h   |   21 +++++++++++++++++++
 arch/arm/mach-mxs/include/mach/vmalloc.h |   22 ++++++++++++++++++++
 4 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/common.h
 create mode 100644 arch/arm/mach-mxs/include/mach/io.h
 create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
 create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h

diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..dca0460
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_arch_reset_init(void __iomem *);
+extern void mxs_timer_init(struct clk *, void __iomem *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void __iomem *);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a)		__typesafe_io(a)
+
+#define __mem_pci(a)	(a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ * Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE		32000	/* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2000 Russell King.
+ *  Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END       0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (16 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-11-30 10:25   ` Uwe Kleine-König
  2010-12-02  9:40   ` Uwe Kleine-König
  2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
                   ` (28 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

 - The mxs wdog is implemented in RTC block.
 - There is a generic software reset routine for most modules on mxs.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()

 arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
 arch/arm/mach-mxs/system.c              |  152 +++++++++++++++++++++++++++++++
 2 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/system.h
 create mode 100644 arch/arm/mach-mxs/system.c

diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..7ad73bf
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG	0x50
+#define MXS_WATCHDOG_EN		(1 << 4)
+
+#define MXS_MODULE_CLKGATE	(1 << 30)
+#define MXS_MODULE_SFTRST	(1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+	/* Set wdog count */
+	__raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
+
+	/* Assert SRS signal */
+	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+	/* Wait for reset to assert... */
+	mdelay(500);
+
+	pr_err("Watchdog reset failed to assert reset\n");
+
+	/* Delay to allow the serial port to show the message */
+	mdelay(50);
+
+	/* We'll take a jump through zero as a poor second */
+	cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+	struct clk *clk;
+
+	wdog_base = base;
+
+	clk = clk_get_sys("rtc", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+	u32 val;
+	int timeout;
+
+	/*
+	 * The process of software reset of IP block is done
+	 * in several steps:
+	 *
+	 * 1) clear SFTRST and wait it cleared;
+	 * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
+	 * 3) clear SFTRST and wait it cleared;
+	 * 4) clear CLKGATE and wait it cleared.
+	 */
+
+	/* Clear SFTRST */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/*
+	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
+	 * recommends to wait 1us.
+	 */
+	udelay(1);
+	/* Poll SFTRST cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear CLKGATE */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_CLKGATE;
+	__raw_writel(val, reset_addr);
+	/* Set SFTRST to reset the block */
+	val = __raw_readl(reset_addr);
+	val |= MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll CLKGATE set */
+	timeout = 0x400;
+	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear SFTRST */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_SFTRST;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll SFTRST cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	/* Clear CLKGATE */
+	val = __raw_readl(reset_addr);
+	val &= ~MXS_MODULE_CLKGATE;
+	__raw_writel(val, reset_addr);
+	/* Wait 1us */
+	udelay(1);
+	/* Poll CLKGATE cleared */
+	timeout = 0x400;
+	while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
+		/* nothing */;
+	if (!timeout)
+		goto error;
+
+	return 0;
+
+error:
+	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+	return -ETIMEDOUT;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 06/15] ARM: mxs: Add timer support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (17 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
                   ` (27 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.

As the result, we need two instances of timers with v1 for better
implementation, one for next_event and another for get_cycles.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 - Fix a bug in timrot_set_next_event(). It should read
   HW_TIMROT_RUNNING_COUNTn to get the current counts.

 arch/arm/mach-mxs/timer.c |  285 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 285 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/timer.c

diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..b07e2e9
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,285 @@
+/*
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for next_event and another for get_cycles. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1()	(cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL			0x00
+#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n)		(0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE		(1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT		0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL	(timrot_is_v1() ? 0x8 : 0xb)
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+	if (timrot_is_v1())
+		return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+				& 0xffff0000) >> 16);
+	else
+		return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrot_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	unsigned long match;
+	int ret;
+
+	/* timrot decrements the count */
+	if (timrot_is_v1()) {
+		__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+		ret = 0;
+	} else {
+		match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
+				- evt;
+		__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+		ret = (int)(match - __raw_readl(timer_base +
+				HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+	}
+
+	return ret;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_mxs;
+
+	timrot_irq_acknowledge();
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+	.name		= "MXS Timer Tick",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	unsigned long flags;
+
+	/*
+	 * The timer interrupt generation is disabled at least
+	 * for enough time to call mxs_set_next_event()
+	 */
+	local_irq_save(flags);
+
+	/* Disable interrupt in timer module */
+	timrot_irq_disable();
+
+	if (mode != clockevent_mode) {
+		/* Set event time into far-far future */
+		__raw_writel(__raw_readl(timer_base +
+				HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+				timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+		/* Clear pending interrupt */
+		timrot_irq_acknowledge();
+	}
+
+#ifdef DEBUG
+	printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+		clock_event_mode_label[clockevent_mode],
+		clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+	/* Remember timer mode */
+	clockevent_mode = mode;
+	local_irq_restore(flags);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+				"supported for MXS-based\n");
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+	/*
+	 * Do not put overhead of interrupt enable/disable into
+	 * mxs_set_next_event(), the core has about 4 minutes
+	 * to call mxs_set_next_event() or shutdown clock after
+	 * mode switching
+	 */
+		local_irq_save(flags);
+		timrot_irq_enable();
+		local_irq_restore(flags);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_mxs = {
+	.name		= "mxs_timrot",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_mode	= mxs_set_mode,
+	.set_next_event	= timrot_set_next_event,
+	.rating		= 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+	clockevent_mxs.cpumask = cpumask_of(0);
+	if (timrot_is_v1()) {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xf, &clockevent_mxs);
+	} else {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xff, &clockevent_mxs);
+	}
+
+	clockevents_register_device(&clockevent_mxs);
+
+	return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+	.name 		= "mxs_timer",
+	.rating		= 200,
+	.read		= timrot_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift 		= 10,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	if (timrot_is_v1())
+		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+	clocksource_register(&clocksource_mxs);
+
+	return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+				void __iomem *base, int irq)
+{
+	clk_enable(timer_clk);
+
+	timer_base = base;
+
+	/*
+	 * Initialize timers to a known state
+	 */
+	mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+	if (timrot_is_v1()) {
+		/* timer0 is for next_event */
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_UPDATE |
+			BM_TIMROT_TIMCTRLn_IRQ_EN,
+			base + HW_TIMROT_TIMCTRLn(0));
+		/* timer1 is for get_cycles */
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_RELOAD,
+			base + HW_TIMROT_TIMCTRLn(1));
+		__raw_writel(0xffff, timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
+
+	} else {
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_IRQ_EN |
+			BM_TIMROT_TIMCTRLn_MATCH_MODE,
+			timer_base + HW_TIMROT_TIMCTRLn(0));
+	}
+
+	/* init and register the timer to the framework */
+	mxs_clocksource_init(timer_clk);
+	mxs_clockevent_init(timer_clk);
+
+	/* Make irqs happen */
+	setup_irq(irq, &mxs_timer_irq);
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 10/15] ARM: mxs: Add static memory mapping
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (18 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
                   ` (26 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Create static memory mapping for MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove the calls to mxs_set_cpu_type()

 arch/arm/mach-mxs/mm-mx23.c |   47 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/mm-mx28.c |   47 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mm-mx23.c
 create mode 100644 arch/arm/mach-mxs/mm-mx28.c

diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..d254064
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+	mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX23, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx23_map_io(void)
+{
+	mxs_iomux_init(MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR));
+	mxs_arch_reset_init(MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR));
+	iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+	icoll_init_irq(MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR));
+	mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..38c27bc
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+	mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX28, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx28_map_io(void)
+{
+	mxs_iomux_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+	mxs_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+	iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+	icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+	mx28_register_gpios();
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (19 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
  2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
                   ` (25 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove cpu.o from arch/arm/mach-mxs/Makefile

 arch/arm/Kconfig                   |   10 ++++++++++
 arch/arm/Makefile                  |    1 +
 arch/arm/mach-mxs/Kconfig          |   34 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/Makefile         |   14 ++++++++++++++
 arch/arm/mach-mxs/Makefile.boot    |    3 +++
 arch/arm/mach-mxs/devices/Kconfig  |    5 +++++
 arch/arm/mach-mxs/devices/Makefile |    2 ++
 7 files changed, 69 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/Kconfig
 create mode 100644 arch/arm/mach-mxs/Makefile
 create mode 100644 arch/arm/mach-mxs/Makefile.boot
 create mode 100644 arch/arm/mach-mxs/devices/Kconfig
 create mode 100644 arch/arm/mach-mxs/devices/Makefile

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..b0a5130 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
+config ARCH_MXS
+	bool "Freescale MXS-based"
+	select GENERIC_CLOCKEVENTS
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLKDEV
+	help
+	  Support for Freescale MXS-based family of processors
+
 config ARCH_STMP3XXX
 	bool "Freescale STMP3xxx"
 	select CPU_ARM926T
@@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
 
 source "arch/arm/mach-mmp/Kconfig"
 
+source "arch/arm/mach-mxs/Kconfig"
+
 source "arch/arm/mach-realview/Kconfig"
 
 source "arch/arm/mach-sa1100/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25)		:= imx
 machine-$(CONFIG_ARCH_MX3)		:= mx3
 machine-$(CONFIG_ARCH_MX5)		:= mx5
 machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
+machine-$(CONFIG_ARCH_MXS)		:= mxs
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+	bool
+	select CPU_ARM926T
+
+config SOC_IMX28
+	bool
+	select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+	bool "Support MX23EVK Platform"
+	select SOC_IMX23
+	select MXS_HAVE_PLATFORM_DUART
+	default y
+	help
+	  Include support for MX23EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+	bool "Support MX28EVK Platform"
+	select SOC_IMX28
+	select MXS_HAVE_PLATFORM_DUART
+	select MXS_HAVE_PLATFORM_FEC
+	default y
+	help
+	  Include support for MX28EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..8fcb683
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..1568ad4
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x40008000
+params_phys-y	:= 0x40000100
+initrd_phys-y	:= 0x40800000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+	bool
+
+config MXS_HAVE_PLATFORM_FEC
+	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 01/15] ARM: mxs: Add core definitions
  2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-30  9:21   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Mon, Nov 29, 2010 at 07:59:11PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
>  - Simplify MXS_IO_P2V_MODULE definition in hardware.h
>  - Remove unnecessary inclusion protection from hardware.h
>  - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
> 
>  arch/arm/mach-mxs/include/mach/hardware.h |   55 +++++++
>  arch/arm/mach-mxs/include/mach/irqs.h     |   32 ++++
>  arch/arm/mach-mxs/include/mach/memory.h   |   24 +++
>  arch/arm/mach-mxs/include/mach/mx23.h     |  147 +++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mx28.h     |  227 +++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mxs.h      |   43 ++++++
>  6 files changed, 528 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..9e757e0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA  02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr)	(addr)
> +#else
> +#define IOMEM(addr)	((void __force __iomem *)(addr))
> +#endif
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
> + *
> + *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
> + *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
> + */
> +#define MXS_IO_P2V(x)	(0xf4000000 +					\
> +			(((x) & 0x80000000) >> 6) +			\
> +			(((x) & 0x000fffff)))
The comment doesn't match the function.

> +
> +
> +#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
> +
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type)	{				\
> +	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
> +	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
> +	.length = soc ## _ ## name ## _SIZE,				\
> +	.type = _type,							\
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + *  Copyright 2004-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 version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS	128
> +
> +#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS		(32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes.  Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS		16
> +
> +#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET		UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..27a11ee
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR		0x00000000
> +#define MX23_OCRAM_SIZE			SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR		0x80000000
> +#define MX23_IO_SIZE			SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
I'd prefer to have these sorted consistently.  Either sort by name or
address, but not a mixure of both.

> +#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART			0
> +#define MX23_INT_COMMS_RX		1
> +#define MX23_INT_COMMS_TX		1
> +#define MX23_INT_SSP2_ERROR		2
> +#define MX23_INT_VDD5V			3
> +#define MX23_INT_HEADPHONE_SHORT	4
> +#define MX23_INT_DAC_DMA		5
> +#define MX23_INT_DAC_ERROR		6
> +#define MX23_INT_ADC_DMA		7
> +#define MX23_INT_ADC_ERROR		8
> +#define MX23_INT_SPDIF_DMA		9
> +#define MX23_INT_SAIF2_DMA		9
> +#define MX23_INT_SPDIF_ERROR		10
> +#define MX23_INT_SAIF1_IRQ		10
> +#define MX23_INT_SAIF2_IRQ		10
> +#define MX23_INT_USB_CTRL		11
> +#define MX23_INT_USB_WAKEUP		12
> +#define MX23_INT_GPMI_DMA		13
> +#define MX23_INT_SSP1_DMA		14
> +#define MX23_INT_SSP_ERROR		15
> +#define MX23_INT_GPIO0			16
> +#define MX23_INT_GPIO1			17
> +#define MX23_INT_GPIO2			18
> +#define MX23_INT_SAIF1_DMA		19
> +#define MX23_INT_SSP2_DMA		20
> +#define MX23_INT_ECC8_IRQ		21
> +#define MX23_INT_RTC_ALARM		22
> +#define MX23_INT_UARTAPP_TX_DMA		23
> +#define MX23_INT_UARTAPP_INTERNAL	24
> +#define MX23_INT_UARTAPP_RX_DMA		25
> +#define MX23_INT_I2C_DMA		26
> +#define MX23_INT_I2C_ERROR		27
> +#define MX23_INT_TIMER0			28
> +#define MX23_INT_TIMER1			29
> +#define MX23_INT_TIMER2			30
> +#define MX23_INT_TIMER3			31
> +#define MX23_INT_BATT_BRNOUT		32
> +#define MX23_INT_VDDD_BRNOUT		33
> +#define MX23_INT_VDDIO_BRNOUT		34
> +#define MX23_INT_VDD18_BRNOUT		35
> +#define MX23_INT_TOUCH_DETECT		36
> +#define MX23_INT_LRADC_CH0		37
> +#define MX23_INT_LRADC_CH1		38
> +#define MX23_INT_LRADC_CH2		39
> +#define MX23_INT_LRADC_CH3		40
> +#define MX23_INT_LRADC_CH4		41
> +#define MX23_INT_LRADC_CH5		42
> +#define MX23_INT_LRADC_CH6		43
> +#define MX23_INT_LRADC_CH7		44
> +#define MX23_INT_LCDIF_DMA		45
> +#define MX23_INT_LCDIF_ERROR		46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP	47
> +#define MX23_INT_RTC_1MSEC		48
> +#define MX23_INT_DRI_DMA		49
> +#define MX23_INT_DRI_ATTENTION		50
> +#define MX23_INT_GPMI_ATTENTION		51
> +#define MX23_INT_IR			52
> +#define MX23_INT_DCP_VMI		53
> +#define MX23_INT_DCP			54
> +#define MX23_INT_BCH			56
> +#define MX23_INT_PXP			57
> +#define MX23_INT_UARTAPP2_TX_DMA	58
> +#define MX23_INT_UARTAPP2_INTERNAL	59
> +#define MX23_INT_UARTAPP2_RX_DMA	60
> +#define MX23_INT_VDAC_DETECT		61
> +#define MX23_INT_VDD5V_DROOP		64
> +#define MX23_INT_DCDC4P2_BO		65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..836d807
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,227 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR		0x00000000
> +#define MX28_OCRAM_SIZE			SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR		0x80000000
> +#define MX28_IO_SIZE			SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT		0
> +#define MX28_INT_VDDD_BRNOUT		1
> +#define MX28_INT_VDDIO_BRNOUT		2
> +#define MX28_INT_VDDA_BRNOUT		3
> +#define MX28_INT_VDD5V_DROOP		4
> +#define MX28_INT_DCDC4P2_BRNOUT		5
> +#define MX28_INT_VDD5V			6
> +#define MX28_INT_RESV7			7
> +#define MX28_INT_CAN0			8
> +#define MX28_INT_CAN1			9
> +#define MX28_INT_LRADC_TOUCH		10
> +#define MX28_INT_RESV11			11
> +#define MX28_INT_RESV12			12
> +#define MX28_INT_HSADC			13
> +#define MX28_INT_IRADC_THRESH0		14
> +#define MX28_INT_IRADC_THRESH1		15
> +#define MX28_INT_LRADC_CH0		16
> +#define MX28_INT_LRADC_CH1		17
> +#define MX28_INT_LRADC_CH2		18
> +#define MX28_INT_LRADC_CH3		19
> +#define MX28_INT_LRADC_CH4		20
> +#define MX28_INT_LRADC_CH5		21
> +#define MX28_INT_LRADC_CH6		22
> +#define MX28_INT_LRADC_CH7		23
> +#define MX28_INT_LRADC_BUTTON0		24
> +#define MX28_INT_LRADC_BUTTON1		25
> +#define MX28_INT_RESV26			26
> +#define MX28_INT_PERFMON		27
> +#define MX28_INT_RTC_1MSEC		28
> +#define MX28_INT_RTC_ALARM		29
> +#define MX28_INT_RESV30			30
> +#define MX28_INT_COMMS			31
> +#define MX28_INT_EMI_ERR		32
> +#define MX28_INT_RESV33			33
> +#define MX28_INT_RESV34			34
> +#define MX28_INT_RESV35			35
> +#define MX28_INT_RESV36			36
> +#define MX28_INT_RESV37			37
> +#define MX28_INT_LCDIF			38
> +#define MX28_INT_PXP			39
> +#define MX28_INT_RESV40			40
> +#define MX28_INT_BCH			41
> +#define MX28_INT_GPMI			42
> +#define MX28_INT_RESV43			43
> +#define MX28_INT_RESV44			44
> +#define MX28_INT_SPDIF_ERROR		45
> +#define MX28_INT_RESV46			46
> +#define MX28_INT_DUART			47
> +#define MX28_INT_TIMER0			48
> +#define MX28_INT_TIMER1			49
> +#define MX28_INT_TIMER2			50
> +#define MX28_INT_TIMER3			51
> +#define MX28_INT_DCP_VMI		52
> +#define MX28_INT_DCP			53
> +#define MX28_INT_DCP_SECURE		54
> +#define MX28_INT_RESV55			55
> +#define MX28_INT_RESV56			56
> +#define MX28_INT_RESV57			57
> +#define MX28_INT_SAIF1			58
> +#define MX28_INT_SAIF0			59
> +#define MX28_INT_RESV60			60
> +#define MX28_INT_RESV61			61
> +#define MX28_INT_RESV62			62
> +#define MX28_INT_RESV63			63
> +#define MX28_INT_RESV64			64
> +#define MX28_INT_RESV65			65
> +#define MX28_INT_SPDIF_DMA		66
> +#define MX28_INT_RESV67			67
> +#define MX28_INT_I2C0_DMA		68
> +#define MX28_INT_I2C1_DMA		69
> +#define MX28_INT_AUART0_RX_DMA		70
> +#define MX28_INT_AUART0_TX_DMA		71
> +#define MX28_INT_AUART1_RX_DMA		72
> +#define MX28_INT_AUART1_TX_DMA		73
> +#define MX28_INT_AUART2_RX_DMA		74
> +#define MX28_INT_AUART2_TX_DMA		75
> +#define MX28_INT_AUART3_RX_DMA		76
> +#define MX28_INT_AUART3_TX_DMA		77
> +#define MX28_INT_AUART4_RX_DMA		78
> +#define MX28_INT_AUART4_TX_DMA		79
> +#define MX28_INT_SAIF0_DMA		80
> +#define MX28_INT_SAIF1_DMA		81
> +#define MX28_INT_SSP0_DMA		82
> +#define MX28_INT_SSP1_DMA		83
> +#define MX28_INT_SSP2_DMA		84
> +#define MX28_INT_SSP3_DMA		85
> +#define MX28_INT_LCDIF_DMA		86
> +#define MX28_INT_HSADC_DMA		87
> +#define MX28_INT_GPMI_DMA		88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP	89
> +#define MX28_INT_RESV90			90
> +#define MX28_INT_RESV91			91
> +#define MX28_INT_USB1			92
> +#define MX28_INT_USB0			93
> +#define MX28_INT_USB1_WAKEUP		94
> +#define MX28_INT_USB0_WAKEUP		95
> +#define MX28_INT_SSP0			96
> +#define MX28_INT_SSP1			97
> +#define MX28_INT_SSP2			98
> +#define MX28_INT_SSP3			99
> +#define MX28_INT_ENET_SWI		100
> +#define MX28_INT_ENET_MAC0		101
> +#define MX28_INT_ENET_MAC1		102
> +#define MX28_INT_ENET_MAC0_1588		103
> +#define MX28_INT_ENET_MAC1_1588		104
> +#define MX28_INT_RESV105		105
> +#define MX28_INT_RESV106		106
> +#define MX28_INT_RESV107		107
> +#define MX28_INT_RESV108		108
> +#define MX28_INT_RESV109		109
> +#define MX28_INT_I2C1_ERROR		110
> +#define MX28_INT_I2C0_ERROR		111
> +#define MX28_INT_AUART0			112
> +#define MX28_INT_AUART1			113
> +#define MX28_INT_AUART2			114
> +#define MX28_INT_AUART3			115
> +#define MX28_INT_AUART4			116
> +#define MX28_INT_RESV117		117
> +#define MX28_INT_RESV118		118
> +#define MX28_INT_RESV119		119
> +#define MX28_INT_RESV120		120
> +#define MX28_INT_RESV121		121
> +#define MX28_INT_RESV122		122
I'd skip these RESV defines.  They are unused anyhow.  And as soon as
you need them they need a more sensible name anyhow.

> +#define MX28_INT_GPIO4			123
> +#define MX28_INT_GPIO3			124
> +#define MX28_INT_GPIO2			125
> +#define MX28_INT_GPIO1			126
> +#define MX28_INT_GPIO0			127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..b691c34
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +
> +#define MXS_SET_ADDR		0x4
> +#define MXS_CLR_ADDR		0x8
> +#define MXS_TOG_ADDR		0xc
> +
> +/*
> + * MXS CPU types
> + */
> +#ifdef CONFIG_SOC_IMX23
> +# define cpu_is_mx23()		(machine_is_mx23evk())
> +#else
> +# define cpu_is_mx23()		(0)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# define cpu_is_mx28()		(machine_is_mx28evk())
> +#else
> +# define cpu_is_mx28()		(0)
> +#endif
Why not just:

#define cpu_is_mx28()	(machine_is_mx28evk())

?  If MACH_MX28EVK isn't defined the macro expands so 0 anyhow.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-30 10:25   ` Uwe Kleine-König
  2010-12-01 10:45     ` Shawn Guo
  2010-12-02  6:02     ` Shawn Guo
  2010-12-02  9:40   ` Uwe Kleine-König
  1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 10:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>  - The mxs wdog is implemented in RTC block.
>  - There is a generic software reset routine for most modules on mxs.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> 
>  arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
>  arch/arm/mach-mxs/system.c              |  152 +++++++++++++++++++++++++++++++
>  2 files changed, 179 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/system.h
>  create mode 100644 arch/arm/mach-mxs/system.c
> 
> diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
> new file mode 100644
> index 0000000..0e42823
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/system.h
> @@ -0,0 +1,27 @@
> +/*
> + *  Copyright (C) 1999 ARM Limited
> + *  Copyright (C) 2000 Deep Blue Solutions Ltd
> + *  Copyright 2004-2008 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.
> + */
> +
> +#ifndef __MACH_MXS_SYSTEM_H__
> +#define __MACH_MXS_SYSTEM_H__
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +void arch_reset(char mode, const char *cmd);
> +
> +#endif /* __MACH_MXS_SYSTEM_H__ */
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..7ad73bf
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; 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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG	0x50
> +#define MXS_WATCHDOG_EN		(1 << 4)
> +
> +#define MXS_MODULE_CLKGATE	(1 << 30)
> +#define MXS_MODULE_SFTRST	(1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> +	/* Set wdog count */
> +	__raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
Which unit is used here?  Does the timer only start running when it's
enabled below?  Does this apply when the watchdog is already in use,
too?

> +
> +	/* Assert SRS signal */
> +	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> +	/* Wait for reset to assert... */
> +	mdelay(500);
> +
> +	pr_err("Watchdog reset failed to assert reset\n");
> +
> +	/* Delay to allow the serial port to show the message */
> +	mdelay(50);
> +
> +	/* We'll take a jump through zero as a poor second */
> +	cpu_reset(0);
> +}
> +
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> +	struct clk *clk;
> +
> +	wdog_base = base;
> +
> +	clk = clk_get_sys("rtc", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
Actually I'm not sure if it's worth to do this.  It might hurt if you
want to save power.

I'll try to find a time slot to look into that.

> +}
> +
> +int mxs_reset_block(void __iomem *reset_addr)
> +{
> +	u32 val;
> +	int timeout;
> +
> +	/*
> +	 * The process of software reset of IP block is done
> +	 * in several steps:
> +	 *
> +	 * 1) clear SFTRST and wait it cleared;
> +	 * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
> +	 * 3) clear SFTRST and wait it cleared;
> +	 * 4) clear CLKGATE and wait it cleared.
> +	 */
> +
> +	/* Clear SFTRST */
> +	val = __raw_readl(reset_addr);
> +	val &= ~MXS_MODULE_SFTRST;
> +	__raw_writel(val, reset_addr);

__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_CLEAR_ADDR);

instead of read-modify-write here doesn't work here?

> +	/*
> +	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
> +	 * recommends to wait 1us.
> +	 */
> +	udelay(1);
> +	/* Poll SFTRST cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> +		/* nothing */;
> +	if (!timeout)
Maybe add an unlikely here?  (i.e.

	if (unlikely(!timeout))
		...
)

> +		goto error;
> +
> +	/* Clear CLKGATE */
> +	val = __raw_readl(reset_addr);
Not sure it's worth to optimize here, but you read reset_addr above.

> +	val &= ~MXS_MODULE_CLKGATE;
> +	__raw_writel(val, reset_addr);
> +	/* Set SFTRST to reset the block */
> +	val = __raw_readl(reset_addr);
> +	val |= MXS_MODULE_SFTRST;
> +	__raw_writel(val, reset_addr);
> +	/* Wait 1us */
> +	udelay(1);
The comment doesn't help much.

> +	/* Poll CLKGATE set */
> +	timeout = 0x400;
> +	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> +		/* nothing */;
> +	if (!timeout)
> +		goto error;
> +
> +	/* Clear SFTRST */
> +	val = __raw_readl(reset_addr);
> +	val &= ~MXS_MODULE_SFTRST;
> +	__raw_writel(val, reset_addr);
> +	/* Wait 1us */
> +	udelay(1);
> +	/* Poll SFTRST cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> +		/* nothing */;
> +	if (!timeout)
> +		goto error;
> +
> +	/* Clear CLKGATE */
> +	val = __raw_readl(reset_addr);
> +	val &= ~MXS_MODULE_CLKGATE;
> +	__raw_writel(val, reset_addr);
> +	/* Wait 1us */
> +	udelay(1);
> +	/* Poll CLKGATE cleared */
> +	timeout = 0x400;
> +	while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
> +		/* nothing */;
> +	if (!timeout)
> +		goto error;

There are quite some repetitions in this function.  If you could get it
down to something that looks like

	clear SFTRST
	udelay
	poll SFTRST cleared

	clear CLKGATE
	set SFTRST
	udelay
	poll CLKGATE set

	clear SFTRST
	udelay
	poll SFTRST cleared

	clear CLKGATE
	udelay
	poll CLKGATE cleared

it's IMHO better than the comment above.  If "clear CLKGATE" and "set
SFTRST" can be done in a single step this might be done like that:

	/* comment describing setmask_poll */
	static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
		u32 pollval, u32 pollmask, u32 *curval)
	{
		int timeout = 0x400;

		*curval &= ~mask;
		*curval |= set;
		__raw_writel(*curval, addr)

		/*
		 * some nice comment about 1us being a good idea
		 */
		udelay(1);

		do {
			*curval = __raw_readl(addr);
			if ((*curval & pollmask) == pollval)
				return 0;

		} while(--timeout);

		return 1;
	}

	int mxs_reset_block(void __iomem *reset_addr)
	{
		u32 val = __raw_readl(reset_addr);
		int ret;

		/* clear SFTRST and poll SFTRST becoming clear */
		ret = setmask_poll(reset_addr,
			0, MXS_MODULE_SFTRST,
			0, MXS_MODULE_SFTRST, &val);
		if (ret)
			goto error;

		/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
		ret = setmask_poll(reset_addr,
			MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
			0, MXS_MODULE_CLKGATE, &val);
		if (ret)
			goto error;

		...
	}

Well, not very nice, but IMHO better that your code.  Maybe
mxs_reset_block fits in a Terminal that way without decreasing the font
size :-)

> +
> +	return 0;
> +
> +error:
> +	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 04/15] ARM: mxs: Add interrupt support
  2010-11-26  6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-11-30 13:56   ` Uwe Kleine-König
  2010-11-30 17:02     ` Russell King - ARM Linux
  2010-12-01 11:23     ` Shawn Guo
  0 siblings, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Fri, Nov 26, 2010 at 02:49:03PM +0800, Shawn Guo wrote:
> Add Interrupt Collector (ICOLL) support for MXS-based.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/icoll.c                    |   77 ++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/entry-macro.S |   36 ++++++++++++
>  2 files changed, 113 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/icoll.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
> 
> diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
> new file mode 100644
> index 0000000..a7a7d4f
> --- /dev/null
> +++ b/arch/arm/mach-mxs/icoll.c
> @@ -0,0 +1,77 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/irq.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define HW_ICOLL_VECTOR				0x0000
> +#define HW_ICOLL_LEVELACK			0x0010
> +#define HW_ICOLL_CTRL				0x0020
> +#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
> +#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
> +#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
> +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
> +
> +void __iomem *icoll_base;
> +
> +static void icoll_ack_irq(unsigned int irq)
> +{
> +	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
You need to write this before handling the irq, no?

> +
> +	/* ACK current interrupt (level 0) */
> +	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
> +			icoll_base + HW_ICOLL_LEVELACK);
> +}
> +
> +static void icoll_mask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
> +}
> +
> +static void icoll_unmask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
> +}
> +
> +static struct irq_chip mxs_icoll_chip = {
> +	.ack = icoll_ack_irq,
> +	.mask = icoll_mask_irq,
> +	.unmask = icoll_unmask_irq,
> +};
> +
> +void __init icoll_init_irq(void __iomem *irqbase)
> +{
> +	int i;
> +
> +	icoll_base = irqbase;
> +
> +	/* Reset icoll */
> +	mxs_reset_block(irqbase + HW_ICOLL_CTRL);
> +
> +	for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
> +		set_irq_chip(i, &mxs_icoll_chip);
> +		set_irq_handler(i, handle_level_irq);
> +		set_irq_flags(i, IRQF_VALID);
> +	}
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..597948d
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,36 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
> +	ldr	\base, =icoll_base
Maybe it's worth to hardcode the base address if only a single cpu is
compiled in?  And what about setting the base register in
get_irqnr_preamble?

> +	ldr	\base, [\base]
> +	ldr	\irqnr, [\base, #0x70]
> +	cmp	\irqnr, #0x7F
> +	moveqs	\irqnr, #0
Hmm, you only need that cmp+moveqs because you cannot be sure that an
irq is pending, right.  Maybe it would make sense not to check for irqs
in a loop?  (This is a arm-global thing, Russell?)  (BTW, you're lucky,
for your irq controller it's only ugly to check if there is an irq
pending.  IIRC ns9xxx has a race here.)

> +	.endm
> +
> +	.macro  get_irqnr_preamble, base, tmp
> +	.endm
> +
> +	.macro  arch_ret_to_user, tmp1, tmp2
> +	.endm
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 05/15] ARM: mxs: Add low-level debug UART support
  2010-11-26  6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-11-30 15:48   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:04PM +0800, Shawn Guo wrote:
> * DEBUG_LL support, which is incompatible with single MXS image
>   because of different DUART base address on MX23 and MX28
> * uncompress message support
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/include/mach/debug-macro.S |   51 ++++++++++++++++
>  arch/arm/mach-mxs/include/mach/uncompress.h  |   82 ++++++++++++++++++++++++++
>  2 files changed, 133 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
>  create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
> new file mode 100644
> index 0000000..efb3173
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
> @@ -0,0 +1,51 @@
> +/* arch/arm/mach-mxs/include/mach/debug-macro.S
> + *
> + * Debugging macro include header
> + *
> + *  Copyright (C) 1994-1999 Russell King
> + *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <mach/hardware.h>
> +
> +#ifdef CONFIG_SOC_IMX23
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR	MX23_DUART_BASE_ADDR
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR	MX28_DUART_BASE_ADDR
> +#endif
> +
> +#define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR)
> +
> +		.macro	addruart, rp, rv
> +		ldr	\rp, =UART_PADDR	@ physical
> +		ldr	\rv, =UART_VADDR	@ virtual
> +		.endm
> +
> +		.macro	senduart, rd, rx
> +		str	\rd, [\rx, #0x0]	@ DR
> +		.endm
> +
> +		.macro	waituart, rd, rx
> +1001:		ldr	\rd, [\rx, #0x18]	@ FR
> +		tst	\rd, #1 << 5		@ FR_TXFF
> +		bne	1001b
> +		.endm
> +
> +		.macro	busyuart, rd, rx
> +1002:		ldr	\rd, [\rx, #0x18]	@ FR
> +		tst	\rd, #1 << 3		@ FR_BUSY
> +		beq	1002b
> +		.endm
> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
> new file mode 100644
> index 0000000..47e5479
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
> @@ -0,0 +1,82 @@
> +/*
> + *  arch/arm/mach-mxs/include/mach/uncompress.h
> + *
> + *  Copyright (C) 1999 ARM Limited
> + *  Copyright (C) Shane Nay (shane at minirl.com)
> + *  Copyright 2010 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.
> + */
> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> +#define __MACH_MXS_UNCOMPRESS_H__
> +
> +#define __MXS_BOOT_UNCOMPRESS
> +
> +#include <asm/mach-types.h>
> +
> +static unsigned long uart_base;
> +
> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> +
> +#define DR		0x00
> +#define FR		0x18
> +#define FR_BUSY		(1 << 3)
> +#define FR_TXFE		(1 << 7)
> +#define CR		0x30
> +#define CR_UARTEN	1
> +
> +/*
> + * The following code assumes the serial port has already been
> + * initialized by the bootloader.  We search for the first enabled
> + * port in the most probable order.  If you didn't setup a port in
> + * your bootloader then nothing will appear (which might be desired).
> + *
> + * This does not append a newline
> + */
This comment seems wrong.

> +static void putc(int ch)
> +{
> +	if (!uart_base)
> +		return;
> +	if (!(UART(CR) & CR_UARTEN))
> +		return;
> +
> +	while (!(UART(FR) & FR_TXFE))
> +		barrier();
> +
> +	UART(DR) = ch;
> +}
> +
> +static inline void flush(void)
> +{
> +}
> +
> +#define MX23_DUART_BASE_ADDR	0x80070000
> +#define MX28_DUART_BASE_ADDR	0x80074000
> +
> +static __inline__ void __arch_decomp_setup(unsigned long arch_id)
> +{
> +	switch (arch_id) {
> +	case MACH_TYPE_MX23EVK:
> +		uart_base = MX23_DUART_BASE_ADDR;
> +		break;
> +	case MACH_TYPE_MX28EVK:
> +		uart_base = MX28_DUART_BASE_ADDR;
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
> +#define arch_decomp_wdog()
> +
> +#endif /* __MACH_MXS_UNCOMPRESS_H__ */
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 06/15] ARM: mxs: Add timer support
  2010-11-26  6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-30 16:13   ` Uwe Kleine-König
  2010-12-02 14:44     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

[added Thomas to Cc, he can probably say more here.  Don't know if he
want though :-)]

On Fri, Nov 26, 2010 at 02:49:05PM +0800, Shawn Guo wrote:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
> 
> As the result, we need two instances of timers with v1 for better
> implementation, one for next_event and another for get_cycles.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/timer.c |  285 +++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 285 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/timer.c
> 
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..c52b465
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
> @@ -0,0 +1,285 @@
> +/*
> + *  Copyright (C) 2000-2001 Deep Blue Solutions
> + *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
> + *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
> + *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
> + *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/clockchips.h>
> +#include <linux/clk.h>
> +
> +#include <mach/hardware.h>
> +#include <asm/mach/time.h>
> +#include <mach/common.h>
> +
> +/*
> + * There are 2 versions of the timrot on Freescale MXS-based SoCs.
> + * The v1 on MX23 only gets 16 bits counter and has no match function.
> + * The v2 on MX28 extends the counter to 32 bits and add the match function.
> + *
> + * As the result, we need two instances of timers with v1 for better
> + * implementation, one for next_event and another for get_cycles. Otherwise,
> + * get_cycles may get imprecise result after long time cumulating.
> + * With v2, one instance can serve two purposes well.
> + */
> +#define timrot_is_v1()	(cpu_is_mx23())
> +
> +#define HW_TIMROT_ROTCTRL			0x00
> +#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
> +#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
> +#define HW_TIMROT_MATCH_COUNTn(n)		(0x50 + (n) * 0x40)
> +#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
> +#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
> +#define BM_TIMROT_TIMCTRLn_MATCH_MODE		(1 << 11)
> +#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
> +#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
> +#define BP_TIMROT_TIMCTRLn_SELECT		0
> +#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL	(timrot_is_v1() ? 0x8 : 0xb)
I don't like hiding different register offsets behind a constant.  This
might make usage of the constant more expensive than the C-code let
expect.

> +
> +static struct clock_event_device clockevent_mxs;
> +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> +
> +static void __iomem *timer_base;
> +
> +static inline void timrot_irq_disable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static cycle_t timrot_get_cycles(struct clocksource *cs)
> +{
> +	if (timrot_is_v1())
> +		return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
> +				& 0xffff0000) >> 16);
> +	else
> +		return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +}
Maybe better implement timrotv1_get_cycles and timrotv2_get_cycles and
only do the distinction once at init time when setting the callback
instead of each time it is called.

> +static int timrot_set_next_event(unsigned long evt,
> +					struct clock_event_device *dev)
> +{
> +	unsigned long match;
> +	int ret;
> +
> +	/* timrot decrements the count */
> +	if (timrot_is_v1()) {
> +		__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +		ret = 0;
> +	} else {
> +		match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNTn(0))
> +				- evt;
> +		__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> +		ret = (int)(match - __raw_readl(timer_base +
> +				HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> +	}
> +
> +	return ret;
> +}
ditto

> +
> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> +{
> +	struct clock_event_device *evt = &clockevent_mxs;
> +
> +	timrot_irq_acknowledge();
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mxs_timer_irq = {
> +	.name		= "MXS Timer Tick",
> +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
IRQF_DISABLED is a noop, skip it.

> +	.handler	= mxs_timer_interrupt,
> +};
> +
> +#ifdef DEBUG
> +static const char *clock_event_mode_label[] = {
> +	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> +	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
> +	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
> +	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
> +};
> +#endif /* DEBUG */
> +
> +static void mxs_set_mode(enum clock_event_mode mode,
> +				struct clock_event_device *evt)
> +{
> +	unsigned long flags;
> +
> +	/*
> +	 * The timer interrupt generation is disabled at least
> +	 * for enough time to call mxs_set_next_event()
> +	 */
> +	local_irq_save(flags);
I think set_mode is called with irqs already off.

> +
> +	/* Disable interrupt in timer module */
> +	timrot_irq_disable();
> +
> +	if (mode != clockevent_mode) {
> +		/* Set event time into far-far future */
> +		__raw_writel(__raw_readl(timer_base +
> +				HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> +				timer_base + HW_TIMROT_MATCH_COUNTn(0));
I don't know if this is needed, maybe there cannot be a pending event
when set_mode is called?  Thomas?

> +		/* Clear pending interrupt */
> +		timrot_irq_acknowledge();
> +	}
> +
> +#ifdef DEBUG
> +	printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
> +		clock_event_mode_label[clockevent_mode],
> +		clock_event_mode_label[mode]);
> +#endif /* DEBUG */
> +
> +	/* Remember timer mode */
> +	clockevent_mode = mode;
> +	local_irq_restore(flags);
> +
> +	switch (mode) {
> +	case CLOCK_EVT_MODE_PERIODIC:
> +		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> +				"supported for MXS-based\n");
> +		break;
> +	case CLOCK_EVT_MODE_ONESHOT:
> +	/*
> +	 * Do not put overhead of interrupt enable/disable into
> +	 * mxs_set_next_event(), the core has about 4 minutes
> +	 * to call mxs_set_next_event() or shutdown clock after
> +	 * mode switching
> +	 */
> +		local_irq_save(flags);
> +		timrot_irq_enable();
> +		local_irq_restore(flags);
> +		break;
> +	case CLOCK_EVT_MODE_SHUTDOWN:
> +	case CLOCK_EVT_MODE_UNUSED:
> +	case CLOCK_EVT_MODE_RESUME:
> +		/* Left event sources disabled, no more interrupts appear */
> +		break;
> +	}
> +}
> +
> +static struct clock_event_device clockevent_mxs = {
> +	.name		= "mxs_timrot",
> +	.features	= CLOCK_EVT_FEAT_ONESHOT,
> +	.shift		= 32,
> +	.set_mode	= mxs_set_mode,
> +	.set_next_event	= timrot_set_next_event,
> +	.rating		= 200,
> +};
> +
> +static int __init mxs_clockevent_init(struct clk *timer_clk)
> +{
> +	unsigned int c = clk_get_rate(timer_clk);
> +
> +	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
> +	clockevent_mxs.cpumask = cpumask_of(0);
> +	if (timrot_is_v1()) {
> +		clockevent_mxs.max_delta_ns =
> +			clockevent_delta2ns(0xfffe, &clockevent_mxs);
> +		clockevent_mxs.min_delta_ns =
> +			clockevent_delta2ns(0xf, &clockevent_mxs);
> +	} else {
> +		clockevent_mxs.max_delta_ns =
> +			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
> +		clockevent_mxs.min_delta_ns =
> +			clockevent_delta2ns(0xff, &clockevent_mxs);
> +	}
> +
> +	clockevents_register_device(&clockevent_mxs);
> +
> +	return 0;
> +}
> +
> +static struct clocksource clocksource_mxs = {
> +	.name 		= "mxs_timer",
> +	.rating		= 200,
> +	.read		= timrot_get_cycles,
> +	.mask		= CLOCKSOURCE_MASK(32),
> +	.shift 		= 10,
> +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> +{
> +	unsigned int c = clk_get_rate(timer_clk);
> +
> +	if (timrot_is_v1())
> +		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
I wonder if a shift of 10 is a bit heavy for a 16 bit timer.

> +	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
> +	clocksource_register(&clocksource_mxs);
> +
> +	return 0;
> +}
> +
> +void __init mxs_timer_init(struct clk *timer_clk,
> +				void __iomem *base, int irq)
> +{
> +	clk_enable(timer_clk);
> +
> +	timer_base = base;
> +
> +	/*
> +	 * Initialize timers to a known state
> +	 */
> +	mxs_reset_block(base + HW_TIMROT_ROTCTRL);
> +
> +	if (timrot_is_v1()) {
> +		/* timer0 is for next_event */
The more usual names are clock_event ...
> +		__raw_writel(
> +			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_UPDATE |
> +			BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			base + HW_TIMROT_TIMCTRLn(0));
> +		/* timer1 is for get_cycles */
and clocksource.

> +		__raw_writel(
> +			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_RELOAD,
> +			base + HW_TIMROT_TIMCTRLn(1));
> +		__raw_writel(0xffff, timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
> +
> +	} else {
> +		__raw_writel(
> +			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_IRQ_EN |
> +			BM_TIMROT_TIMCTRLn_MATCH_MODE,
> +			timer_base + HW_TIMROT_TIMCTRLn(0));
> +	}
> +
> +	/* init and register the timer to the framework */
> +	mxs_clocksource_init(timer_clk);
> +	mxs_clockevent_init(timer_clk);
> +
> +	/* Make irqs happen */
> +	setup_irq(irq, &mxs_timer_irq);
> +}

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 07/15] ARM: mxs: Add gpio support
  2010-11-26  6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-11-30 16:21   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Fri, Nov 26, 2010 at 02:49:06PM +0800, Shawn Guo wrote:
> MXS-based SoCs implement gpio support in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/gpio.c              |  364 +++++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/gpio.h |   49 +++++
>  2 files changed, 413 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/gpio.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
> 
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..7e3674b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
> @@ -0,0 +1,364 @@
> +/*
> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * Based on code from Freescale,
> + * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/gpio.h>
> +#include <mach/hardware.h>
> +#include <asm-generic/bug.h>
> +
> +static struct mxs_gpio_port *mxs_gpio_ports;
> +static int gpio_table_size;
> +
> +#define PINCTRL_DOUT(n)		((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
> +#define PINCTRL_DIN(n)		((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
> +#define PINCTRL_DOE(n)		((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
> +#define PINCTRL_PIN2IRQ(n)	((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
> +#define PINCTRL_IRQEN(n)	((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
> +#define PINCTRL_IRQLEV(n)	((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
> +#define PINCTRL_IRQPOL(n)	((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
> +#define PINCTRL_IRQSTAT(n)	((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
> +
> +#define GPIO_INT_FALL_EDGE	0x0
> +#define GPIO_INT_LOW_LEV	0x1
> +#define GPIO_INT_RISE_EDGE	0x2
> +#define GPIO_INT_HIGH_LEV	0x3
> +
> +/* Note: This driver assumes 32 GPIOs are handled in one register */
> +
> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
> +{
> +	__raw_writel(1 << index,
> +			port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
> +}
> +
> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> +				int enable)
> +{
> +	if (enable == 0) {
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> +	} else {
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
> +	}
> +}
> +
> +static void gpio_ack_irq(u32 irq)
> +{
> +	u32 gpio = irq_to_gpio(irq);
> +	_clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
> +}
> +
> +static void gpio_mask_irq(u32 irq)
> +{
> +	u32 gpio = irq_to_gpio(irq);
> +	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
> +}
> +
> +static void gpio_unmask_irq(u32 irq)
> +{
> +	u32 gpio = irq_to_gpio(irq);
> +	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
> +}
> +
> +static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
> +
> +static int gpio_set_irq_type(u32 irq, u32 type)
> +{
> +	u32 gpio = irq_to_gpio(irq);
> +	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
> +	u32 val;
> +	int edge;
> +
> +	port->both_edges &= ~(1 << (gpio & 31));
> +	switch (type) {
> +	case IRQ_TYPE_EDGE_RISING:
> +		edge = GPIO_INT_RISE_EDGE;
> +		break;
> +	case IRQ_TYPE_EDGE_FALLING:
> +		edge = GPIO_INT_FALL_EDGE;
> +		break;
> +	case IRQ_TYPE_EDGE_BOTH:
> +		val = mxs_gpio_get(&port->chip, gpio & 31);
> +		if (val) {
> +			edge = GPIO_INT_LOW_LEV;
> +			pr_debug("mxs: set GPIO %d to low trigger\n", gpio);
> +		} else {
> +			edge = GPIO_INT_HIGH_LEV;
> +			pr_debug("mxs: set GPIO %d to high trigger\n", gpio);
> +		}
> +		port->both_edges |= 1 << (gpio & 31);
This is ugly and might be racy.  Do you really need to support
IRQ_TYPE_EDGE_BOTH?

> +		break;
> +	case IRQ_TYPE_LEVEL_LOW:
> +		edge = GPIO_INT_LOW_LEV;
> +		break;
> +	case IRQ_TYPE_LEVEL_HIGH:
> +		edge = GPIO_INT_HIGH_LEV;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	/* set level or edge */
> +	if (edge & 0x1)
Why use 0x1 here instead of a constant?

> +		__raw_writel(1 << (gpio & 31),
> +			port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
> +	else
> +		__raw_writel(1 << (gpio & 31),
> +			port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
> +
> +	/* set polarity */
> +	if ((edge >> 1) & 0x1)
ditto

> +		__raw_writel(1 << (gpio & 31),
> +			port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
> +	else
> +		__raw_writel(1 << (gpio & 31),
> +			port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
> +
> +	_clear_gpio_irqstatus(port, gpio & 0x1f);
> +
> +	return 0;
> +}
> +
> +static void mxs_flip_edge(struct mxs_gpio_port *port, u32 gpio)
> +{
> +	u32 val;
> +	int edge;
> +
> +	edge = 1 << (gpio & 31);
> +	val = __raw_readl(port->base + PINCTRL_IRQLEV(port->id));
> +	if (val & edge) {
> +		/* level is invalid for this function */
> +		pr_err("mxs: invalid configuration for GPIO %d: %x\n",
> +			gpio, edge);
> +		return;
> +	}
> +	__raw_writel(1 << (gpio & 31),
> +			port->base + PINCTRL_IRQPOL(port->id) + MXS_TOG_ADDR);
> +}
> +
> +/* MXS has one interrupt *per* gpio port */
> +static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> +	u32 irq_stat;
> +	struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
> +	u32 gpio_irq_no_base = port->virtual_irq_start;
> +
> +	irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
> +			__raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
> +			__raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
> +
> +	while (irq_stat != 0) {
> +		int irqoffset = fls(irq_stat) - 1;
> +
> +		if (port->both_edges & (1 << irqoffset))
> +			mxs_flip_edge(port, irqoffset);
> +
> +		generic_handle_irq(gpio_irq_no_base + irqoffset);
> +
> +		irq_stat &= ~(1 << irqoffset);
> +	}
> +}
> +
> +/*
> + * Set interrupt number "irq" in the GPIO as a wake-up source.
> + * While system is running, all registered GPIO interrupts need to have
> + * wake-up enabled. When system is suspended, only selected GPIO interrupts
> + * need to have wake-up enabled.
> + * @param  irq          interrupt source number
> + * @param  enable       enable as wake-up if equal to non-zero
> + * @return       This function returns 0 on success.
> + */
> +static int gpio_set_wake_irq(u32 irq, u32 enable)
> +{
> +	u32 gpio = irq_to_gpio(irq);
> +	u32 gpio_idx = gpio & 0x1f;
> +	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
> +
> +	if (enable) {
> +		if (port->irq_high && (gpio_idx >= 16))
> +			enable_irq_wake(port->irq_high);
> +		else
> +			enable_irq_wake(port->irq);
> +	} else {
> +		if (port->irq_high && (gpio_idx >= 16))
> +			disable_irq_wake(port->irq_high);
> +		else
> +			disable_irq_wake(port->irq);
> +	}
> +
> +	return 0;
> +}
> +
> +static struct irq_chip gpio_irq_chip = {
> +	.ack = gpio_ack_irq,
> +	.mask = gpio_mask_irq,
> +	.unmask = gpio_unmask_irq,
> +	.set_type = gpio_set_irq_type,
> +	.set_wake = gpio_set_wake_irq,
> +};
> +
> +static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
> +				int dir)
> +{
> +	struct mxs_gpio_port *port =
> +		container_of(chip, struct mxs_gpio_port, chip);
> +	u32 l;
> +	unsigned long flags;
> +	void __iomem *reg = port->base + PINCTRL_DOE(port->id);
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	l = __raw_readl(reg);
> +	if (dir)
> +		l |= 1 << offset;
> +	else
> +		l &= ~(1 << offset);
> +	__raw_writel(l, reg);
> +	spin_unlock_irqrestore(&port->lock, flags);
No SET/CLR register set?

> +}
> +
> +static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> +{
> +	struct mxs_gpio_port *port =
> +		container_of(chip, struct mxs_gpio_port, chip);
> +	u32 l;
> +	unsigned long flags;
> +	void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> +	__raw_writel(l, reg);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +}
> +
> +static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
> +{
> +	struct mxs_gpio_port *port =
> +		container_of(chip, struct mxs_gpio_port, chip);
> +	void __iomem *reg = port->base + PINCTRL_DIN(port->id);
> +
> +	return (__raw_readl(reg) >> offset) & 1;
> +}
> +
> +static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> +{
> +	_set_gpio_direction(chip, offset, 0);
> +	return 0;
> +}
> +
> +static int mxs_gpio_direction_output(struct gpio_chip *chip,
> +				     unsigned offset, int value)
> +{
> +	mxs_gpio_set(chip, offset, value);
> +	_set_gpio_direction(chip, offset, 1);
> +	return 0;
> +}
> +
> +int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
> +{
> +	int i, j;
> +
> +	/* save for local usage */
> +	mxs_gpio_ports = port;
> +	gpio_table_size = cnt;
> +
> +	printk(KERN_INFO "MXS GPIO hardware\n");
pr_info?

> +
> +	for (i = 0; i < cnt; i++) {
> +		/* disable the interrupt and clear the status */
> +		__raw_writel(0, port[i].base +
> +				PINCTRL_PIN2IRQ(i));
> +		__raw_writel(0, port[i].base +
> +				PINCTRL_IRQEN(i));
> +		__raw_writel(~0, port[i].base +
> +				PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
> +
> +		for (j = port[i].virtual_irq_start;
> +			j < port[i].virtual_irq_start + 32; j++) {
> +			set_irq_chip(j, &gpio_irq_chip);
> +			set_irq_handler(j, handle_level_irq);
> +			set_irq_flags(j, IRQF_VALID);
> +		}
> +
> +		/* register gpio chip */
> +		port[i].chip.direction_input = mxs_gpio_direction_input;
> +		port[i].chip.direction_output = mxs_gpio_direction_output;
> +		port[i].chip.get = mxs_gpio_get;
> +		port[i].chip.set = mxs_gpio_set;
> +		port[i].chip.base = i * 32;
> +		port[i].chip.ngpio = 32;
> +
> +		spin_lock_init(&port[i].lock);
> +
> +		/* its a serious configuration bug when it fails */
> +		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
> +
> +		/* setup one handler for each entry */
> +		set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
> +		set_irq_data(port[i].irq, &port[i]);
> +	}
> +
> +	return 0;
> +}
> +
> +#define DEFINE_MXS_GPIO_PORT(soc, _id)					\
> +	{								\
> +		.chip.label = "gpio-" #_id,				\
> +		.id = _id,						\
> +		.irq = soc ## _INT_GPIO ## _id,				\
> +		.base = soc ## _IO_ADDRESS(				\
> +				soc ## _PINCTRL ## _BASE_ADDR),		\
> +		.virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,	\
> +	}
> +
> +#define DEFINE_REGISTER_FUNCTION(prefix)				\
> +int __init prefix ## _register_gpios(void)				\
> +{									\
> +	return mxs_gpio_init(prefix ## _gpio_ports,			\
> +			ARRAY_SIZE(prefix ## _gpio_ports));		\
> +}
> +
> +#ifdef CONFIG_SOC_IMX23
> +static struct mxs_gpio_port mx23_gpio_ports[] = {
> +	DEFINE_MXS_GPIO_PORT(MX23, 0),
> +	DEFINE_MXS_GPIO_PORT(MX23, 1),
> +	DEFINE_MXS_GPIO_PORT(MX23, 2),
> +};
> +DEFINE_REGISTER_FUNCTION(mx23)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +static struct mxs_gpio_port mx28_gpio_ports[] = {
> +	DEFINE_MXS_GPIO_PORT(MX28, 0),
> +	DEFINE_MXS_GPIO_PORT(MX28, 1),
> +	DEFINE_MXS_GPIO_PORT(MX28, 2),
> +	DEFINE_MXS_GPIO_PORT(MX28, 3),
> +	DEFINE_MXS_GPIO_PORT(MX28, 4),
> +};
> +DEFINE_REGISTER_FUNCTION(mx28)
> +#endif
> diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
> new file mode 100644
> index 0000000..7692de6
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/gpio.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_GPIO_H__
> +#define __MACH_MXS_GPIO_H__
> +
> +#include <linux/spinlock.h>
> +#include <mach/hardware.h>
> +#include <asm-generic/gpio.h>
> +
> +#define MXS_GPIO_NR(bank, nr)		((bank) * 32 + (nr))
> +
> +/* use gpiolib dispatchers */
> +#define gpio_get_value		__gpio_get_value
> +#define gpio_set_value		__gpio_set_value
> +#define gpio_cansleep		__gpio_cansleep
> +
> +#define gpio_to_irq(gpio)	(MXS_GPIO_IRQ_START + (gpio))
> +#define irq_to_gpio(irq)	((irq) - MXS_GPIO_IRQ_START)
> +
> +struct mxs_gpio_port {
> +	void __iomem *base;
> +	int id;
> +	int irq;
> +	int irq_high;
> +	int virtual_irq_start;
> +	struct gpio_chip chip;
> +	u32 both_edges;
> +	spinlock_t lock;
> +};
This doesn't need to be that public, arch/arm/mach-mxs/gpio.h would be
enough.
> +
> +int mxs_gpio_init(struct mxs_gpio_port*, int);
ditto.

> +
> +#endif /* __MACH_MXS_GPIO_H__ */
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 08/15] ARM: mxs: Add iomux support
  2010-11-26  6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-11-30 16:32   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:07PM +0800, Shawn Guo wrote:
> MXS-based SoCs implements iomux functions in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/include/mach/iomux-mx23.h |   29 +++++++
>  arch/arm/mach-mxs/include/mach/iomux-mx28.h |   44 +++++++++++
>  arch/arm/mach-mxs/include/mach/iomux.h      |   77 +++++++++++++++++++
>  arch/arm/mach-mxs/iomux.c                   |  110 +++++++++++++++++++++++++++
>  4 files changed, 260 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
>  create mode 100644 arch/arm/mach-mxs/iomux.c
> 
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> new file mode 100644
> index 0000000..3fc0439
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#ifndef __MACH_IOMUX_MX23_H__
> +#define __MACH_IOMUX_MX23_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + *					 		BANK PIN     MUX            VOL          MA            PULL
> + */
> +/* DUART */
> +#define MX23_PAD_PWM0__DUART_RX			IOMUX_PAD(1, 26, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
> +#define MX23_PAD_PWM1__DUART_TX			IOMUX_PAD(1, 27, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..ca37a15
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#ifndef __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + *					 		BANK PIN     MUX            VOL          MA            PULL
> + */
> +/* DUART */
> +#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +/* FEC */
> +#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +
> +/* GPIO */
> +#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
> new file mode 100644
> index 0000000..27bcada
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux.h
> @@ -0,0 +1,77 @@
> +/*
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *			<armlinux@phytec.de>
> + * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_IOMUX_H__
> +#define __MACH_MXS_IOMUX_H__
> +
> +typedef struct pad_desc {
> +	unsigned bank:3;
> +	unsigned pin:5;
> +	unsigned muxsel:2;
> +	unsigned ma:3;
> +	unsigned vol:2;
> +	unsigned pull:1;
> +} iomux_cfg_t;
mxc just switches to u64 (IIRC) for pad descriptions because the values
are easier to manipulate.  This would be better for mxs, too.

> +
> +#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)	\
> +		{						\
> +			.bank	= _bank,			\
> +			.pin	= _pin,				\
> +			.muxsel	= _muxsel,			\
> +			.vol	= _vol,				\
> +			.ma	= _ma,				\
> +			.pull	= _pull,			\
> +		}
> +
> +#define PAD_MUXSEL_0		0
> +#define PAD_MUXSEL_1		1
> +#define PAD_MUXSEL_2		2
> +#define PAD_MUXSEL_GPIO		3
> +
> +#define PAD_1V8			0
> +#define PAD_3V3			1
> +#define PAD_VOL_NONE		2
> +
> +#define PAD_4MA			0
> +#define PAD_8MA			1
> +#define PAD_12MA		2
> +#define PAD_16MA		3
> +#define PAD_MA_NONE		4
> +
> +#define PAD_NOPULL		0
> +#define PAD_PULL		1
> +
> +/*
> + * setups a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t *pad);
> +
> +/*
> + * setups multiple pads
> + * convenient way to call the above function with tables
> + */
> +int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
> +
> +/*
> + * Initialise the iomux controller
> + */
> +void mxs_iomux_init(void __iomem *iomux_base);
> +
> +#endif /* __MACH_MXS_IOMUX_H__*/
> diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
> new file mode 100644
> index 0000000..803cadf
> --- /dev/null
> +++ b/arch/arm/mach-mxs/iomux.c
> @@ -0,0 +1,110 @@
> +/*
> + * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *                       <armlinux@phytec.de>
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/string.h>
> +#include <linux/gpio.h>
> +
> +#include <asm/mach/map.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/iomux.h>
> +
> +static void __iomem *base;
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t *pad)
> +{
> +	u32 reg, ofs, bp, bm;
> +
> +	/* muxsel */
> +	ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
> +	bp = pad->pin % 16 * 2;
> +	bm = 0x3 << bp;
> +	reg = __raw_readl(base + ofs);
> +	reg &= ~bm;
> +	reg |= pad->muxsel << bp;
> +	__raw_writel(reg, base + ofs);
> +
> +	/* drive */
> +	ofs = cpu_is_mx23() ? 0x200 : 0x300;
> +	ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
> +	/* ma */
> +	if (pad->ma != PAD_MA_NONE)
> +	{
> +		bp = pad->pin % 8 * 4;
> +		bm = 0x3 << bp;
> +		reg = __raw_readl(base + ofs);
> +		reg &= ~bm;
> +		reg |= pad->ma << bp;
> +		__raw_writel(reg, base + ofs);
> +	}
> +	/* vol */
> +	if (pad->vol != PAD_VOL_NONE)
> +	{
> +		bp = pad->pin % 8 * 4 + 2;
> +		bm = 0x1 << bp;
> +		reg = __raw_readl(base + ofs);
> +		reg &= ~bm;
> +		reg |= pad->vol << bp;
> +		__raw_writel(reg, base + ofs);
> +	}
> +
> +	/* pull */
> +	ofs = cpu_is_mx23() ? 0x400 : 0x600;
> +	ofs += pad->bank * 0x10;
> +	bp = pad->pin;
> +	bm = 0x1 << bp;
> +	reg = __raw_readl(base + ofs);
> +	reg &= ~bm;
> +	reg |= pad->pull << bp;
> +	__raw_writel(reg, base + ofs);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(mxs_iomux_setup_pad);
Really needed?

> +
> +int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
> +{
> +	iomux_cfg_t *p = pad_list;
> +	int i;
> +	int ret;
> +
> +	for (i = 0; i < count; i++) {
> +		ret = mxs_iomux_setup_pad(p);
> +		if (ret)
> +			return ret;
> +		p++;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
> +
> +void mxs_iomux_init(void __iomem *iomux_base)
> +{
> +	base = iomux_base;
> +}

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-11-26  6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-11-30 16:39   ` Uwe Kleine-König
  2010-12-07 13:09     ` Shawn Guo
  2010-12-02 15:07   ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/clock-mx23.c          |  521 ++++++++++++++++++++++
>  arch/arm/mach-mxs/clock-mx28.c          |  732 +++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/clock.c               |  201 +++++++++
>  arch/arm/mach-mxs/include/mach/clkdev.h |    7 +
>  arch/arm/mach-mxs/include/mach/clock.h  |   64 +++
>  arch/arm/mach-mxs/regs-clkctrl-mx23.h   |  455 +++++++++++++++++++
>  arch/arm/mach-mxs/regs-clkctrl-mx28.h   |  663 ++++++++++++++++++++++++++++
>  7 files changed, 2643 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/clock-mx23.c
>  create mode 100644 arch/arm/mach-mxs/clock-mx28.c
>  create mode 100644 arch/arm/mach-mxs/clock.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
>  create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
>  create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
> 
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..832db0b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,521 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +#include <asm/clkdev.h>
> +#include <asm/div64.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/clock.h>
> +
> +#include "regs-clkctrl-mx23.h"
> +
> +#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
> +#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
> +
> +static int _raw_clk_enable(struct clk *clk)
> +{
> +	u32 reg;
> +
> +	if (clk->enable_reg) {
> +		reg = __raw_readl(clk->enable_reg);
> +		reg &= ~(1 << clk->enable_shift);
> +		__raw_writel(reg, clk->enable_reg);
> +	}
> +
> +	return 0;
> +}
Hmm, I would have used an approach that is quickly switchable to the
generic clock stuff posted a few times here.  But probably already too
late.  So it's up to you to decide when to switch (or if at all).

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 04/15] ARM: mxs: Add interrupt support
  2010-11-30 13:56   ` Uwe Kleine-König
@ 2010-11-30 17:02     ` Russell King - ARM Linux
  2010-12-01 11:23     ` Shawn Guo
  1 sibling, 0 replies; 146+ messages in thread
From: Russell King - ARM Linux @ 2010-11-30 17:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Nov 30, 2010 at 02:56:23PM +0100, Uwe Kleine-K?nig wrote:
> > +	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
> > +	ldr	\base, =icoll_base
> Maybe it's worth to hardcode the base address if only a single cpu is
> compiled in?  And what about setting the base register in
> get_irqnr_preamble?
> 
> > +	ldr	\base, [\base]
> > +	ldr	\irqnr, [\base, #0x70]
> > +	cmp	\irqnr, #0x7F
> > +	moveqs	\irqnr, #0
> Hmm, you only need that cmp+moveqs because you cannot be sure that an
> irq is pending, right.  Maybe it would make sense not to check for irqs
> in a loop?  (This is a arm-global thing, Russell?)  (BTW, you're lucky,
> for your irq controller it's only ugly to check if there is an irq
> pending.  IIRC ns9xxx has a race here.)

It always makes sense to check for more IRQs after you've processed
the first one before returning.  Entering and exiting from the calling
context is very expensive compared to looping back to check for further
interrupts.

It's also possible for interrupts to be received on a core, but there
to be no IRQ pending in the controller.  So you can't guarantee that
you have work to do just because the CPU entered the IRQ vector.  This
is especially true with level-activated IRQ sources.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices
  2010-11-26  6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-11-30 20:01   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:11PM +0800, Shawn Guo wrote:
> Dynamically allocate fec devices for MX28, which gets dual
> fec interface.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/devices-mx28.h                |    6 +++
>  arch/arm/mach-mxs/devices/platform-fec.c        |   51 +++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/devices-common.h |   12 +++++
>  3 files changed, 69 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c
> 
> diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
> index 47c2f04..c509e5d 100644
> --- a/arch/arm/mach-mxs/devices-mx28.h
> +++ b/arch/arm/mach-mxs/devices-mx28.h
> @@ -14,3 +14,9 @@
>  extern const struct mxs_duart_data mx28_duart_data __initconst;
>  #define mx28_add_duart() \
>  	mxs_add_duart(&mx28_duart_data)
> +
> +extern const struct mxs_fec_data mx28_fec_data[] __initconst;
> +#define mx28_add_fec(id, pdata) \
> +	mxs_add_fec(&mx28_fec_data[id], pdata)
> +#define mx28_add_fec0(pdata)	mx28_add_fec(0, pdata)
> +#define mx28_add_fec1(pdata)	mx28_add_fec(1, pdata)
On MXC I only kept the defines that have the id in the macro name for
compatibility.  Just to let you know.

> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> new file mode 100644
> index 0000000..a2389b2
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -0,0 +1,51 @@
> +/*
> + * Copyright (C) 2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <asm/sizes.h>
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +
> +#define mxs_fec_data_entry_single(soc, _id, _size)			\
> +	{								\
> +		.id = _id,						\
> +		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
> +		.iosize = _size,					\
You don't necessarily need to add the size here as it's equal for all
devices.

> +		.irq = soc ## _INT_ENET_MAC ## _id,			\
> +	}
> +
> +#define mxs_fec_data_entry(soc, _id, _size)				\
> +	[_id] = mxs_fec_data_entry_single(soc, _id, _size)
> +
> +#ifdef CONFIG_SOC_IMX28
> +const struct mxs_fec_data mx28_fec_data[] __initconst = {
> +#define mx28_fec_data_entry(_id)					\
> +	mxs_fec_data_entry(MX28, _id, SZ_16K)
> +	mx28_fec_data_entry(0),
> +	mx28_fec_data_entry(1),
> +};
> +#endif
> +
> +struct platform_device *__init mxs_add_fec(
> +		const struct mxs_fec_data *data,
> +		const struct fec_platform_data *pdata)
> +{
> +	struct resource res[] = {
> +		{
> +			.start = data->iobase,
> +			.end = data->iobase + data->iosize - 1,
> +			.flags = IORESOURCE_MEM,
> +		}, {
> +			.start = data->irq,
> +			.end = data->irq,
> +			.flags = IORESOURCE_IRQ,
> +		},
> +	};
> +
> +	return mxs_add_platform_device("fec", data->id,
> +			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
> index 07b4439..3da48d4 100644
> --- a/arch/arm/mach-mxs/include/mach/devices-common.h
> +++ b/arch/arm/mach-mxs/include/mach/devices-common.h
> @@ -32,3 +32,15 @@ struct mxs_duart_data {
>  };
>  struct platform_device *__init mxs_add_duart(
>  		const struct mxs_duart_data *data);
> +
> +/* fec */
> +#include <linux/fec.h>
> +struct mxs_fec_data {
> +	int id;
> +	resource_size_t iobase;
> +	resource_size_t iosize;
> +	resource_size_t irq;
> +};
> +struct platform_device *__init mxs_add_fec(
> +		const struct mxs_fec_data *data,
> +		const struct fec_platform_data *pdata);
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 13/15] ARM: mxs: Add initial mx23evk support
  2010-11-26  6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-11-30 20:02   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:12PM +0800, Shawn Guo wrote:
> Add initial mx23evk support with duart.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/mach-mx23evk.c |   59 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 59 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c
> 
> diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
> new file mode 100644
> index 0000000..9048035
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx23evk.c
> @@ -0,0 +1,59 @@
> +/*
> + * Copyright 2010 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/irq.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx23.h>
> +
> +#include "devices-mx23.h"
> +
> +static iomux_cfg_t mx23evk_pads[] = {
> +	/* duart */
> +	MX23_PAD_PWM0__DUART_RX,
> +	MX23_PAD_PWM1__DUART_TX,
> +};
> +
> +static void __init mx23evk_init(void)
> +{
> +	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
> +
> +	mx23_add_duart();
> +}
> +
> +static void __init mx23evk_timer_init(void)
> +{
> +	mx23_clocks_init();
> +}
> +
> +static struct sys_timer mx23evk_timer = {
> +	.init	= mx23evk_timer_init,
> +};
> +
> +MACHINE_START(MX23EVK, "Freescale MX23 EVK")
> +	/* Maintainer: Freescale Semiconductor, Inc. */
> +	.boot_params    = PHYS_OFFSET + 0x100,
MX23_PHYS_OFFSET.  Or better just don't define .boot_params at all.

> +	.map_io         = mx23_map_io,
> +	.init_irq       = mx23_init_irq,
> +	.init_machine   = mx23evk_init,
> +	.timer          = &mx23evk_timer,
> +MACHINE_END

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 14/15] ARM: mxs: Add initial mx28evk support
  2010-11-26  6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-11-30 20:06   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:06 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:13PM +0800, Shawn Guo wrote:
> Add initial mx28evk support with duart and fec0.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/mach-mx28evk.c |  108 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 108 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> new file mode 100644
> index 0000000..901e6b1
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright 2010 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/irq.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx28.h>
> +
> +#include "devices-mx28.h"
> +
> +#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
> +#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
> +
> +static iomux_cfg_t mx28evk_pads[] = {
> +	/* duart */
> +	MX28_PAD_PWM0__DUART_RX,
> +	MX28_PAD_PWM1__DUART_TX,
> +
> +	/* fec0 */
> +	MX28_PAD_ENET0_MDC__ENET0_MDC,
> +	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
> +	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
> +	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
> +	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
> +	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
> +	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
> +	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
> +	MX28_PAD_ENET_CLK__ENET_CLK,
> +	/* phy power line */
> +	MX28_PAD_SSP1_DATA3__GPIO_2_15,
> +	/* phy reset line */
> +	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
> +};
> +
> +/* fec */
> +static inline void mx28evk_fec_reset(void)
If the function is inlined everything is OK.  If not it should live in
.init.text.  I suggest to remove the inline to give the compiler the
freedom to inline it or not and mark it with __init.

> +{
> +	int ret;
> +
> +	/* Power up fec phy */
> +	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
> +	if (ret) {
> +		pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
> +		return;
> +	}
> +	gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
technically gpio_direction_output can fail.  Not sure this matters much
here though.

> +
> +	/* Reset fec phy */
> +	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
> +	if (ret) {
> +		pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
You can save a few bytes here by using the same format string as above.
Obviously you need to pass "POWER" and "RESET" as parameter for that.
Is it worth the effort?  Up to you to decide.

> +		return;
> +	}
> +	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> +	mdelay(1);
> +	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> +        .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static void __init mx28evk_init(void)
> +{
> +	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
> +
> +	mx28_add_duart();
> +
> +	mx28evk_fec_reset();
> +	mx28_add_fec0(&mx28_fec_pdata);
> +}
> +
> +static void __init mx28evk_timer_init(void)
> +{
> +	mx28_clocks_init();
> +}
> +
> +static struct sys_timer mx28evk_timer = {
> +	.init	= mx28evk_timer_init,
> +};
> +
> +MACHINE_START(MX28EVK, "Freescale MX28 EVK")
> +	/* Maintainer: Freescale Semiconductor, Inc. */
> +	.boot_params    = PHYS_OFFSET + 0x100,
> +	.map_io         = mx28_map_io,
> +	.init_irq       = mx28_init_irq,
> +	.init_machine   = mx28evk_init,
> +	.timer          = &mx28evk_timer,
> +MACHINE_END
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 15/15] ARM: mxs: Add build configuration for mxs
  2010-11-26  6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-11-30 20:08   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:14PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/Kconfig                   |   10 ++++++++++
>  arch/arm/Makefile                  |    1 +
>  arch/arm/mach-mxs/Kconfig          |   34 ++++++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/Makefile         |   14 ++++++++++++++
>  arch/arm/mach-mxs/Makefile.boot    |    3 +++
>  arch/arm/mach-mxs/devices/Kconfig  |    5 +++++
>  arch/arm/mach-mxs/devices/Makefile |    2 ++
>  7 files changed, 69 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/Kconfig
>  create mode 100644 arch/arm/mach-mxs/Makefile
>  create mode 100644 arch/arm/mach-mxs/Makefile.boot
>  create mode 100644 arch/arm/mach-mxs/devices/Kconfig
>  create mode 100644 arch/arm/mach-mxs/devices/Makefile
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index db524e7..b0a5130 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -351,6 +351,14 @@ config ARCH_MXC
>  	help
>  	  Support for Freescale MXC/iMX-based family of processors
>  
> +config ARCH_MXS
> +	bool "Freescale MXS-based"
> +	select GENERIC_CLOCKEVENTS
> +	select ARCH_REQUIRE_GPIOLIB
> +	select COMMON_CLKDEV
> +	help
> +	  Support for Freescale MXS-based family of processors
> +
>  config ARCH_STMP3XXX
>  	bool "Freescale STMP3xxx"
>  	select CPU_ARM926T
> @@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
>  
>  source "arch/arm/mach-mmp/Kconfig"
>  
> +source "arch/arm/mach-mxs/Kconfig"
> +
>  source "arch/arm/mach-realview/Kconfig"
>  
>  source "arch/arm/mach-sa1100/Kconfig"
optimally you should put the source line between mxc and stmp3xxx to
have the same order as in the symbol definition above.

> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 057beb8..c22c1ad 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25)		:= imx
>  machine-$(CONFIG_ARCH_MX3)		:= mx3
>  machine-$(CONFIG_ARCH_MX5)		:= mx5
>  machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
> +machine-$(CONFIG_ARCH_MXS)		:= mxs
>  machine-$(CONFIG_ARCH_NETX)		:= netx
>  machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
>  machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> new file mode 100644
> index 0000000..c4ac7b4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -0,0 +1,34 @@
> +if ARCH_MXS
> +
> +source "arch/arm/mach-mxs/devices/Kconfig"
> +
> +config SOC_IMX23
> +	bool
> +	select CPU_ARM926T
> +
> +config SOC_IMX28
> +	bool
> +	select CPU_ARM926T
> +
> +comment "MXS platforms:"
> +
> +config MACH_MX23EVK
> +	bool "Support MX23EVK Platform"
> +	select SOC_IMX23
> +	select MXS_HAVE_PLATFORM_DUART
> +	default y
> +	help
> +	  Include support for MX23EVK platform. This includes specific
> +	  configurations for the board and its peripherals.
> +
> +config MACH_MX28EVK
> +	bool "Support MX28EVK Platform"
> +	select SOC_IMX28
> +	select MXS_HAVE_PLATFORM_DUART
> +	select MXS_HAVE_PLATFORM_FEC
> +	default y
> +	help
> +	  Include support for MX28EVK platform. This includes specific
> +	  configurations for the board and its peripherals.
> +
> +endif
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> new file mode 100644
> index 0000000..0b24b0d
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -0,0 +1,14 @@
> +#
> +# Makefile for the linux kernel.
not very helpful
> +#
> +
> +# Common support
> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +
> +obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> +obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> +
> +obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
> +obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
> +
> +obj-y += devices/
> diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
> new file mode 100644
> index 0000000..1568ad4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile.boot
> @@ -0,0 +1,3 @@
> +   zreladdr-y	:= 0x40008000
> +params_phys-y	:= 0x40000100
> +initrd_phys-y	:= 0x40800000
do you need params_phys and initrd_phys?

> diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
> new file mode 100644
> index 0000000..a35a2dc
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/Kconfig
> @@ -0,0 +1,5 @@
> +config MXS_HAVE_PLATFORM_DUART
> +	bool
> +
> +config MXS_HAVE_PLATFORM_FEC
> +	bool
> diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
> new file mode 100644
> index 0000000..4b5266a
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/Makefile
> @@ -0,0 +1,2 @@
> +obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
> +obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-11-30 10:25   ` Uwe Kleine-König
@ 2010-12-01 10:45     ` Shawn Guo
  2010-12-01 10:59       ` Uwe Kleine-König
  2010-12-02  6:02     ` Shawn Guo
  1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 10:45 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
> On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> +/*
>> + * Reset the system. It is called by machine_restart().
>> + */
>> +void arch_reset(char mode, const char *cmd)
>> +{
>> + ? ? /* Set wdog count */
>> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> Which unit is used here? ?Does the timer only start running when it's
> enabled below? ?Does this apply when the watchdog is already in use,
> too?
>
The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
is used here.

Good catch here.  I thought the watchdog counter only starts counting
after WATCHDOG_EN is set.  But I just confirmed it with designer that
the watchdog counter starts counting once CLKGATE is cleared, and
WATCHDOG_EN bit only controls the watchdog reset generation.  Even in
this case, 1ms should be long enough for the WATCHDOG_EN setting below
to get executed before counter goes to 0.  What is your concern here?

I should change mdelay(500) to mdelay(1).

>> +
>> + ? ? /* Assert SRS signal */
>> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
>> +
>> + ? ? /* Wait for reset to assert... */
>> + ? ? mdelay(500);
>> +
>> + ? ? pr_err("Watchdog reset failed to assert reset\n");
>> +
>> + ? ? /* Delay to allow the serial port to show the message */
>> + ? ? mdelay(50);
>> +
>> + ? ? /* We'll take a jump through zero as a poor second */
>> + ? ? cpu_reset(0);
>> +}
>> +
>> +void mxs_arch_reset_init(void __iomem *base)
>> +{
>> + ? ? struct clk *clk;
>> +
>> + ? ? wdog_base = base;
>> +
>> + ? ? clk = clk_get_sys("rtc", NULL);
>> + ? ? if (!IS_ERR(clk))
>> + ? ? ? ? ? ? clk_enable(clk);
> Actually I'm not sure if it's worth to do this. ?It might hurt if you
> want to save power.
>
> I'll try to find a time slot to look into that.
>
As this is the very initial support, I would not consider the power
saving very much.  I will be very happy to applied your solution after
it becomes available.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-12-01 10:45     ` Shawn Guo
@ 2010-12-01 10:59       ` Uwe Kleine-König
  2010-12-01 11:34         ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-01 10:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 01, 2010 at 06:45:20PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> > On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
> >> +/*
> >> + * Reset the system. It is called by machine_restart().
> >> + */
> >> +void arch_reset(char mode, const char *cmd)
> >> +{
> >> + ? ? /* Set wdog count */
> >> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> > Which unit is used here? ?Does the timer only start running when it's
> > enabled below? ?Does this apply when the watchdog is already in use,
> > too?
> >
> The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
> is used here.
"unit" was meant as in "seconds".  I assume it means seconds below, but
it doesn't matter much.

> Good catch here.  I thought the watchdog counter only starts counting
> after WATCHDOG_EN is set.  But I just confirmed it with designer that
> the watchdog counter starts counting once CLKGATE is cleared, and
> WATCHDOG_EN bit only controls the watchdog reset generation.  Even in
> this case, 1ms should be long enough for the WATCHDOG_EN setting below
> to get executed before counter goes to 0.  What is your concern here?
My concern is that it might happen that even though the timer is set to
1s, the first change happens nearly immediatly resulting in a zero.
Depending on the hardware a reset occurs when the enable bit is only set
after the counter reached zero.
 
> I should change mdelay(500) to mdelay(1).
> 
> >> +
> >> + ? ? /* Assert SRS signal */
> >> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> >> +
> >> + ? ? /* Wait for reset to assert... */
> >> + ? ? mdelay(500);
> >> +
> >> + ? ? pr_err("Watchdog reset failed to assert reset\n");
> >> +
> >> + ? ? /* Delay to allow the serial port to show the message */
> >> + ? ? mdelay(50);
> >> +
> >> + ? ? /* We'll take a jump through zero as a poor second */
> >> + ? ? cpu_reset(0);
> >> +}
> >> +
> >> +void mxs_arch_reset_init(void __iomem *base)
> >> +{
> >> + ? ? struct clk *clk;
> >> +
> >> + ? ? wdog_base = base;
> >> +
> >> + ? ? clk = clk_get_sys("rtc", NULL);
> >> + ? ? if (!IS_ERR(clk))
> >> + ? ? ? ? ? ? clk_enable(clk);
> > Actually I'm not sure if it's worth to do this. ?It might hurt if you
> > want to save power.
> >
> > I'll try to find a time slot to look into that.
> >
> As this is the very initial support, I would not consider the power
> saving very much.  I will be very happy to applied your solution after
> it becomes available.
That's OK

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 04/15] ARM: mxs: Add interrupt support
  2010-11-30 13:56   ` Uwe Kleine-König
  2010-11-30 17:02     ` Russell King - ARM Linux
@ 2010-12-01 11:23     ` Shawn Guo
  1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:03PM +0800, Shawn Guo wrote:
[...]
>> +static void icoll_ack_irq(unsigned int irq)
>> +{
>> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> You need to write this before handling the irq, no?
>
No need, indeed.  Will remove it.

>> +
>> + ? ? /* ACK current interrupt (level 0) */
>> + ? ? __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
>> + ? ? ? ? ? ? ? ? ? ? icoll_base + HW_ICOLL_LEVELACK);
>> +}
>> +
[...]
>> +
>> + ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
>> + ? ? ldr ? ? \base, =icoll_base
> Maybe it's worth to hardcode the base address if only a single cpu is
> compiled in? ?And what about setting the base register in
> get_irqnr_preamble?
>
I suppose you have known that MX23 and MX28 could be built into single
zImage.  So you are asking something as below, right?

        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
        ldr     \irqnr, [\base, #0x70]
        cmp     \irqnr, #0x7F
        moveqs  \irqnr, #0
        .endm

        .macro  get_irqnr_preamble, base, tmp
#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
        ldr     \base, =icoll_base
        ldr     \base, [\base]
#elif defined (CONFIG_SOC_IMX23)
        ldr     \base, =MX23_ICOLL_BASE_ADDR
#else
        ldr     \base, =MX28_ICOLL_BASE_ADDR
#endif
        .endm

>> + ? ? ldr ? ? \base, [\base]
>> + ? ? ldr ? ? \irqnr, [\base, #0x70]
>> + ? ? cmp ? ? \irqnr, #0x7F
>> + ? ? moveqs ?\irqnr, #0
> Hmm, you only need that cmp+moveqs because you cannot be sure that an
> irq is pending, right. ?Maybe it would make sense not to check for irqs
> in a loop? ?(This is a arm-global thing, Russell?) ?(BTW, you're lucky,
> for your irq controller it's only ugly to check if there is an irq
> pending. ?IIRC ns9xxx has a race here.)
>
Right.  But we actually have a problem with that on i.MX28, because
i.MX28  uses IRQ 127 as below.

#define MX28_INT_GPIO0                  127

So GPIO0 interrupt will not work.  Any suggestion to work around it?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-12-01 10:59       ` Uwe Kleine-König
@ 2010-12-01 11:34         ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 11:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 01, 2010 at 06:45:20PM +0800, Shawn Guo wrote:
>> Hi Uwe,
>>
>> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello,
>> >
>> > On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> >> +/*
>> >> + * Reset the system. It is called by machine_restart().
>> >> + */
>> >> +void arch_reset(char mode, const char *cmd)
>> >> +{
>> >> + ? ? /* Set wdog count */
>> >> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
>> > Which unit is used here? ?Does the timer only start running when it's
>> > enabled below? ?Does this apply when the watchdog is already in use,
>> > too?
>> >
>> The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
>> is used here.
> "unit" was meant as in "seconds". ?I assume it means seconds below, but
> it doesn't matter much.
>
Sorry.  The unit is 1ms.

>> Good catch here. ?I thought the watchdog counter only starts counting
>> after WATCHDOG_EN is set. ?But I just confirmed it with designer that
>> the watchdog counter starts counting once CLKGATE is cleared, and
>> WATCHDOG_EN bit only controls the watchdog reset generation. ?Even in
>> this case, 1ms should be long enough for the WATCHDOG_EN setting below
>> to get executed before counter goes to 0. ?What is your concern here?
> My concern is that it might happen that even though the timer is set to
> 1s, the first change happens nearly immediatly resulting in a zero.
> Depending on the hardware a reset occurs when the enable bit is only set
> after the counter reached zero.
>
Should the following changes be safe enough to address your concern?

        /* Set wdog timer 10 ms */
        __raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);

        /* Enable wdog reset */
        __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);

        /* Wait for reset to assert... */
        mdelay(10);

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-11-30 10:25   ` Uwe Kleine-König
  2010-12-01 10:45     ` Shawn Guo
@ 2010-12-02  6:02     ` Shawn Guo
  2010-12-02  7:27       ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-02  6:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
[...]
>
>> + ? ? /* Poll CLKGATE set */
>> + ? ? timeout = 0x400;
>> + ? ? while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>> +
>> + ? ? /* Clear SFTRST */
>> + ? ? val = __raw_readl(reset_addr);
>> + ? ? val &= ~MXS_MODULE_SFTRST;
>> + ? ? __raw_writel(val, reset_addr);
>> + ? ? /* Wait 1us */
>> + ? ? udelay(1);
>> + ? ? /* Poll SFTRST cleared */
>> + ? ? timeout = 0x400;
>> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>> +
>> + ? ? /* Clear CLKGATE */
>> + ? ? val = __raw_readl(reset_addr);
>> + ? ? val &= ~MXS_MODULE_CLKGATE;
>> + ? ? __raw_writel(val, reset_addr);
>> + ? ? /* Wait 1us */
>> + ? ? udelay(1);
>> + ? ? /* Poll CLKGATE cleared */
>> + ? ? timeout = 0x400;
>> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>
> There are quite some repetitions in this function. ?If you could get it
> down to something that looks like
>
> ? ? ? ?clear SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll SFTRST cleared
>
> ? ? ? ?clear CLKGATE
> ? ? ? ?set SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll CLKGATE set
>
> ? ? ? ?clear SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll SFTRST cleared
>
> ? ? ? ?clear CLKGATE
> ? ? ? ?udelay
> ? ? ? ?poll CLKGATE cleared
>
> it's IMHO better than the comment above. ?If "clear CLKGATE" and "set
> SFTRST" can be done in a single step this might be done like that:
>
> ? ? ? ?/* comment describing setmask_poll */
> ? ? ? ?static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
> ? ? ? ? ? ? ? ?u32 pollval, u32 pollmask, u32 *curval)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?int timeout = 0x400;
>
> ? ? ? ? ? ? ? ?*curval &= ~mask;
> ? ? ? ? ? ? ? ?*curval |= set;
> ? ? ? ? ? ? ? ?__raw_writel(*curval, addr)
>
> ? ? ? ? ? ? ? ?/*
> ? ? ? ? ? ? ? ? * some nice comment about 1us being a good idea
> ? ? ? ? ? ? ? ? */
> ? ? ? ? ? ? ? ?udelay(1);
>
> ? ? ? ? ? ? ? ?do {
> ? ? ? ? ? ? ? ? ? ? ? ?*curval = __raw_readl(addr);
> ? ? ? ? ? ? ? ? ? ? ? ?if ((*curval & pollmask) == pollval)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return 0;
>
> ? ? ? ? ? ? ? ?} while(--timeout);
>
> ? ? ? ? ? ? ? ?return 1;
> ? ? ? ?}
>
> ? ? ? ?int mxs_reset_block(void __iomem *reset_addr)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?u32 val = __raw_readl(reset_addr);
> ? ? ? ? ? ? ? ?int ret;
>
> ? ? ? ? ? ? ? ?/* clear SFTRST and poll SFTRST becoming clear */
> ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST, &val);
> ? ? ? ? ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ? ? ? ? ?goto error;
>
> ? ? ? ? ? ? ? ?/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
> ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> ? ? ? ? ? ? ? ? ? ? ? ?MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_CLKGATE, &val);
> ? ? ? ? ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ? ? ? ? ?goto error;
>
> ? ? ? ? ? ? ? ?...
> ? ? ? ?}
>
> Well, not very nice, but IMHO better that your code. ?Maybe
> mxs_reset_block fits in a Terminal that way without decreasing the font
> size :-)
>
I checked designer about doing "clear CLKGATE" and "set SFTRST" in a
single step, and got the following feedback.

"Per HW design, it is not safe to get those two done by write once
time. By two step write, one instruction period interval can be
ensured at least for clock  enabling before sync. Soft reset.  Your
code is only once time write in fact, so it shall not be equal to two
write operation."

In this case, how do the following changes look to you?

/*
 * Clear the bit and poll it cleared, the bit has to be
 * SFTRST(bit 31) or CLKGATE (bit 30) of block control register.
 */
static int clear_poll_bit(void __iomem *addr, u32 mask)
{
        int timeout = 0x400;

        /* clear the bit */
        __raw_writel(mask, addr + MXS_CLR_ADDR);

        /*
         * SFTRST needs 3 GPMI clocks to settle, the reference manual
         * recommends to wait 1us.
         */
        udelay(1);

        /* poll the bit becoming clear */
        while ((__raw_readl(addr) & mask) && --timeout)
                /* nothing */;

        if (unlikely(!timeout))
                return 1;

        return 0;
}

int mxs_reset_block(void __iomem *reset_addr)
{
        int ret;
        int timeout = 0x400;

        /* clear and poll SFTRST */
        ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
        if (ret)
                goto error;

        /* clear CLKGATE */
        __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
        /* set SFTRST to reset the block */
        __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
        udelay(1);
        /* poll CLKGATE becoming set */
        while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
                /* nothing */;
        if (unlikely(!timeout))
                goto error;

        /* clear and poll SFTRST */
        ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
        if (ret)
                goto error;

        /* clear and poll CLKGATE */
        ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
        if (ret)
                goto error;

error:
        pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
        return -ETIMEDOUT;
}

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-12-02  6:02     ` Shawn Guo
@ 2010-12-02  7:27       ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02  7:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

On Thu, Dec 02, 2010 at 02:02:39PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> [...]
> >
> >> + ? ? /* Poll CLKGATE set */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >> +
> >> + ? ? /* Clear SFTRST */
> >> + ? ? val = __raw_readl(reset_addr);
> >> + ? ? val &= ~MXS_MODULE_SFTRST;
> >> + ? ? __raw_writel(val, reset_addr);
> >> + ? ? /* Wait 1us */
> >> + ? ? udelay(1);
> >> + ? ? /* Poll SFTRST cleared */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >> +
> >> + ? ? /* Clear CLKGATE */
> >> + ? ? val = __raw_readl(reset_addr);
> >> + ? ? val &= ~MXS_MODULE_CLKGATE;
> >> + ? ? __raw_writel(val, reset_addr);
> >> + ? ? /* Wait 1us */
> >> + ? ? udelay(1);
> >> + ? ? /* Poll CLKGATE cleared */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >
> > There are quite some repetitions in this function. ?If you could get it
> > down to something that looks like
> >
> > ? ? ? ?clear SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll SFTRST cleared
> >
> > ? ? ? ?clear CLKGATE
> > ? ? ? ?set SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll CLKGATE set
> >
> > ? ? ? ?clear SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll SFTRST cleared
> >
> > ? ? ? ?clear CLKGATE
> > ? ? ? ?udelay
> > ? ? ? ?poll CLKGATE cleared
> >
> > it's IMHO better than the comment above. ?If "clear CLKGATE" and "set
> > SFTRST" can be done in a single step this might be done like that:
> >
> > ? ? ? ?/* comment describing setmask_poll */
> > ? ? ? ?static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
> > ? ? ? ? ? ? ? ?u32 pollval, u32 pollmask, u32 *curval)
> > ? ? ? ?{
> > ? ? ? ? ? ? ? ?int timeout = 0x400;
> >
> > ? ? ? ? ? ? ? ?*curval &= ~mask;
> > ? ? ? ? ? ? ? ?*curval |= set;
> > ? ? ? ? ? ? ? ?__raw_writel(*curval, addr)
> >
> > ? ? ? ? ? ? ? ?/*
> > ? ? ? ? ? ? ? ? * some nice comment about 1us being a good idea
> > ? ? ? ? ? ? ? ? */
> > ? ? ? ? ? ? ? ?udelay(1);
> >
> > ? ? ? ? ? ? ? ?do {
> > ? ? ? ? ? ? ? ? ? ? ? ?*curval = __raw_readl(addr);
> > ? ? ? ? ? ? ? ? ? ? ? ?if ((*curval & pollmask) == pollval)
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return 0;
> >
> > ? ? ? ? ? ? ? ?} while(--timeout);
> >
> > ? ? ? ? ? ? ? ?return 1;
> > ? ? ? ?}
> >
> > ? ? ? ?int mxs_reset_block(void __iomem *reset_addr)
> > ? ? ? ?{
> > ? ? ? ? ? ? ? ?u32 val = __raw_readl(reset_addr);
> > ? ? ? ? ? ? ? ?int ret;
> >
> > ? ? ? ? ? ? ? ?/* clear SFTRST and poll SFTRST becoming clear */
> > ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST, &val);
> > ? ? ? ? ? ? ? ?if (ret)
> > ? ? ? ? ? ? ? ? ? ? ? ?goto error;
> >
> > ? ? ? ? ? ? ? ?/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
> > ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> > ? ? ? ? ? ? ? ? ? ? ? ?MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_CLKGATE, &val);
> > ? ? ? ? ? ? ? ?if (ret)
> > ? ? ? ? ? ? ? ? ? ? ? ?goto error;
> >
> > ? ? ? ? ? ? ? ?...
> > ? ? ? ?}
> >
> > Well, not very nice, but IMHO better that your code. ?Maybe
> > mxs_reset_block fits in a Terminal that way without decreasing the font
> > size :-)
> >
> I checked designer about doing "clear CLKGATE" and "set SFTRST" in a
> single step, and got the following feedback.
> 
> "Per HW design, it is not safe to get those two done by write once
> time. By two step write, one instruction period interval can be
> ensured at least for clock  enabling before sync. Soft reset.  Your
> code is only once time write in fact, so it shall not be equal to two
> write operation."
> 
> In this case, how do the following changes look to you?
> 
> /*
>  * Clear the bit and poll it cleared, the bit has to be
>  * SFTRST(bit 31) or CLKGATE (bit 30) of block control register.
for the function it doesn't have to be one of these bits.  Maybe:

	Clear the bit and poll it cleared.  This is usually called with
	a reset address and mask being either SFTRST(bit 31) or CLKGATE
	(bit 30).

>  */
> static int clear_poll_bit(void __iomem *addr, u32 mask)
> {
>         int timeout = 0x400;
> 
>         /* clear the bit */
>         __raw_writel(mask, addr + MXS_CLR_ADDR);
ah, so there is a clr register, that's nice.

> 
>         /*
>          * SFTRST needs 3 GPMI clocks to settle, the reference manual
>          * recommends to wait 1us.
>          */
>         udelay(1);
> 
>         /* poll the bit becoming clear */
>         while ((__raw_readl(addr) & mask) && --timeout)
>                 /* nothing */;
> 
>         if (unlikely(!timeout))
>                 return 1;
> 
>         return 0;
return !timeout; ?

> }
> 
> int mxs_reset_block(void __iomem *reset_addr)
> {
>         int ret;
>         int timeout = 0x400;
> 
>         /* clear and poll SFTRST */
>         ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
>         if (ret)
>                 goto error;
> 
>         /* clear CLKGATE */
>         __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
>         /* set SFTRST to reset the block */
>         __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
>         udelay(1);
>         /* poll CLKGATE becoming set */
>         while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
>                 /* nothing */;
>         if (unlikely(!timeout))
>                 goto error;
> 
>         /* clear and poll SFTRST */
>         ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
>         if (ret)
>                 goto error;
> 
>         /* clear and poll CLKGATE */
>         ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
>         if (ret)
>                 goto error;
> 
	return 0;

> error:
>         pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
>         return -ETIMEDOUT;
> }
Other than that it looks much better IMHO.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
  2010-11-30 10:25   ` Uwe Kleine-König
@ 2010-12-02  9:40   ` Uwe Kleine-König
  2010-12-02 10:16     ` Shawn Guo
  1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02  9:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn

On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> +	/* Set wdog count */
> +	__raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> +
> +	/* Assert SRS signal */
> +	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> +	/* Wait for reset to assert... */
> +	mdelay(500);
> +
> +	pr_err("Watchdog reset failed to assert reset\n");
> +
> +	/* Delay to allow the serial port to show the message */
> +	mdelay(50);
> +
> +	/* We'll take a jump through zero as a poor second */
> +	cpu_reset(0);
After reading a bit in IMX28RM, I wonder why do you bother with the
watchdog at all?  Doesn't 

	__raw_writel(MXS_CLKCTRL_RESET_CHIP, MXS_CLKCTRL_RESET + MXS_SET_ADDR);

work easier and without the need to worry about timeouts, sleeping while
clk_{get,enable} and races?
(Note I didn't check if i.MX23 has the same register at the same
address.)

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 03/15] ARM: mxs: Add reset routines
  2010-12-02  9:40   ` Uwe Kleine-König
@ 2010-12-02 10:16     ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-02 10:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn
>
> On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> +/*
>> + * Reset the system. It is called by machine_restart().
>> + */
>> +void arch_reset(char mode, const char *cmd)
>> +{
>> + ? ? /* Set wdog count */
>> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
>> +
>> + ? ? /* Assert SRS signal */
>> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
>> +
>> + ? ? /* Wait for reset to assert... */
>> + ? ? mdelay(500);
>> +
>> + ? ? pr_err("Watchdog reset failed to assert reset\n");
>> +
>> + ? ? /* Delay to allow the serial port to show the message */
>> + ? ? mdelay(50);
>> +
>> + ? ? /* We'll take a jump through zero as a poor second */
>> + ? ? cpu_reset(0);
> After reading a bit in IMX28RM, I wonder why do you bother with the
> watchdog at all? ?Doesn't
>
> ? ? ? ?__raw_writel(MXS_CLKCTRL_RESET_CHIP, MXS_CLKCTRL_RESET + MXS_SET_ADDR);
>
> work easier and without the need to worry about timeouts, sleeping while
> clk_{get,enable} and races?
> (Note I didn't check if i.MX23 has the same register at the same
> address.)
>
Yes, it's a good way to reset mxs SoC.  But the bad thing is the
offset of the register is different between MX23 and MX28.  Also there
is no SET_ADDR for this register.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 06/15] ARM: mxs: Add timer support
  2010-11-30 16:13   ` Uwe Kleine-König
@ 2010-12-02 14:44     ` Shawn Guo
  2010-12-02 15:20       ` Thomas Gleixner
  2010-12-02 16:48       ` Uwe Kleine-König
  0 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-02 14:44 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
[...]
>> +
>> + ? ? /* Disable interrupt in timer module */
>> + ? ? timrot_irq_disable();
>> +
>> + ? ? if (mode != clockevent_mode) {
>> + ? ? ? ? ? ? /* Set event time into far-far future */
>> + ? ? ? ? ? ? __raw_writel(__raw_readl(timer_base +
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0)) + 3,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? timer_base + HW_TIMROT_MATCH_COUNTn(0));
> I don't know if this is needed, maybe there cannot be a pending event
> when set_mode is called? ?Thomas?
>
Freescale BSP works well without this.  It's probably not needed.

>> +
>> +static struct clocksource clocksource_mxs = {
>> + ? ? .name ? ? ? ? ? = "mxs_timer",
>> + ? ? .rating ? ? ? ? = 200,
>> + ? ? .read ? ? ? ? ? = timrot_get_cycles,
>> + ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
>> + ? ? .shift ? ? ? ? ?= 10,
>> + ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
>> +};
>> +
>> +static int __init mxs_clocksource_init(struct clk *timer_clk)
>> +{
>> + ? ? unsigned int c = clk_get_rate(timer_clk);
>> +
>> + ? ? if (timrot_is_v1())
>> + ? ? ? ? ? ? clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
>
I do not understand that.  The shift is used in clocksource_hz2mult() as below.

static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
{
        /*  hz = cyc/(Billion ns)
         *  mult/2^shift  = ns/cyc
         *  mult = ns/cyc * 2^shift
         *  mult = 1Billion/hz * 2^shift
         *  mult = 1000000000 * 2^shift / hz
         *  mult = (1000000000<<shift) / hz
         */
        u64 tmp = ((u64)1000000000) << shift_constant;

        tmp += hz/2; /* round for do_div */
        do_div(tmp, hz);

        return (u32)tmp;
}

The shift is working against the timers frequency (hz).  Should hz be
the thing concerned here instead of timer bit width?  Since both MX23
and MX28 timer are running@32K, so shift value 10 is picked here.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-11-26  6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
  2010-11-30 16:39   ` Uwe Kleine-König
@ 2010-12-02 15:07   ` Uwe Kleine-König
  2010-12-03  5:07     ` Shawn Guo
  1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 15:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-mxs/clock-mx23.c          |  521 ++++++++++++++++++++++
>  arch/arm/mach-mxs/clock-mx28.c          |  732 +++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/clock.c               |  201 +++++++++
>  arch/arm/mach-mxs/include/mach/clkdev.h |    7 +
>  arch/arm/mach-mxs/include/mach/clock.h  |   64 +++
>  arch/arm/mach-mxs/regs-clkctrl-mx23.h   |  455 +++++++++++++++++++
>  arch/arm/mach-mxs/regs-clkctrl-mx28.h   |  663 ++++++++++++++++++++++++++++
>  7 files changed, 2643 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/clock-mx23.c
>  create mode 100644 arch/arm/mach-mxs/clock-mx28.c
>  create mode 100644 arch/arm/mach-mxs/clock.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
>  create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
>  create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
> 
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..832db0b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,521 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +#include <asm/clkdev.h>
> +#include <asm/div64.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/clock.h>
> +
> +#include "regs-clkctrl-mx23.h"
> +
> +#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
> +#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
> +
> +static int _raw_clk_enable(struct clk *clk)
> +{
> +	u32 reg;
> +
> +	if (clk->enable_reg) {
> +		reg = __raw_readl(clk->enable_reg);
> +		reg &= ~(1 << clk->enable_shift);
> +		__raw_writel(reg, clk->enable_reg);
> +	}
> +
> +	return 0;
> +}
> +
> +static void _raw_clk_disable(struct clk *clk)
> +{
> +	u32 reg;
> +
> +	if (clk->enable_reg) {
> +		reg = __raw_readl(clk->enable_reg);
> +		reg |= 1 << clk->enable_shift;
> +		__raw_writel(reg, clk->enable_reg);
> +	}
> +}
> +
> +/*
> + * ref_xtal_clk
> + */
> +static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
> +{
> +	return 24000000;
> +}
> +
> +static struct clk ref_xtal_clk = {
> +	.get_rate = ref_xtal_clk_get_rate,
> +};
> +
> +/*
> + * pll_clk
> + */
> +static unsigned long pll_clk_get_rate(struct clk *clk)
> +{
> +	return 480000000;
> +}
> +
> +static int pll_clk_enable(struct clk *clk)
> +{
> +	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
> +			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
> +			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
> +
> +	/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
> +	 * and is incorrect (excessive). Per definition of the PLLCTRL0
> +	 * POWER field, waiting at least 10us.
> +	 */
> +	udelay(10);
> +
> +	return 0;
> +}
> +
> +static void pll_clk_disable(struct clk *clk)
> +{
> +	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
> +			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
> +			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
> +}
> +
> +static struct clk pll_clk = {
> +	 .get_rate = pll_clk_get_rate,
> +	 .enable = pll_clk_enable,
> +	 .disable = pll_clk_disable,
> +	 .parent = &ref_xtal_clk,
> +};
> +
> +/*
> + * ref_clk
> + */
> +#define _CLK_GET_RATE_REF(name, sr, ss)					\
> +static unsigned long name##_get_rate(struct clk *clk)			\
> +{									\
> +	unsigned long parent_rate;					\
> +	u32 reg, div;							\
> +									\
> +	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
> +	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
> +	parent_rate = clk_get_rate(clk->parent);			\
> +									\
> +	return parent_rate * 18 / div;					\
> +}
> +
> +_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
> +
> +#define _DEFINE_CLOCK_REF(name, er, es)					\
> +	static struct clk name = {					\
> +		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
> +		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
> +		.get_rate	= name##_get_rate,			\
> +		.enable		= _raw_clk_enable,			\
> +		.disable	= _raw_clk_disable,			\
> +		.parent		= &pll_clk,				\
> +	}
> +
> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
What happens if get_clock_rate(ref_cpu_clk) is called?:

	ref_cpu_clk_get_rate
		reg = something
		div = something else
		parent_rate = clk_get_rate(clk->parent)
			= pll_clk_get_rate() 
			= 480000000;
		return parent_rate * 18 / div
			= (480000000 * 18) / div
			= 0x202fbf000 / div
			= ...

Note that 0x202fbf000 is too big for an unsigned long so (AFAIK) this is
truncated to 0x02fbf000 / div which is wrong.

The same overflow happens in at least one set_rate function, too.

Either you have to switch to long long or (IMHO preferable) use shifted
values.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 06/15] ARM: mxs: Add timer support
  2010-12-02 14:44     ` Shawn Guo
@ 2010-12-02 15:20       ` Thomas Gleixner
  2010-12-02 16:48       ` Uwe Kleine-König
  1 sibling, 0 replies; 146+ messages in thread
From: Thomas Gleixner @ 2010-12-02 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2 Dec 2010, Shawn Guo wrote:

> Hi Uwe,
> 
> 2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn,
> >
> [...]
> >> +
> >> + ? ? /* Disable interrupt in timer module */
> >> + ? ? timrot_irq_disable();
> >> +
> >> + ? ? if (mode != clockevent_mode) {
> >> + ? ? ? ? ? ? /* Set event time into far-far future */
> >> + ? ? ? ? ? ? __raw_writel(__raw_readl(timer_base +
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? timer_base + HW_TIMROT_MATCH_COUNTn(0));
> > I don't know if this is needed, maybe there cannot be a pending event
> > when set_mode is called? ?Thomas?
> >
> Freescale BSP works well without this.  It's probably not needed.

There is no guarantee, that there is no event pending. Especially not
when we shutdown the timer. And the observation that the Fleescale
stuff did not explode yet does not prove anything.
 
> > I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
> >
> I do not understand that.  The shift is used in clocksource_hz2mult() as below.
> 
> static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)

Use clocksource_register_hz() or clocksource_register_khz() and let
the clocksource code decide the shift and mult value.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 06/15] ARM: mxs: Add timer support
  2010-12-02 14:44     ` Shawn Guo
  2010-12-02 15:20       ` Thomas Gleixner
@ 2010-12-02 16:48       ` Uwe Kleine-König
  1 sibling, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn (and Thomas),

On Thu, Dec 02, 2010 at 10:44:06PM +0800, Shawn Guo wrote:
> >> +
> >> +static struct clocksource clocksource_mxs = {
> >> + ? ? .name ? ? ? ? ? = "mxs_timer",
> >> + ? ? .rating ? ? ? ? = 200,
> >> + ? ? .read ? ? ? ? ? = timrot_get_cycles,
> >> + ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
> >> + ? ? .shift ? ? ? ? ?= 10,
> >> + ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
> >> +};
> >> +
> >> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> >> +{
> >> + ? ? unsigned int c = clk_get_rate(timer_clk);
> >> +
> >> + ? ? if (timrot_is_v1())
> >> + ? ? ? ? ? ? clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> > I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
> >
> I do not understand that.  The shift is used in clocksource_hz2mult() as below.
> 
> static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
> {
>         /*  hz = cyc/(Billion ns)
>          *  mult/2^shift  = ns/cyc
>          *  mult = ns/cyc * 2^shift
>          *  mult = 1Billion/hz * 2^shift
>          *  mult = 1000000000 * 2^shift / hz
>          *  mult = (1000000000<<shift) / hz
>          */
>         u64 tmp = ((u64)1000000000) << shift_constant;
> 
>         tmp += hz/2; /* round for do_div */
>         do_div(tmp, hz);
> 
>         return (u32)tmp;
> }
> 
> The shift is working against the timers frequency (hz).  Should hz be
> the thing concerned here instead of timer bit width?  Since both MX23
> and MX28 timer are running at 32K, so shift value 10 is picked here.
Might be, it's some time ago that I dealt with the clock code.  After
rechecking I think you're right, but now I think 10 is too low :-)

In general a bigger shift increases accuracy at the cost of the range of
values that can be converted (from ticks to ns).  As a 16 bit counter
has a very limited range anyhow you can at least use a high accuracy
without loosing anything.

With shift=10 and tickrate=32k you get mult=0x1e84800, so the maximal
value that (theoretically) occurs is 0xffff * 0x1e84800 = 0x1e84617b800
which is far away from using the available 64 bits.  So (unless I'm
mistaken) the shift value using most of the 64 would be 33 but that
would overflow mult (which is only 32bit wide).  So I'd recommend 17
(resulting in mult=0xf4240000) for both the 16 and the 32 bit case.

Thomas, does this make sense?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-12-02 15:07   ` Uwe Kleine-König
@ 2010-12-03  5:07     ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-03  5:07 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
>> +
>> +/*
>> + * ref_clk
>> + */
>> +#define _CLK_GET_RATE_REF(name, sr, ss) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +static unsigned long name##_get_rate(struct clk *clk) ? ? ? ? ? ? ? ? ? ? ? ?\
>> +{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? unsigned long parent_rate; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? u32 reg, div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); ? ? ? ? \
>> + ? ? div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; ? ? ? ? ? ? \
>> + ? ? parent_rate = clk_get_rate(clk->parent); ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? return parent_rate * 18 / div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +}
>> +
>> +_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
>> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
>> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
>> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
>> +
>> +#define _DEFINE_CLOCK_REF(name, er, es) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? static struct clk name = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .enable_reg ? ? = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, ?\
>> + ? ? ? ? ? ? .enable_shift ? = BP_CLKCTRL_##er##_CLKGATE##es, ? ? ? ?\
>> + ? ? ? ? ? ? .get_rate ? ? ? = name##_get_rate, ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .enable ? ? ? ? = _raw_clk_enable, ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .disable ? ? ? ?= _raw_clk_disable, ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .parent ? ? ? ? = &pll_clk, ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? }
>> +
>> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
> What happens if get_clock_rate(ref_cpu_clk) is called?:
>
> ? ? ? ?ref_cpu_clk_get_rate
> ? ? ? ? ? ? ? ?reg = something
> ? ? ? ? ? ? ? ?div = something else
> ? ? ? ? ? ? ? ?parent_rate = clk_get_rate(clk->parent)
> ? ? ? ? ? ? ? ? ? ? ? ?= pll_clk_get_rate()
> ? ? ? ? ? ? ? ? ? ? ? ?= 480000000;
> ? ? ? ? ? ? ? ?return parent_rate * 18 / div
> ? ? ? ? ? ? ? ? ? ? ? ?= (480000000 * 18) / div
> ? ? ? ? ? ? ? ? ? ? ? ?= 0x202fbf000 / div
> ? ? ? ? ? ? ? ? ? ? ? ?= ...
>
> Note that 0x202fbf000 is too big for an unsigned long so (AFAIK) this is
> truncated to 0x02fbf000 / div which is wrong.
>
> The same overflow happens in at least one set_rate function, too.
>
> Either you have to switch to long long or (IMHO preferable) use shifted
> values.
>
Excellent catch.  It solved another issue that I ran into, which
caused by imprecise mdelay.

Thanks a million, Uwe.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
  2010-11-29  9:58             ` Uwe Kleine-König
@ 2010-12-06 16:13               ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-06 16:13 UTC (permalink / raw)
  To: linux-arm-kernel

[extended the audience, some context:  arch/arm/plat-mxc currently uses
a clk_enable in arch_reset which might sleep]

On Mon, Nov 29, 2010 at 10:58:33AM +0100, Uwe Kleine-K?nig wrote:
> Hello Lothar,
> 
> On Mon, Nov 29, 2010 at 10:25:34AM +0100, Lothar Wa?mann wrote:
> > arch_reset() may be called from interrupt context (e.g. induced by
> > SYSRQ-B), thus clk_get() and clk_enable() must not be called from
> > within arch_reset(). Move these calls to mxc_arch_reset_init().
> I wonder if SYSRQ-B is the only way to trigger that.  And if yes if that
> could be "fixed" to allow sleeping?!
Hmmm, the comment for emergency_restart() says:

/**
 *      emergency_restart - reboot the system
 *
 *      Without shutting down any hardware or taking any locks
 *      reboot the system.  This is called when we know we are in
 *      trouble so this is our best effort to reboot.  This is
 *      safe to call in interrupt context.
 */

emergency_restart has several callers apart from sysrq (watchdog, ocfs2,
kdb, panic), so I think allowing to sleep isn't that easy.

Moreover the sysrq function is called with the uart port's lock hold,
that would need fixing in the serial driver.  I found the same problem
in amba-pl011 (the only driver I checked), so this seems to be a big
task.  Sysrq holds a lock, too, while calling the handler.

I still think it's wrong to enable the watchdog clock unconditionally
during boot and wonder if that sleep in atomic can just be ignored?!

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-11-30 16:39   ` Uwe Kleine-König
@ 2010-12-07 13:09     ` Shawn Guo
  2010-12-07 13:33       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 13:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
>> Add clock for MXS-based SoCs, MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> ?arch/arm/mach-mxs/clock-mx23.c ? ? ? ? ?| ?521 ++++++++++++++++++++++
>> ?arch/arm/mach-mxs/clock-mx28.c ? ? ? ? ?| ?732 +++++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/clock.c ? ? ? ? ? ? ? | ?201 +++++++++
>> ?arch/arm/mach-mxs/include/mach/clkdev.h | ? ?7 +
>> ?arch/arm/mach-mxs/include/mach/clock.h ?| ? 64 +++
>> ?arch/arm/mach-mxs/regs-clkctrl-mx23.h ? | ?455 +++++++++++++++++++
>> ?arch/arm/mach-mxs/regs-clkctrl-mx28.h ? | ?663 ++++++++++++++++++++++++++++
>> ?7 files changed, 2643 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/clock-mx23.c
>> ?create mode 100644 arch/arm/mach-mxs/clock-mx28.c
>> ?create mode 100644 arch/arm/mach-mxs/clock.c
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
>> ?create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
>> ?create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
>>
>> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
>> new file mode 100644
>> index 0000000..832db0b
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/clock-mx23.c
>> @@ -0,0 +1,521 @@
>> +/*
>> + * Copyright (C) 2009-2010 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.,
>> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>> + */
>> +
>> +#include <linux/mm.h>
>> +#include <linux/delay.h>
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +
>> +#include <asm/clkdev.h>
>> +#include <asm/div64.h>
>> +
>> +#include <mach/hardware.h>
>> +#include <mach/common.h>
>> +#include <mach/clock.h>
>> +
>> +#include "regs-clkctrl-mx23.h"
>> +
>> +#define CLKCTRL_BASE_ADDR ? ?MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
>> +#define DIGCTRL_BASE_ADDR ? ?MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
>> +
>> +static int _raw_clk_enable(struct clk *clk)
>> +{
>> + ? ? u32 reg;
>> +
>> + ? ? if (clk->enable_reg) {
>> + ? ? ? ? ? ? reg = __raw_readl(clk->enable_reg);
>> + ? ? ? ? ? ? reg &= ~(1 << clk->enable_shift);
>> + ? ? ? ? ? ? __raw_writel(reg, clk->enable_reg);
>> + ? ? }
>> +
>> + ? ? return 0;
>> +}
> Hmm, I would have used an approach that is quickly switchable to the
> generic clock stuff posted a few times here. ?But probably already too
> late. ?So it's up to you to decide when to switch (or if at all).
>
I suppose you are talking about the common struct clk patch from
Jeremy Kerr.  Since mxs is closely tracking mxc, I would switch mxs
only mxc is switched.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-12-07 13:09     ` Shawn Guo
@ 2010-12-07 13:33       ` Uwe Kleine-König
  2010-12-07 13:53         ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 13:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

> > Hmm, I would have used an approach that is quickly switchable to the
> > generic clock stuff posted a few times here. ?But probably already too
> > late. ?So it's up to you to decide when to switch (or if at all).
> >
> I suppose you are talking about the common struct clk patch from
> Jeremy Kerr.  Since mxs is closely tracking mxc, I would switch mxs
> only mxc is switched.
I want mxc switched sooner rather than later.

If you ask me, don't stop to be inovative because of tracking mxc which
supports many machines and so isn't that flexible as a new machine
support.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH 09/15] ARM: mxs: Add clock support
  2010-12-07 13:33       ` Uwe Kleine-König
@ 2010-12-07 13:53         ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/7 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> > Hmm, I would have used an approach that is quickly switchable to the
>> > generic clock stuff posted a few times here. ?But probably already too
>> > late. ?So it's up to you to decide when to switch (or if at all).
>> >
>> I suppose you are talking about the common struct clk patch from
>> Jeremy Kerr. ?Since mxs is closely tracking mxc, I would switch mxs
>> only mxc is switched.
> I want mxc switched sooner rather than later.
>
> If you ask me, don't stop to be inovative because of tracking mxc which
> supports many machines and so isn't that flexible as a new machine
> support.
>
OK.  I will try to switch once Jeremy's bits get merged.  But can we
pick the current implementation on imx tree for now, and then switch
based off imx tree later?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 01/15] ARM: mxs: Add core definitions
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (20 preceding siblings ...)
  2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-07 20:18   ` Uwe Kleine-König
  2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
                   ` (24 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add core definitions for MXS-based SoC MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Update MXS_IO_P2V definition and comment to get them matched
 - Sort mx23 base address definitions by offset
 - Remove mx28 reserved IRQ definitions
 - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()

Changes for v2:
 - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
 - Simplify MXS_IO_P2V_MODULE definition in hardware.h
 - Remove unnecessary inclusion protection from hardware.h
 - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx

 arch/arm/mach-mxs/include/mach/hardware.h |   55 +++++++++
 arch/arm/mach-mxs/include/mach/irqs.h     |   32 +++++
 arch/arm/mach-mxs/include/mach/memory.h   |   24 ++++
 arch/arm/mach-mxs/include/mach/mx23.h     |  147 ++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mx28.h     |  190 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mxs.h      |   34 +++++
 6 files changed, 482 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h

diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..d73f149
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr)	(addr)
+#else
+#define IOMEM(addr)	((void __force __iomem *)(addr))
+#endif
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
+ *	IO	0x80000000+0x100000	->	0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x)	(0xf4000000 +					\
+			(((x) & 0x80000000) >> 7) +			\
+			(((x) & 0x000fffff)))
+
+
+#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type)	{				\
+	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
+	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
+	.length = soc ## _ ## name ## _SIZE,				\
+	.type = _type,							\
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS	128
+
+#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS		(32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS		16
+
+#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET		UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..2033ed4
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR		0x00000000
+#define MX23_OCRAM_SIZE			SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR		0x80000000
+#define MX23_IO_SIZE			SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART			0
+#define MX23_INT_COMMS_RX		1
+#define MX23_INT_COMMS_TX		1
+#define MX23_INT_SSP2_ERROR		2
+#define MX23_INT_VDD5V			3
+#define MX23_INT_HEADPHONE_SHORT	4
+#define MX23_INT_DAC_DMA		5
+#define MX23_INT_DAC_ERROR		6
+#define MX23_INT_ADC_DMA		7
+#define MX23_INT_ADC_ERROR		8
+#define MX23_INT_SPDIF_DMA		9
+#define MX23_INT_SAIF2_DMA		9
+#define MX23_INT_SPDIF_ERROR		10
+#define MX23_INT_SAIF1_IRQ		10
+#define MX23_INT_SAIF2_IRQ		10
+#define MX23_INT_USB_CTRL		11
+#define MX23_INT_USB_WAKEUP		12
+#define MX23_INT_GPMI_DMA		13
+#define MX23_INT_SSP1_DMA		14
+#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_GPIO0			16
+#define MX23_INT_GPIO1			17
+#define MX23_INT_GPIO2			18
+#define MX23_INT_SAIF1_DMA		19
+#define MX23_INT_SSP2_DMA		20
+#define MX23_INT_ECC8_IRQ		21
+#define MX23_INT_RTC_ALARM		22
+#define MX23_INT_UARTAPP_TX_DMA		23
+#define MX23_INT_UARTAPP_INTERNAL	24
+#define MX23_INT_UARTAPP_RX_DMA		25
+#define MX23_INT_I2C_DMA		26
+#define MX23_INT_I2C_ERROR		27
+#define MX23_INT_TIMER0			28
+#define MX23_INT_TIMER1			29
+#define MX23_INT_TIMER2			30
+#define MX23_INT_TIMER3			31
+#define MX23_INT_BATT_BRNOUT		32
+#define MX23_INT_VDDD_BRNOUT		33
+#define MX23_INT_VDDIO_BRNOUT		34
+#define MX23_INT_VDD18_BRNOUT		35
+#define MX23_INT_TOUCH_DETECT		36
+#define MX23_INT_LRADC_CH0		37
+#define MX23_INT_LRADC_CH1		38
+#define MX23_INT_LRADC_CH2		39
+#define MX23_INT_LRADC_CH3		40
+#define MX23_INT_LRADC_CH4		41
+#define MX23_INT_LRADC_CH5		42
+#define MX23_INT_LRADC_CH6		43
+#define MX23_INT_LRADC_CH7		44
+#define MX23_INT_LCDIF_DMA		45
+#define MX23_INT_LCDIF_ERROR		46
+#define MX23_INT_DIGCTL_DEBUG_TRAP	47
+#define MX23_INT_RTC_1MSEC		48
+#define MX23_INT_DRI_DMA		49
+#define MX23_INT_DRI_ATTENTION		50
+#define MX23_INT_GPMI_ATTENTION		51
+#define MX23_INT_IR			52
+#define MX23_INT_DCP_VMI		53
+#define MX23_INT_DCP			54
+#define MX23_INT_BCH			56
+#define MX23_INT_PXP			57
+#define MX23_INT_UARTAPP2_TX_DMA	58
+#define MX23_INT_UARTAPP2_INTERNAL	59
+#define MX23_INT_UARTAPP2_RX_DMA	60
+#define MX23_INT_VDAC_DETECT		61
+#define MX23_INT_VDD5V_DROOP		64
+#define MX23_INT_DCDC4P2_BO		65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..be1c2a4
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR		0x00000000
+#define MX28_OCRAM_SIZE			SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR		0x80000000
+#define MX28_IO_SIZE			SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT		0
+#define MX28_INT_VDDD_BRNOUT		1
+#define MX28_INT_VDDIO_BRNOUT		2
+#define MX28_INT_VDDA_BRNOUT		3
+#define MX28_INT_VDD5V_DROOP		4
+#define MX28_INT_DCDC4P2_BRNOUT		5
+#define MX28_INT_VDD5V			6
+#define MX28_INT_CAN0			8
+#define MX28_INT_CAN1			9
+#define MX28_INT_LRADC_TOUCH		10
+#define MX28_INT_HSADC			13
+#define MX28_INT_IRADC_THRESH0		14
+#define MX28_INT_IRADC_THRESH1		15
+#define MX28_INT_LRADC_CH0		16
+#define MX28_INT_LRADC_CH1		17
+#define MX28_INT_LRADC_CH2		18
+#define MX28_INT_LRADC_CH3		19
+#define MX28_INT_LRADC_CH4		20
+#define MX28_INT_LRADC_CH5		21
+#define MX28_INT_LRADC_CH6		22
+#define MX28_INT_LRADC_CH7		23
+#define MX28_INT_LRADC_BUTTON0		24
+#define MX28_INT_LRADC_BUTTON1		25
+#define MX28_INT_PERFMON		27
+#define MX28_INT_RTC_1MSEC		28
+#define MX28_INT_RTC_ALARM		29
+#define MX28_INT_COMMS			31
+#define MX28_INT_EMI_ERR		32
+#define MX28_INT_LCDIF			38
+#define MX28_INT_PXP			39
+#define MX28_INT_BCH			41
+#define MX28_INT_GPMI			42
+#define MX28_INT_SPDIF_ERROR		45
+#define MX28_INT_DUART			47
+#define MX28_INT_TIMER0			48
+#define MX28_INT_TIMER1			49
+#define MX28_INT_TIMER2			50
+#define MX28_INT_TIMER3			51
+#define MX28_INT_DCP_VMI		52
+#define MX28_INT_DCP			53
+#define MX28_INT_DCP_SECURE		54
+#define MX28_INT_SAIF1			58
+#define MX28_INT_SAIF0			59
+#define MX28_INT_SPDIF_DMA		66
+#define MX28_INT_I2C0_DMA		68
+#define MX28_INT_I2C1_DMA		69
+#define MX28_INT_AUART0_RX_DMA		70
+#define MX28_INT_AUART0_TX_DMA		71
+#define MX28_INT_AUART1_RX_DMA		72
+#define MX28_INT_AUART1_TX_DMA		73
+#define MX28_INT_AUART2_RX_DMA		74
+#define MX28_INT_AUART2_TX_DMA		75
+#define MX28_INT_AUART3_RX_DMA		76
+#define MX28_INT_AUART3_TX_DMA		77
+#define MX28_INT_AUART4_RX_DMA		78
+#define MX28_INT_AUART4_TX_DMA		79
+#define MX28_INT_SAIF0_DMA		80
+#define MX28_INT_SAIF1_DMA		81
+#define MX28_INT_SSP0_DMA		82
+#define MX28_INT_SSP1_DMA		83
+#define MX28_INT_SSP2_DMA		84
+#define MX28_INT_SSP3_DMA		85
+#define MX28_INT_LCDIF_DMA		86
+#define MX28_INT_HSADC_DMA		87
+#define MX28_INT_GPMI_DMA		88
+#define MX28_INT_DIGCTL_DEBUG_TRAP	89
+#define MX28_INT_USB1			92
+#define MX28_INT_USB0			93
+#define MX28_INT_USB1_WAKEUP		94
+#define MX28_INT_USB0_WAKEUP		95
+#define MX28_INT_SSP0			96
+#define MX28_INT_SSP1			97
+#define MX28_INT_SSP2			98
+#define MX28_INT_SSP3			99
+#define MX28_INT_ENET_SWI		100
+#define MX28_INT_ENET_MAC0		101
+#define MX28_INT_ENET_MAC1		102
+#define MX28_INT_ENET_MAC0_1588		103
+#define MX28_INT_ENET_MAC1_1588		104
+#define MX28_INT_I2C1_ERROR		110
+#define MX28_INT_I2C0_ERROR		111
+#define MX28_INT_AUART0			112
+#define MX28_INT_AUART1			113
+#define MX28_INT_AUART2			114
+#define MX28_INT_AUART3			115
+#define MX28_INT_AUART4			116
+#define MX28_INT_GPIO4			123
+#define MX28_INT_GPIO3			124
+#define MX28_INT_GPIO2			125
+#define MX28_INT_GPIO1			126
+#define MX28_INT_GPIO0			127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..13e06ae
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+
+#define MXS_SET_ADDR		0x4
+#define MXS_CLR_ADDR		0x8
+#define MXS_TOG_ADDR		0xc
+
+/*
+ * MXS CPU types
+ */
+# define cpu_is_mx23()		(machine_is_mx23evk())
+# define cpu_is_mx28()		(machine_is_mx28evk())
+
+#endif /* __MACH_MXS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (21 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-07 20:27   ` Uwe Kleine-König
  2010-12-08  7:33   ` Lothar Waßmann
  2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
                   ` (23 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

 - The mxs wdog is implemented in RTC block.
 - There is a generic software reset routine for most modules on mxs.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Change wdog timeout to 10ms for safety
 - Simplify function mxs_reset_block() to get it look better

Changes for v2:
 - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()

 arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
 arch/arm/mach-mxs/system.c              |  134 +++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/system.h
 create mode 100644 arch/arm/mach-mxs/system.c

diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..58cb044
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG	0x50
+#define MXS_WATCHDOG_EN		(1 << 4)
+
+#define MXS_MODULE_CLKGATE	(1 << 30)
+#define MXS_MODULE_SFTRST	(1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+	/* Set wdog timer 10 ms */
+	__raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
+
+	/* Enable wdog reset */
+	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+	/* Wait for reset to assert... */
+	mdelay(10);
+
+	pr_err("Watchdog reset failed to assert reset\n");
+
+	/* Delay to allow the serial port to show the message */
+	mdelay(50);
+
+	/* We'll take a jump through zero as a poor second */
+	cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+	struct clk *clk;
+
+	wdog_base = base;
+
+	clk = clk_get_sys("rtc", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+}
+
+/*
+ * Clear the bit and poll it cleared.  This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+	int timeout = 0x400;
+
+	/* clear the bit */
+	__raw_writel(mask, addr + MXS_CLR_ADDR);
+
+	/*
+	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
+	 * recommends to wait 1us.
+	 */
+	udelay(1);
+
+	/* poll the bit becoming clear */
+	while ((__raw_readl(addr) & mask) && --timeout)
+		/* nothing */;
+
+	return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+	int ret;
+	int timeout = 0x400;
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+	if (ret)
+		goto error;
+
+	/* clear CLKGATE */
+	__raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+	/* set SFTRST to reset the block */
+	__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
+	udelay(1);
+	/* poll CLKGATE becoming set */
+	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+		/* nothing */;
+	if (unlikely(!timeout))
+		goto error;
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+	if (ret)
+		goto error;
+
+	/* clear and poll CLKGATE */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+	if (ret)
+		goto error;
+
+	return 0;
+
+error:
+	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+	return -ETIMEDOUT;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (22 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-07 21:03   ` Uwe Kleine-König
  2010-12-08  8:24   ` Lothar Waßmann
  2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
                   ` (22 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add Interrupt Collector (ICOLL) support for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Get icoll base in get_irqnr_preamble
 - Check the case of single SoC build and use hard-coding address if possible

 arch/arm/mach-mxs/icoll.c                    |   77 ++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/entry-macro.S |   44 +++++++++++++++
 2 files changed, 121 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/icoll.c
 create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S

diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..a7a7d4f
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR				0x0000
+#define HW_ICOLL_LEVELACK			0x0010
+#define HW_ICOLL_CTRL				0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
+
+void __iomem *icoll_base;
+
+static void icoll_ack_irq(unsigned int irq)
+{
+	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
+
+	/* ACK current interrupt (level 0) */
+	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+			icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+	.ack = icoll_ack_irq,
+	.mask = icoll_mask_irq,
+	.unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void __iomem *irqbase)
+{
+	int i;
+
+	icoll_base = irqbase;
+
+	/* Reset icoll */
+	mxs_reset_block(irqbase + HW_ICOLL_CTRL);
+
+	for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxs_icoll_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..2c7755b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,44 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/hardware.h>
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\irqnr, [\base, #0x70]
+	cmp	\irqnr, #0x7F
+	moveqs	\irqnr, #0
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
+	ldr	\base, =icoll_base
+	ldr	\base, [\base]
+#elif defined (CONFIG_SOC_IMX23)
+	ldr	\base, =MX23_ICOLL_BASE_ADDR
+#else
+	ldr	\base, =MX28_ICOLL_BASE_ADDR
+#endif
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (23 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-08 20:27   ` Uwe Kleine-König
  2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
                   ` (21 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

 - DEBUG_LL support, which is incompatible with single MXS image
   because of different DUART base address on MX23 and MX28
 - uncompress message support

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove incorrect comments

 arch/arm/mach-mxs/include/mach/debug-macro.S |   51 +++++++++++++++++
 arch/arm/mach-mxs/include/mach/uncompress.h  |   78 ++++++++++++++++++++++++++
 2 files changed, 129 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h

diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..efb3173
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,51 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/hardware.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR)
+
+		.macro	addruart, rp, rv
+		ldr	\rp, =UART_PADDR	@ physical
+		ldr	\rv, =UART_VADDR	@ virtual
+		.endm
+
+		.macro	senduart, rd, rx
+		str	\rd, [\rx, #0x0]	@ DR
+		.endm
+
+		.macro	waituart, rd, rx
+1001:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 5		@ FR_TXFF
+		bne	1001b
+		.endm
+
+		.macro	busyuart, rd, rx
+1002:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 3		@ FR_BUSY
+		beq	1002b
+		.endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..efdacc7
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,78 @@
+/*
+ *  arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) Shane Nay (shane@minirl.com)
+ *  Copyright 2010 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#define __MXS_BOOT_UNCOMPRESS
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define DR		0x00
+#define FR		0x18
+#define FR_BUSY		(1 << 3)
+#define FR_TXFE		(1 << 7)
+#define CR		0x30
+#define CR_UARTEN	1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.
+ */
+
+static void putc(int ch)
+{
+	if (!uart_base)
+		return;
+	if (!(UART(CR) & CR_UARTEN))
+		return;
+
+	while (!(UART(FR) & FR_TXFE))
+		barrier();
+
+	UART(DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR	0x80070000
+#define MX28_DUART_BASE_ADDR	0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+	switch (arch_id) {
+	case MACH_TYPE_MX23EVK:
+		uart_base = MX23_DUART_BASE_ADDR;
+		break;
+	case MACH_TYPE_MX28EVK:
+		uart_base = MX28_DUART_BASE_ADDR;
+		break;
+	default:
+		break;
+	}
+}
+
+#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (24 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-07 21:18   ` Uwe Kleine-König
  2010-12-08  8:30   ` Lothar Waßmann
  2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
                   ` (20 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.

As the result, we need two instances of timers with v1 for better
implementation, one for clock_event and another for clocksource.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Use term clock_event over next_event and clocksource over get_cycles
 - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
 - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
 - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
 - Skip flag IRQF_DISABLED
 - Remove unncessary IRQ disabling in mxs_set_mode()
 - Change shift of clocksource_mxs to 17

Changes for v2:
 - Fix a bug in timrot_set_next_event(). It should read
   HW_TIMROT_RUNNING_COUNTn to get the current counts.

 arch/arm/mach-mxs/timer.c |  276 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 276 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/timer.c

diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..b0e7ffe
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,276 @@
+/*
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for clock_event and another for clocksource. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1()	(cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL			0x00
+#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n)		(0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE		(1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT		0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL	0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL	0xb
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+	return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+			& 0xffff0000) >> 16);
+}
+
+static cycle_t timrotv2_get_cycles(struct clocksource *cs)
+{
+	return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	/* timrot decrements the count */
+	__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+
+	return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	unsigned long match;
+
+	/* timrot decrements the count */
+	match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
+			- evt;
+	__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+	return (int)(match - __raw_readl(timer_base +
+			HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &clockevent_mxs;
+
+	timrot_irq_acknowledge();
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+	.name		= "MXS Timer Tick",
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	/* Disable interrupt in timer module */
+	timrot_irq_disable();
+
+	if (mode != clockevent_mode) {
+		/* Set event time into far-far future */
+		__raw_writel(__raw_readl(timer_base +
+				HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+				timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+		/* Clear pending interrupt */
+		timrot_irq_acknowledge();
+	}
+
+#ifdef DEBUG
+	printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+		clock_event_mode_label[clockevent_mode],
+		clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+	/* Remember timer mode */
+	clockevent_mode = mode;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+				"supported for MXS-based\n");
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		timrot_irq_enable();
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_mxs = {
+	.name		= "mxs_timrot",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_mode	= mxs_set_mode,
+	.set_next_event	= timrotv2_set_next_event,
+	.rating		= 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+	clockevent_mxs.cpumask = cpumask_of(0);
+	if (timrot_is_v1()) {
+		clockevent_mxs.set_next_event = timrotv1_set_next_event;
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xf, &clockevent_mxs);
+	} else {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xff, &clockevent_mxs);
+	}
+
+	clockevents_register_device(&clockevent_mxs);
+
+	return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+	.name 		= "mxs_timer",
+	.rating		= 200,
+	.read		= timrotv2_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift 		= 17,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	if (timrot_is_v1()) {
+		clocksource_mxs.read = timrotv1_get_cycles;
+		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+	}
+	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+	clocksource_register(&clocksource_mxs);
+
+	return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+				void __iomem *base, int irq)
+{
+	clk_enable(timer_clk);
+
+	timer_base = base;
+
+	/*
+	 * Initialize timers to a known state
+	 */
+	mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+	if (timrot_is_v1()) {
+		/* timer0 is for clock_event */
+		__raw_writel(
+			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_UPDATE |
+			BM_TIMROT_TIMCTRLn_IRQ_EN,
+			base + HW_TIMROT_TIMCTRLn(0));
+		/* timer1 is for clocksource */
+		__raw_writel(
+			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_RELOAD,
+			base + HW_TIMROT_TIMCTRLn(1));
+		__raw_writel(0xffff, timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
+
+	} else {
+		__raw_writel(
+			BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRLn_IRQ_EN |
+			BM_TIMROT_TIMCTRLn_MATCH_MODE,
+			timer_base + HW_TIMROT_TIMCTRLn(0));
+	}
+
+	/* init and register the timer to the framework */
+	mxs_clocksource_init(timer_clk);
+	mxs_clockevent_init(timer_clk);
+
+	/* Make irqs happen */
+	setup_irq(irq, &mxs_timer_irq);
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 07/15] ARM: mxs: Add gpio support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (25 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-08  7:21   ` Lothar Waßmann
  2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
                   ` (19 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implement gpio support in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
 - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
 - Remove both edges IRQ support which is not needed
 - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
 - Use pr_info over printk(KERN_INFO)

 arch/arm/mach-mxs/gpio.c              |  331 +++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/gpio.h              |   36 ++++
 arch/arm/mach-mxs/include/mach/gpio.h |   35 ++++
 3 files changed, 402 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/gpio.c
 create mode 100644 arch/arm/mach-mxs/gpio.h
 create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h

diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..6db7541
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,331 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n)		((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n)		((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n)		((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n)	((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n)	((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n)	((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n)	((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n)	((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE	0x0
+#define GPIO_INT_LOW_LEV	0x1
+#define GPIO_INT_RISE_EDGE	0x2
+#define GPIO_INT_HIGH_LEV	0x3
+#define GPIO_INT_LEV_MASK	(1 << 0)
+#define GPIO_INT_POL_MASK	(1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+	__raw_writel(1 << index,
+			port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+				int enable)
+{
+	if (enable == 0) {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+	} else {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+	}
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+	u32 gpio = irq_to_gpio(irq);
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+	int edge;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		edge = GPIO_INT_RISE_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		edge = GPIO_INT_FALL_EDGE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		edge = GPIO_INT_LOW_LEV;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		edge = GPIO_INT_HIGH_LEV;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set level or edge */
+	if (edge & GPIO_INT_LEV_MASK)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+	/* set polarity */
+	if (edge & GPIO_INT_POL_MASK)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+	_clear_gpio_irqstatus(port, gpio & 0x1f);
+
+	return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_stat;
+	struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+	u32 gpio_irq_no_base = port->virtual_irq_start;
+
+	irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+			__raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+			__raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
+		irq_stat &= ~(1 << irqoffset);
+	}
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+	u32 gpio = irq_to_gpio(irq);
+	u32 gpio_idx = gpio & 0x1f;
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+	if (enable) {
+		if (port->irq_high && (gpio_idx >= 16))
+			enable_irq_wake(port->irq_high);
+		else
+			enable_irq_wake(port->irq);
+	} else {
+		if (port->irq_high && (gpio_idx >= 16))
+			disable_irq_wake(port->irq_high);
+		else
+			disable_irq_wake(port->irq);
+	}
+
+	return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.ack = gpio_ack_irq,
+	.mask = gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+	.set_type = gpio_set_irq_type,
+	.set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+				int dir)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+	if (dir)
+		__raw_writel(1 << offset,
+			port->base + PINCTRL_DOE(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << offset,
+			port->base + PINCTRL_DOE(port->id) + MXS_CLR_ADDR);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	u32 l;
+	unsigned long flags;
+	void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
+
+	spin_lock_irqsave(&port->lock, flags);
+	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
+	__raw_writel(l, reg);
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+	void __iomem *reg = port->base + PINCTRL_DIN(port->id);
+
+	return (__raw_readl(reg) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	_set_gpio_direction(chip, offset, 0);
+	return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	mxs_gpio_set(chip, offset, value);
+	_set_gpio_direction(chip, offset, 1);
+	return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+	int i, j;
+
+	/* save for local usage */
+	mxs_gpio_ports = port;
+	gpio_table_size = cnt;
+
+	pr_info("MXS GPIO hardware\n");
+
+	for (i = 0; i < cnt; i++) {
+		/* disable the interrupt and clear the status */
+		__raw_writel(0, port[i].base +
+				PINCTRL_PIN2IRQ(i));
+		__raw_writel(0, port[i].base +
+				PINCTRL_IRQEN(i));
+		__raw_writel(~0, port[i].base +
+				PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+		for (j = port[i].virtual_irq_start;
+			j < port[i].virtual_irq_start + 32; j++) {
+			set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, handle_level_irq);
+			set_irq_flags(j, IRQF_VALID);
+		}
+
+		/* register gpio chip */
+		port[i].chip.direction_input = mxs_gpio_direction_input;
+		port[i].chip.direction_output = mxs_gpio_direction_output;
+		port[i].chip.get = mxs_gpio_get;
+		port[i].chip.set = mxs_gpio_set;
+		port[i].chip.base = i * 32;
+		port[i].chip.ngpio = 32;
+
+		spin_lock_init(&port[i].lock);
+
+		/* its a serious configuration bug when it fails */
+		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+		/* setup one handler for each entry */
+		set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+		set_irq_data(port[i].irq, &port[i]);
+	}
+
+	return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id)					\
+	{								\
+		.chip.label = "gpio-" #_id,				\
+		.id = _id,						\
+		.irq = soc ## _INT_GPIO ## _id,				\
+		.base = soc ## _IO_ADDRESS(				\
+				soc ## _PINCTRL ## _BASE_ADDR),		\
+		.virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,	\
+	}
+
+#define DEFINE_REGISTER_FUNCTION(prefix)				\
+int __init prefix ## _register_gpios(void)				\
+{									\
+	return mxs_gpio_init(prefix ## _gpio_ports,			\
+			ARRAY_SIZE(prefix ## _gpio_ports));		\
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX23, 0),
+	DEFINE_MXS_GPIO_PORT(MX23, 1),
+	DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX28, 0),
+	DEFINE_MXS_GPIO_PORT(MX28, 1),
+	DEFINE_MXS_GPIO_PORT(MX28, 2),
+	DEFINE_MXS_GPIO_PORT(MX28, 3),
+	DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 0000000..e469281
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+#include <linux/spinlock.h>
+
+struct mxs_gpio_port {
+	void __iomem *base;
+	int id;
+	int irq;
+	int irq_high;
+	int virtual_irq_start;
+	struct gpio_chip chip;
+	spinlock_t lock;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..a743e3a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr)	((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value		__gpio_get_value
+#define gpio_set_value		__gpio_set_value
+#define gpio_cansleep		__gpio_cansleep
+
+#define gpio_to_irq(gpio)	(MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq)	((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (26 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-08  7:25   ` Lothar Waßmann
  2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
                   ` (18 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implements iomux functions in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Define iomux_cfg_t as u64
 - Turn mxs_iomux_setup_pad() into a static function
 - Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.

 arch/arm/mach-mxs/include/mach/iomux-mx23.h |   29 +++++++
 arch/arm/mach-mxs/include/mach/iomux-mx28.h |   44 +++++++++++
 arch/arm/mach-mxs/include/mach/iomux.h      |   72 +++++++++++++++++
 arch/arm/mach-mxs/iomux.c                   |  110 +++++++++++++++++++++++++++
 4 files changed, 255 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
 create mode 100644 arch/arm/mach-mxs/iomux.c

diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX			IOMUX_PAD(1, 26, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX			IOMUX_PAD(1, 27, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..ca37a15
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..91de8e7
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *			<armlinux@phytec.de>
+ * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+typedef struct pad_desc {
+	unsigned bank:12;
+	unsigned pin:20;
+	unsigned muxsel:8;
+	unsigned ma:12;
+	unsigned vol:8;
+	unsigned pull:4;
+} iomux_cfg_t;
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)	\
+		{						\
+			.bank	= _bank,			\
+			.pin	= _pin,				\
+			.muxsel	= _muxsel,			\
+			.vol	= _vol,				\
+			.ma	= _ma,				\
+			.pull	= _pull,			\
+		}
+
+#define PAD_MUXSEL_0		0
+#define PAD_MUXSEL_1		1
+#define PAD_MUXSEL_2		2
+#define PAD_MUXSEL_GPIO		3
+
+#define PAD_1V8			0
+#define PAD_3V3			1
+#define PAD_VOL_NONE		2
+
+#define PAD_4MA			0
+#define PAD_8MA			1
+#define PAD_12MA		2
+#define PAD_16MA		3
+#define PAD_MA_NONE		4
+
+#define PAD_NOPULL		0
+#define PAD_PULL		1
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxs_iomux_init(void __iomem *iomux_base);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..e6ebb0d
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *                       <armlinux@phytec.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/iomux.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+static int mxs_iomux_setup_pad(iomux_cfg_t *pad)
+{
+	u32 reg, ofs, bp, bm;
+
+	/* muxsel */
+	ofs = 0x100;
+	ofs += pad->bank * 0x20 + pad->pin / 16 * 0x10;
+	bp = pad->pin % 16 * 2;
+	bm = 0x3 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->muxsel << bp;
+	__raw_writel(reg, base + ofs);
+
+	/* drive */
+	ofs = cpu_is_mx23() ? 0x200 : 0x300;
+	ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
+	/* ma */
+	if (pad->ma != PAD_MA_NONE)
+	{
+		bp = pad->pin % 8 * 4;
+		bm = 0x3 << bp;
+		reg = __raw_readl(base + ofs);
+		reg &= ~bm;
+		reg |= pad->ma << bp;
+		__raw_writel(reg, base + ofs);
+	}
+	/* vol */
+	if (pad->vol != PAD_VOL_NONE)
+	{
+		bp = pad->pin % 8 * 4 + 2;
+		bm = 0x1 << bp;
+		reg = __raw_readl(base + ofs);
+		reg &= ~bm;
+		reg |= pad->vol << bp;
+		__raw_writel(reg, base + ofs);
+	}
+
+	/* pull */
+	ofs = cpu_is_mx23() ? 0x400 : 0x600;
+	ofs += pad->bank * 0x10;
+	bp = pad->pin;
+	bm = 0x1 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->pull << bp;
+	__raw_writel(reg, base + ofs);
+
+	return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+{
+	iomux_cfg_t *p = pad_list;
+	int i;
+	int ret;
+
+	for (i = 0; i < count; i++) {
+		ret = mxs_iomux_setup_pad(p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
+
+void mxs_iomux_init(void __iomem *iomux_base)
+{
+	base = iomux_base;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (27 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
  2010-12-08 20:57   ` Uwe Kleine-König
  2010-12-09  8:41   ` Uwe Kleine-König
  2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
                   ` (17 subsequent siblings)
  46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Add clock for MXS-based SoCs, MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
 - Fix fec_clk to stand for fec clock than IEEE1588 time clock
 - Add pll2_clk into clock lookups, as it's fec phy clock and needs to be on before reset phy

 arch/arm/mach-mxs/clock-mx23.c          |  521 ++++++++++++++++++++++
 arch/arm/mach-mxs/clock-mx28.c          |  731 +++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/clock.c               |  201 +++++++++
 arch/arm/mach-mxs/include/mach/clkdev.h |    7 +
 arch/arm/mach-mxs/include/mach/clock.h  |   64 +++
 arch/arm/mach-mxs/regs-clkctrl-mx23.h   |  455 +++++++++++++++++++
 arch/arm/mach-mxs/regs-clkctrl-mx28.h   |  663 ++++++++++++++++++++++++++++
 7 files changed, 2642 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/clock-mx23.c
 create mode 100644 arch/arm/mach-mxs/clock-mx28.c
 create mode 100644 arch/arm/mach-mxs/clock.c
 create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..832db0b
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+	/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+	 * and is incorrect (excessive). Per definition of the PLLCTRL0
+	 * POWER field, waiting at least 10us.
+	 */
+	udelay(10);
+
+	return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+	 .get_rate = pll_clk_get_rate,
+	 .enable = pll_clk_enable,
+	 .disable = pll_clk_disable,
+	 .parent = &ref_xtal_clk,
+};
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return parent_rate * 18 / div;					\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, bm_busy, div_max, d, f, div, frac;
+	unsigned long diff, parent_rate, calc_rate;
+	int i;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &ref_xtal_clk) {
+		div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+		div = DIV_ROUND_UP(parent_rate, rate);
+		if (div == 0 || div > div_max)
+			return -EINVAL;
+	} else {
+		div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+		div = frac = 1;
+		diff = parent_rate;
+		for (d = 1; d <= div_max; d++) {
+			f = parent_rate * 18 / d / rate;
+			if ((parent_rate * 18 / d) % rate)
+				f++;
+			if (f < 18 || f > 35)
+				continue;
+
+			calc_rate = parent_rate * 18 / f / d;
+			if (calc_rate > rate)
+				continue;
+
+			if (rate - calc_rate < diff) {
+				frac = f;
+				div = d;
+				diff = rate - calc_rate;
+			}
+
+			if (diff == 0)
+				break;
+		}
+
+		if (diff == parent_rate)
+			return -EINVAL;
+
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+		reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+		reg |= frac;
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	}
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+	reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+	reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+					HW_CLKCTRL_CPU) & bm_busy))
+			break;
+	if (!i)	{
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+#define _CLK_SET_RATE(name, dr)						\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "usb", usb_clk)
+	_REGISTER_CLOCK(NULL, "audio", audio_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+			&ref_xtal_clk : &ref_io_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_io_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+			&ref_xtal_clk : &ref_pix_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+	reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+	reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX23_IO_ADDRESS(MX23_TIMROT_BASE_ADDR),
+			MX23_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..9c0abe1
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,731 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+	return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g)					\
+static int name##_enable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	udelay(10);							\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+									\
+	return 0;							\
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g)					\
+static void name##_disable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name)						\
+	static struct clk name = {					\
+		.get_rate	= name##_get_rate,			\
+		.enable		= name##_enable,			\
+		.disable	= name##_disable,			\
+		.parent		= &ref_xtal_clk,			\
+	}
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return parent_rate / 1000 * 18 / div * 1000;			\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll0_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	if (clk == &saif0_clk || clk == &saif1_clk)			\
+		return (clk_get_rate(clk->parent) >> 16 * div);		\
+	else								\
+		return clk_get_rate(clk->parent) / div;			\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+_CLK_GET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV	0
+#define BP_CLKCTRL_CPU_DIV	0
+#define BM_CLKCTRL_CPU_BUSY	0
+
+#define _CLK_SET_RATE(name, dr, fr, fs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, bm_busy, div_max, d, f, div, frac;			\
+	unsigned long diff, parent_rate, calc_rate;			\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+	bm_busy = BM_CLKCTRL_##dr##_BUSY;				\
+									\
+	if (clk->parent == &ref_xtal_clk) {				\
+		div = DIV_ROUND_UP(parent_rate, rate);			\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_XTAL >>		\
+				BP_CLKCTRL_CPU_DIV_XTAL;		\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;		\
+		}							\
+		if (div == 0 || div > div_max)				\
+			return -EINVAL;					\
+	} else {							\
+		rate /= 1000;						\
+		parent_rate /= 1000;					\
+		diff = parent_rate;					\
+		div = frac = 1;						\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_CPU >>		\
+				BP_CLKCTRL_CPU_DIV_CPU;			\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;		\
+		}							\
+		for (d = 1; d <= div_max; d++) {			\
+			f = parent_rate * 18 / d / rate;		\
+			if ((parent_rate * 18 / d) % rate)		\
+				f++;					\
+			if (f < 18 || f > 35)				\
+				continue;				\
+									\
+			calc_rate = parent_rate * 18 / f / d;		\
+			if (calc_rate > rate)				\
+				continue;				\
+									\
+			if (rate - calc_rate < diff) {			\
+				frac = f;				\
+				div = d;				\
+				diff = rate - calc_rate;		\
+			}						\
+									\
+			if (diff == 0)					\
+				break;					\
+		}							\
+									\
+		if (diff == parent_rate)				\
+			return -EINVAL;					\
+									\
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+		reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC;			\
+		reg |= frac;						\
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+	}								\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	if (clk == &cpu_clk) {						\
+		reg &= ~BM_CLKCTRL_CPU_DIV_CPU;				\
+		reg |= div << BP_CLKCTRL_CPU_DIV_CPU;			\
+	} else {							\
+		reg &= ~BM_CLKCTRL_##dr##_DIV;				\
+		reg |= div << BP_CLKCTRL_##dr##_DIV;			\
+		if (reg | (1 << clk->enable_shift)) {			\
+			pr_err("%s: clock is gated\n", __func__);	\
+			return -EINVAL;					\
+		}							\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & bm_busy))			\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u16 div;							\
+	u32 reg;							\
+	u64 lrate;							\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	if (rate > parent_rate)						\
+		return -EINVAL;						\
+									\
+	lrate = (u64)rate << 16;					\
+	do_div(lrate, parent_rate);					\
+	div = (u16)lrate;						\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	reg &= ~BM_CLKCTRL_##rs##_DIV;					\
+	reg |= div << BP_CLKCTRL_##rs##_DIV;				\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))	\
+			break;						\
+	if (!i) {							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+_CLK_SET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+	.get_rate = lradc_clk_get_rate,
+	.parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 16,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "can0", can0_clk)
+	_REGISTER_CLOCK(NULL, "can1", can1_clk)
+	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+	_REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+			&ref_xtal_clk : &ref_pix_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_gpmi_clk;
+	saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+			&ref_xtal_clk : &pll0_clk;
+	saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+			&ref_xtal_clk : &pll0_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+	reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+	reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+	reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+	reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+	reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+	/* SAIF has to use frac div for functional operation */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+	reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+	reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	/* Extra fec clock setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg &= ~BM_CLKCTRL_ENET_SLEEP;
+	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+			MX28_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e262759
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,201 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+	WARN_ON(!clk->usecount);
+
+	if (!(--clk->usecount)) {
+		if (clk->disable)
+			clk->disable(clk);
+		__clk_disable(clk->parent);
+		__clk_disable(clk->secondary);
+	}
+}
+
+static int __clk_enable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	if (clk->usecount++ == 0) {
+		__clk_enable(clk->parent);
+		__clk_enable(clk->secondary);
+
+		if (clk->enable)
+			clk->enable(clk);
+	}
+	return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	ret = __clk_enable(clk);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
+	mutex_lock(&clocks_mutex);
+	__clk_disable(clk);
+	mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return 0UL;
+
+	if (clk->get_rate)
+		return clk->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+		return 0;
+
+	return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+		return ret;
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_rate(clk, rate);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -EINVAL;
+	struct clk *old;
+
+	if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+	    IS_ERR(parent) || clk->set_parent == NULL)
+		return ret;
+
+	if (clk->usecount)
+		clk_enable(parent);
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_parent(clk, parent);
+	if (ret == 0) {
+		old = clk->parent;
+		clk->parent = parent;
+	} else {
+		old = parent;
+	}
+	mutex_unlock(&clocks_mutex);
+
+	if (clk->usecount)
+		clk_disable(old);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+	struct clk *ret = NULL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+	int id;
+	/* Source clock this clk depends on */
+	struct clk *parent;
+	/* Secondary clock to enable/disable with this clock */
+	struct clk *secondary;
+	/* Reference count of clock enable/disable */
+	__s8 usecount;
+	/* Register bit position for clock's enable/disable control. */
+	u8 enable_shift;
+	/* Register address for clock's enable/disable control. */
+	void __iomem *enable_reg;
+	u32 flags;
+	/* get the current clock rate (always a fresh value) */
+	unsigned long (*get_rate) (struct clk *);
+	/* Function ptr to set the clock to a new rate. The rate must match a
+	   supported rate returned from round_rate. Leave blank if clock is not
+	   programmable */
+	int (*set_rate) (struct clk *, unsigned long);
+	/* Function ptr to round the requested clock rate to the nearest
+	   supported rate that is less than or equal to the requested rate. */
+	unsigned long (*round_rate) (struct clk *, unsigned long);
+	/* Function ptr to enable the clock. Leave blank if clock can not
+	   be gated. */
+	int (*enable) (struct clk *);
+	/* Function ptr to disable the clock. Leave blank if clock can not
+	   be gated. */
+	void (*disable) (struct clk *);
+	/* Function ptr to set the parent clock of the clock. */
+	int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0	(0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2	0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER	0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU	(0x00000020)
+#define HW_CLKCTRL_CPU_SET	(0x00000024)
+#define HW_CLKCTRL_CPU_CLR	(0x00000028)
+#define HW_CLKCTRL_CPU_TOG	(0x0000002c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000030)
+#define HW_CLKCTRL_HBUS_SET	(0x00000034)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000038)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4	30
+#define BM_CLKCTRL_HBUS_RSRVD4	0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+		(((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY	0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE	0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	11
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000050)
+#define HW_CLKCTRL_XTAL_SET	(0x00000054)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000058)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE	30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE	0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE	0x08000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_PIX	(0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE	31
+#define BM_CLKCTRL_PIX_CLKGATE	0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2	0x40000000
+#define BM_CLKCTRL_PIX_BUSY	0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1	13
+#define BM_CLKCTRL_PIX_RSRVD1	0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v)  \
+		(((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN	0x00001000
+#define BP_CLKCTRL_PIX_DIV	0
+#define BM_CLKCTRL_PIX_DIV	0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP	(0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE	31
+#define BM_CLKCTRL_SSP_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP_BUSY	0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1	10
+#define BM_CLKCTRL_SSP_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP_DIV	0
+#define BM_CLKCTRL_SSP_DIV	0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x00000080)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x00000090)
+
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000a0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_IR	(0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE	0x80000000
+#define BM_CLKCTRL_IR_RSRVD3	0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV	0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY	0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY	0x08000000
+#define BP_CLKCTRL_IR_RSRVD2	25
+#define BM_CLKCTRL_IR_RSRVD2	0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v)  \
+		(((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV	16
+#define BM_CLKCTRL_IR_IROV_DIV	0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1	10
+#define BM_CLKCTRL_IR_RSRVD1	0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV	0
+#define BM_CLKCTRL_IR_IR_DIV	0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF	(0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1	17
+#define BM_CLKCTRL_SAIF_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF_DIV	0
+#define BM_CLKCTRL_SAIF_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV	(0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE	0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE	0x40000000
+#define BP_CLKCTRL_TV_RSRVD	0
+#define BM_CLKCTRL_TV_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM	(0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	7
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000040
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC	(0x000000f0)
+#define HW_CLKCTRL_FRAC_SET	(0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR	(0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG	(0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO	31
+#define BM_CLKCTRL_FRAC_CLKGATEIO	0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC	24
+#define BM_CLKCTRL_FRAC_IOFRAC	0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX	23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX	0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC	16
+#define BM_CLKCTRL_FRAC_PIXFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC	8
+#define BM_CLKCTRL_FRAC_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC	0
+#define BM_CLKCTRL_FRAC_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x00000100)
+#define HW_CLKCTRL_FRAC1_SET	(0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR	(0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG	(0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID	0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1	0
+#define BM_CLKCTRL_FRAC1_RSRVD1	0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ	(0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR	0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD	2
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x00000130)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000140)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2009-2010 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_H__
+
+#define HW_CLKCTRL_PLL0CTRL0	(0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0	(0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET	(0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR	(0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG	(0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI	0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6	0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1	(0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0	(0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET	(0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR	(0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG	(0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE	0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3	0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2	0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B	0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER	0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1	0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU	(0x00000050)
+#define HW_CLKCTRL_CPU_SET	(0x00000054)
+#define HW_CLKCTRL_CPU_CLR	(0x00000058)
+#define HW_CLKCTRL_CPU_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000060)
+#define HW_CLKCTRL_HBUS_SET	(0x00000064)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000068)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY	0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE	0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	12
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE	0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000080)
+#define HW_CLKCTRL_XTAL_SET	(0x00000084)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000088)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2	27
+#define BM_CLKCTRL_XTAL_RSRVD2	0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v)  \
+		(((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0	(0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE	31
+#define BM_CLKCTRL_SSP0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP0_BUSY	0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1	10
+#define BM_CLKCTRL_SSP0_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP0_DIV	0
+#define BM_CLKCTRL_SSP0_DIV	0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1	(0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE	31
+#define BM_CLKCTRL_SSP1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP1_BUSY	0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1	10
+#define BM_CLKCTRL_SSP1_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP1_DIV	0
+#define BM_CLKCTRL_SSP1_DIV	0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2	(0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE	31
+#define BM_CLKCTRL_SSP2_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP2_BUSY	0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1	10
+#define BM_CLKCTRL_SSP2_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP2_DIV	0
+#define BM_CLKCTRL_SSP2_DIV	0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3	(0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE	31
+#define BM_CLKCTRL_SSP3_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP3_BUSY	0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1	10
+#define BM_CLKCTRL_SSP3_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP3_DIV	0
+#define BM_CLKCTRL_SSP3_DIV	0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE	31
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0	(0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE	31
+#define BM_CLKCTRL_SAIF0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1	17
+#define BM_CLKCTRL_SAIF0_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF0_DIV	0
+#define BM_CLKCTRL_SAIF0_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1	(0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE	31
+#define BM_CLKCTRL_SAIF1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1	17
+#define BM_CLKCTRL_SAIF1_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF1_DIV	0
+#define BM_CLKCTRL_SAIF1_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF	(0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE	31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY	0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1	14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1	0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v)  \
+		(((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN	0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV	0
+#define BM_CLKCTRL_DIS_LCDIF_DIV	0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM	(0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	8
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000080
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET	(0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP	0x80000000
+#define BP_CLKCTRL_ENET_DISABLE	30
+#define BM_CLKCTRL_ENET_DISABLE	0x40000000
+#define BM_CLKCTRL_ENET_STATUS	0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1	0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME	0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME	21
+#define BM_CLKCTRL_ENET_DIV_TIME	0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY	0x08000000
+#define BP_CLKCTRL_ENET_DIV	21
+#define BM_CLKCTRL_ENET_DIV	0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL	19
+#define BM_CLKCTRL_ENET_TIME_SEL	0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v)  \
+		(((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL      0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL       0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK  0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN	0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP	0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW	0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0	0
+#define BM_CLKCTRL_ENET_RSRVD0	0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v)  \
+		(((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC	(0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2	0x80000000
+#define BM_CLKCTRL_HSADC_RESETB	0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV	28
+#define BM_CLKCTRL_HSADC_FREQDIV	0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v)  \
+		(((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1	0
+#define BM_CLKCTRL_HSADC_RSRVD1	0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN	(0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2	0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0	30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0	0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS	0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1	28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1	0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS	0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1	0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1	0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0	(0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET	(0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR	(0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG	(0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0	31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0	0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC	24
+#define BM_CLKCTRL_FRAC0_IO0FRAC	0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1	23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1	0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC	16
+#define BM_CLKCTRL_FRAC0_IO1FRAC	0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC	8
+#define BM_CLKCTRL_FRAC0_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC	0
+#define BM_CLKCTRL_FRAC0_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET	(0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR	(0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG	(0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2	24
+#define BM_CLKCTRL_FRAC1_RSRVD2	0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+		(((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI	23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI	0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC	16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC	15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC	0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC	8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX	7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX	0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC	0
+#define BM_CLKCTRL_FRAC1_PIXFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ	(0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0	19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+		(((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v)  \
+		(((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF	0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD    0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2	0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v)  \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0	0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD	6
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE	0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE	0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE	0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT	0x00000004
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX28_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (28 preceding siblings ...)
  2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
  2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
                   ` (16 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

Dynamically allocate fec devices for MX28, which gets dual
fec interface.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove the use of mx28_add_fec0 and mx28_add_fec1
 - Remove unnessary passing of data->iosize

 arch/arm/mach-mxs/devices-mx28.h                |    4 ++
 arch/arm/mach-mxs/devices/platform-fec.c        |   50 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   12 +++++
 3 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c

diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..00b736c 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,7 @@
 extern const struct mxs_duart_data mx28_duart_data __initconst;
 #define mx28_add_duart() \
 	mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+	mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..fb62f0c
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id)				\
+	{								\
+		.id = _id,						\
+		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
+		.irq = soc ## _INT_ENET_MAC ## _id,			\
+	}
+
+#define mxs_fec_data_entry(soc, _id)					\
+	[_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id)					\
+	mxs_fec_data_entry(MX28, _id)
+	mx28_fec_data_entry(0),
+	mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_16K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("fec", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
 };
 struct platform_device *__init mxs_add_duart(
 		const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (29 preceding siblings ...)
  2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
  2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
                   ` (15 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx23evk support with duart.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Remove boot_params

 arch/arm/mach-mxs/mach-mx23evk.c |   58 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 58 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c

diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..2169937
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+static iomux_cfg_t mx23evk_pads[] = {
+	/* duart */
+	MX23_PAD_PWM0__DUART_RX,
+	MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+	mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+	mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+	.init	= mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.map_io         = mx23_map_io,
+	.init_irq       = mx23_init_irq,
+	.init_machine   = mx23evk_init,
+	.timer          = &mx23evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (30 preceding siblings ...)
  2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
  2010-12-08 20:28   ` Uwe Kleine-König
  2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
                   ` (14 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx28evk support with duart and fec0.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Change function mx28evk_fec_reset() from inline to __init
 - Enable pll2 clock before phy operation
 - Add error checking for gpio_direction_output()
 - Save bytes by passing parameter into pr_err format string
 - Change mx28_add_fec0() to mx28_add_fec(0)
 - Remove boot_params

 arch/arm/mach-mxs/mach-mx28evk.c |  126 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..3e8e37a
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+
+static iomux_cfg_t mx28evk_pads[] = {
+	/* duart */
+	MX28_PAD_PWM0__DUART_RX,
+	MX28_PAD_PWM1__DUART_TX,
+
+	/* fec0 */
+	MX28_PAD_ENET0_MDC__ENET0_MDC,
+	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
+	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
+	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
+	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
+	MX28_PAD_ENET_CLK__ENET_CLK,
+	/* phy power line */
+	MX28_PAD_SSP1_DATA3__GPIO_2_15,
+	/* phy reset line */
+	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
+};
+
+/* fec */
+static void __init mx28evk_fec_reset(void)
+{
+	int ret;
+	struct clk *clk;
+
+	/* Enable fec phy clock */
+	clk = clk_get_sys("pll2", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+
+	/* Power up fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+	if (ret) {
+		pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+		return;
+	}
+
+	/* Reset fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+	if (ret) {
+		pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+		return;
+	}
+
+	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+		return;
+	}
+
+	mdelay(1);
+	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+        .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+	mx28_add_duart();
+
+	mx28evk_fec_reset();
+	mx28_add_fec(0, &mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+	mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+	.init	= mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.map_io         = mx28_map_io,
+	.init_irq       = mx28_init_irq,
+	.init_machine   = mx28evk_init,
+	.timer          = &mx28evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (31 preceding siblings ...)
  2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
  2010-12-10 14:51   ` Uwe Kleine-König
  2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
                   ` (13 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Sort mach-mxs behind plat-mxc in arch/arm/Kconfig
 - Remove meaningless comment from arch/arm/mach-mxs/Makefile
 - Remove unused params_phys and initrd_phys from arch/arm/mach-mxs/Makefile.boot

Changes for v2:
 - Remove cpu.o from arch/arm/mach-mxs/Makefile

 arch/arm/Kconfig                   |   10 ++++++++++
 arch/arm/Makefile                  |    1 +
 arch/arm/mach-mxs/Kconfig          |   34 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/Makefile         |   10 ++++++++++
 arch/arm/mach-mxs/Makefile.boot    |    1 +
 arch/arm/mach-mxs/devices/Kconfig  |    5 +++++
 arch/arm/mach-mxs/devices/Makefile |    2 ++
 7 files changed, 63 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/Kconfig
 create mode 100644 arch/arm/mach-mxs/Makefile
 create mode 100644 arch/arm/mach-mxs/Makefile.boot
 create mode 100644 arch/arm/mach-mxs/devices/Kconfig
 create mode 100644 arch/arm/mach-mxs/devices/Makefile

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..0403aa8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
+config ARCH_MXS
+	bool "Freescale MXS-based"
+	select GENERIC_CLOCKEVENTS
+	select ARCH_REQUIRE_GPIOLIB
+	select COMMON_CLKDEV
+	help
+	  Support for Freescale MXS-based family of processors
+
 config ARCH_STMP3XXX
 	bool "Freescale STMP3xxx"
 	select CPU_ARM926T
@@ -902,6 +910,8 @@ source "arch/arm/mach-mv78xx0/Kconfig"
 
 source "arch/arm/plat-mxc/Kconfig"
 
+source "arch/arm/mach-mxs/Kconfig"
+
 source "arch/arm/mach-netx/Kconfig"
 
 source "arch/arm/mach-nomadik/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25)		:= imx
 machine-$(CONFIG_ARCH_MX3)		:= mx3
 machine-$(CONFIG_ARCH_MX5)		:= mx5
 machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
+machine-$(CONFIG_ARCH_MXS)		:= mxs
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
 machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+	bool
+	select CPU_ARM926T
+
+config SOC_IMX28
+	bool
+	select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+	bool "Support MX23EVK Platform"
+	select SOC_IMX23
+	select MXS_HAVE_PLATFORM_DUART
+	default y
+	help
+	  Include support for MX23EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+	bool "Support MX28EVK Platform"
+	select SOC_IMX28
+	select MXS_HAVE_PLATFORM_DUART
+	select MXS_HAVE_PLATFORM_FEC
+	default y
+	help
+	  Include support for MX28EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..40b808c
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,10 @@
+# Common support
+obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..eb541e0
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x40008000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+	bool
+
+config MXS_HAVE_PLATFORM_FEC
+	bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 01/15] ARM: mxs: Add core definitions
  2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-07 20:18   ` Uwe Kleine-König
  2010-12-08  4:50     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 20:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Update MXS_IO_P2V definition and comment to get them matched
>  - Sort mx23 base address definitions by offset
>  - Remove mx28 reserved IRQ definitions
>  - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
> 
> Changes for v2:
>  - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
>  - Simplify MXS_IO_P2V_MODULE definition in hardware.h
>  - Remove unnecessary inclusion protection from hardware.h
>  - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
> 
>  arch/arm/mach-mxs/include/mach/hardware.h |   55 +++++++++
>  arch/arm/mach-mxs/include/mach/irqs.h     |   32 +++++
>  arch/arm/mach-mxs/include/mach/memory.h   |   24 ++++
>  arch/arm/mach-mxs/include/mach/mx23.h     |  147 ++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mx28.h     |  190 +++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mxs.h      |   34 +++++
>  6 files changed, 482 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..d73f149
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA  02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr)	(addr)
> +#else
> +#define IOMEM(addr)	((void __force __iomem *)(addr))
> +#endif
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
The maximal address that can occur is 0xf50fffff

> + *
> + *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
> + *	IO	0x80000000+0x100000	->	0xf5000000+0x100000
> + */
> +#define MXS_IO_P2V(x)	(0xf4000000 +					\
> +			(((x) & 0x80000000) >> 7) +			\
> +			(((x) & 0x000fffff)))
> +
> +
> +#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
> +
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type)	{				\
> +	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
> +	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
> +	.length = soc ## _ ## name ## _SIZE,				\
> +	.type = _type,							\
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + *  Copyright 2004-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 version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS	128
> +
> +#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS		(32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes.  Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS		16
> +
> +#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET		UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..2033ed4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
You don't need this, do you?

#inclusion of hardware.h would be OK, then you could remove the
#includes of mx23.h and mx28.h in there.
(Believe me, this is better, mxc already made me headaches because of
that.)

> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR		0x00000000
> +#define MX23_OCRAM_SIZE			SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR		0x80000000
> +#define MX23_IO_SIZE			SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART			0
> +#define MX23_INT_COMMS_RX		1
> +#define MX23_INT_COMMS_TX		1
> +#define MX23_INT_SSP2_ERROR		2
> +#define MX23_INT_VDD5V			3
> +#define MX23_INT_HEADPHONE_SHORT	4
> +#define MX23_INT_DAC_DMA		5
> +#define MX23_INT_DAC_ERROR		6
> +#define MX23_INT_ADC_DMA		7
> +#define MX23_INT_ADC_ERROR		8
> +#define MX23_INT_SPDIF_DMA		9
> +#define MX23_INT_SAIF2_DMA		9
> +#define MX23_INT_SPDIF_ERROR		10
> +#define MX23_INT_SAIF1_IRQ		10
> +#define MX23_INT_SAIF2_IRQ		10
> +#define MX23_INT_USB_CTRL		11
> +#define MX23_INT_USB_WAKEUP		12
> +#define MX23_INT_GPMI_DMA		13
> +#define MX23_INT_SSP1_DMA		14
> +#define MX23_INT_SSP_ERROR		15
> +#define MX23_INT_GPIO0			16
> +#define MX23_INT_GPIO1			17
> +#define MX23_INT_GPIO2			18
> +#define MX23_INT_SAIF1_DMA		19
> +#define MX23_INT_SSP2_DMA		20
> +#define MX23_INT_ECC8_IRQ		21
> +#define MX23_INT_RTC_ALARM		22
> +#define MX23_INT_UARTAPP_TX_DMA		23
> +#define MX23_INT_UARTAPP_INTERNAL	24
> +#define MX23_INT_UARTAPP_RX_DMA		25
> +#define MX23_INT_I2C_DMA		26
> +#define MX23_INT_I2C_ERROR		27
> +#define MX23_INT_TIMER0			28
> +#define MX23_INT_TIMER1			29
> +#define MX23_INT_TIMER2			30
> +#define MX23_INT_TIMER3			31
> +#define MX23_INT_BATT_BRNOUT		32
> +#define MX23_INT_VDDD_BRNOUT		33
> +#define MX23_INT_VDDIO_BRNOUT		34
> +#define MX23_INT_VDD18_BRNOUT		35
> +#define MX23_INT_TOUCH_DETECT		36
> +#define MX23_INT_LRADC_CH0		37
> +#define MX23_INT_LRADC_CH1		38
> +#define MX23_INT_LRADC_CH2		39
> +#define MX23_INT_LRADC_CH3		40
> +#define MX23_INT_LRADC_CH4		41
> +#define MX23_INT_LRADC_CH5		42
> +#define MX23_INT_LRADC_CH6		43
> +#define MX23_INT_LRADC_CH7		44
> +#define MX23_INT_LCDIF_DMA		45
> +#define MX23_INT_LCDIF_ERROR		46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP	47
> +#define MX23_INT_RTC_1MSEC		48
> +#define MX23_INT_DRI_DMA		49
> +#define MX23_INT_DRI_ATTENTION		50
> +#define MX23_INT_GPMI_ATTENTION		51
> +#define MX23_INT_IR			52
> +#define MX23_INT_DCP_VMI		53
> +#define MX23_INT_DCP			54
> +#define MX23_INT_BCH			56
> +#define MX23_INT_PXP			57
> +#define MX23_INT_UARTAPP2_TX_DMA	58
> +#define MX23_INT_UARTAPP2_INTERNAL	59
> +#define MX23_INT_UARTAPP2_RX_DMA	60
> +#define MX23_INT_VDAC_DETECT		61
> +#define MX23_INT_VDD5V_DROOP		64
> +#define MX23_INT_DCDC4P2_BO		65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..be1c2a4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,190 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
ditto

> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR		0x00000000
> +#define MX28_OCRAM_SIZE			SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR		0x80000000
> +#define MX28_IO_SIZE			SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT		0
> +#define MX28_INT_VDDD_BRNOUT		1
> +#define MX28_INT_VDDIO_BRNOUT		2
> +#define MX28_INT_VDDA_BRNOUT		3
> +#define MX28_INT_VDD5V_DROOP		4
> +#define MX28_INT_DCDC4P2_BRNOUT		5
> +#define MX28_INT_VDD5V			6
> +#define MX28_INT_CAN0			8
> +#define MX28_INT_CAN1			9
> +#define MX28_INT_LRADC_TOUCH		10
> +#define MX28_INT_HSADC			13
> +#define MX28_INT_IRADC_THRESH0		14
> +#define MX28_INT_IRADC_THRESH1		15
> +#define MX28_INT_LRADC_CH0		16
> +#define MX28_INT_LRADC_CH1		17
> +#define MX28_INT_LRADC_CH2		18
> +#define MX28_INT_LRADC_CH3		19
> +#define MX28_INT_LRADC_CH4		20
> +#define MX28_INT_LRADC_CH5		21
> +#define MX28_INT_LRADC_CH6		22
> +#define MX28_INT_LRADC_CH7		23
> +#define MX28_INT_LRADC_BUTTON0		24
> +#define MX28_INT_LRADC_BUTTON1		25
> +#define MX28_INT_PERFMON		27
> +#define MX28_INT_RTC_1MSEC		28
> +#define MX28_INT_RTC_ALARM		29
> +#define MX28_INT_COMMS			31
> +#define MX28_INT_EMI_ERR		32
> +#define MX28_INT_LCDIF			38
> +#define MX28_INT_PXP			39
> +#define MX28_INT_BCH			41
> +#define MX28_INT_GPMI			42
> +#define MX28_INT_SPDIF_ERROR		45
> +#define MX28_INT_DUART			47
> +#define MX28_INT_TIMER0			48
> +#define MX28_INT_TIMER1			49
> +#define MX28_INT_TIMER2			50
> +#define MX28_INT_TIMER3			51
> +#define MX28_INT_DCP_VMI		52
> +#define MX28_INT_DCP			53
> +#define MX28_INT_DCP_SECURE		54
> +#define MX28_INT_SAIF1			58
> +#define MX28_INT_SAIF0			59
> +#define MX28_INT_SPDIF_DMA		66
> +#define MX28_INT_I2C0_DMA		68
> +#define MX28_INT_I2C1_DMA		69
> +#define MX28_INT_AUART0_RX_DMA		70
> +#define MX28_INT_AUART0_TX_DMA		71
> +#define MX28_INT_AUART1_RX_DMA		72
> +#define MX28_INT_AUART1_TX_DMA		73
> +#define MX28_INT_AUART2_RX_DMA		74
> +#define MX28_INT_AUART2_TX_DMA		75
> +#define MX28_INT_AUART3_RX_DMA		76
> +#define MX28_INT_AUART3_TX_DMA		77
> +#define MX28_INT_AUART4_RX_DMA		78
> +#define MX28_INT_AUART4_TX_DMA		79
> +#define MX28_INT_SAIF0_DMA		80
> +#define MX28_INT_SAIF1_DMA		81
> +#define MX28_INT_SSP0_DMA		82
> +#define MX28_INT_SSP1_DMA		83
> +#define MX28_INT_SSP2_DMA		84
> +#define MX28_INT_SSP3_DMA		85
> +#define MX28_INT_LCDIF_DMA		86
> +#define MX28_INT_HSADC_DMA		87
> +#define MX28_INT_GPMI_DMA		88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP	89
> +#define MX28_INT_USB1			92
> +#define MX28_INT_USB0			93
> +#define MX28_INT_USB1_WAKEUP		94
> +#define MX28_INT_USB0_WAKEUP		95
> +#define MX28_INT_SSP0			96
> +#define MX28_INT_SSP1			97
> +#define MX28_INT_SSP2			98
> +#define MX28_INT_SSP3			99
> +#define MX28_INT_ENET_SWI		100
> +#define MX28_INT_ENET_MAC0		101
> +#define MX28_INT_ENET_MAC1		102
> +#define MX28_INT_ENET_MAC0_1588		103
> +#define MX28_INT_ENET_MAC1_1588		104
> +#define MX28_INT_I2C1_ERROR		110
> +#define MX28_INT_I2C0_ERROR		111
> +#define MX28_INT_AUART0			112
> +#define MX28_INT_AUART1			113
> +#define MX28_INT_AUART2			114
> +#define MX28_INT_AUART3			115
> +#define MX28_INT_AUART4			116
> +#define MX28_INT_GPIO4			123
> +#define MX28_INT_GPIO3			124
> +#define MX28_INT_GPIO2			125
> +#define MX28_INT_GPIO1			126
> +#define MX28_INT_GPIO0			127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..13e06ae
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,34 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +
> +#define MXS_SET_ADDR		0x4
> +#define MXS_CLR_ADDR		0x8
> +#define MXS_TOG_ADDR		0xc
> +
> +/*
> + * MXS CPU types
> + */
> +# define cpu_is_mx23()		(machine_is_mx23evk())
> +# define cpu_is_mx28()		(machine_is_mx28evk())
> +
> +#endif /* __MACH_MXS_H__ */
> -- 
> 1.7.1

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-07 20:27   ` Uwe Kleine-König
  2010-12-08  7:33   ` Lothar Waßmann
  1 sibling, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 20:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Wed, Dec 08, 2010 at 12:31:53AM +0800, Shawn Guo wrote:
>  - The mxs wdog is implemented in RTC block.
>  - There is a generic software reset routine for most modules on mxs.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Change wdog timeout to 10ms for safety
>  - Simplify function mxs_reset_block() to get it look better
> 
> Changes for v2:
>  - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> 
>  arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
>  arch/arm/mach-mxs/system.c              |  134 +++++++++++++++++++++++++++++++
>  2 files changed, 161 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/system.h
>  create mode 100644 arch/arm/mach-mxs/system.c
> 
> diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
> new file mode 100644
> index 0000000..0e42823
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/system.h
> @@ -0,0 +1,27 @@
> +/*
> + *  Copyright (C) 1999 ARM Limited
> + *  Copyright (C) 2000 Deep Blue Solutions Ltd
> + *  Copyright 2004-2008 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.
> + */
> +
> +#ifndef __MACH_MXS_SYSTEM_H__
> +#define __MACH_MXS_SYSTEM_H__
> +
> +static inline void arch_idle(void)
> +{
> +	cpu_do_idle();
> +}
> +
> +void arch_reset(char mode, const char *cmd);
> +
> +#endif /* __MACH_MXS_SYSTEM_H__ */
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..58cb044
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,134 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; 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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG	0x50
> +#define MXS_WATCHDOG_EN		(1 << 4)
> +
> +#define MXS_MODULE_CLKGATE	(1 << 30)
> +#define MXS_MODULE_SFTRST	(1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> +	/* Set wdog timer 10 ms */
> +	__raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
> +
> +	/* Enable wdog reset */
> +	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> +	/* Wait for reset to assert... */
> +	mdelay(10);
> +
> +	pr_err("Watchdog reset failed to assert reset\n");
> +
> +	/* Delay to allow the serial port to show the message */
> +	mdelay(50);
> +
> +	/* We'll take a jump through zero as a poor second */
> +	cpu_reset(0);
> +}
> +
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> +	struct clk *clk;
> +
> +	wdog_base = base;
> +
> +	clk = clk_get_sys("rtc", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
> +}
> +
> +/*
> + * Clear the bit and poll it cleared.  This is usually called with
> + * a reset address and mask being either SFTRST(bit 31) or CLKGATE
> + * (bit 30).
> + */
> +static int clear_poll_bit(void __iomem *addr, u32 mask)
> +{
> +	int timeout = 0x400;
> +
> +	/* clear the bit */
> +	__raw_writel(mask, addr + MXS_CLR_ADDR);
> +
> +	/*
> +	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
> +	 * recommends to wait 1us.
> +	 */
> +	udelay(1);
> +
> +	/* poll the bit becoming clear */
> +	while ((__raw_readl(addr) & mask) && --timeout)
> +		/* nothing */;
> +
> +	return !timeout;
> +}
> +
> +int mxs_reset_block(void __iomem *reset_addr)
> +{
> +	int ret;
> +	int timeout = 0x400;
> +
> +	/* clear and poll SFTRST */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> +	if (ret)
unlikely(ret)?

> +		goto error;
> +
> +	/* clear CLKGATE */
> +	__raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);

> +	/* set SFTRST to reset the block */
> +	__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
> +	udelay(1);

> +	/* poll CLKGATE becoming set */
Can you add empty lines above the comments, please.  This makes it much
easier to read.

> +	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> +		/* nothing */;
> +	if (unlikely(!timeout))
> +		goto error;
> +
> +	/* clear and poll SFTRST */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> +	if (ret)
> +		goto error;
> +
> +	/* clear and poll CLKGATE */
> +	ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
> +	if (ret)
> +		goto error;
> +
> +	return 0;
> +
> +error:
> +	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> +	return -ETIMEDOUT;
> +}
> -- 
> 1.7.1

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-07 21:03   ` Uwe Kleine-König
  2010-12-08  8:27     ` Shawn Guo
  2010-12-08  8:56     ` Shawn Guo
  2010-12-08  8:24   ` Lothar Waßmann
  1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 21:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> Add Interrupt Collector (ICOLL) support for MXS-based.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Get icoll base in get_irqnr_preamble
>  - Check the case of single SoC build and use hard-coding address if possible
> 
>  arch/arm/mach-mxs/icoll.c                    |   77 ++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/entry-macro.S |   44 +++++++++++++++
>  2 files changed, 121 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/icoll.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
> 
> diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
> new file mode 100644
> index 0000000..a7a7d4f
> --- /dev/null
> +++ b/arch/arm/mach-mxs/icoll.c
> @@ -0,0 +1,77 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/irq.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define HW_ICOLL_VECTOR				0x0000
> +#define HW_ICOLL_LEVELACK			0x0010
> +#define HW_ICOLL_CTRL				0x0020
> +#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
> +#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
> +#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
> +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
> +
> +void __iomem *icoll_base;
> +
> +static void icoll_ack_irq(unsigned int irq)
> +{
> +	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
You need to write this before handling the irq, no?  Note this question
is a repetition.  You answered "No need, indeed.  Will remove it."
According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
in-service state".  Are you sure this is not needed?  If no (i.e. it's
needed) the write should go into entry-macro.S.  As I don't have
hardware yet I cannot test that.  Maybe it's only needed when the
priority levels are used?!

> +
> +	/* ACK current interrupt (level 0) */
I suggest to extend this a bit, like:

	The Interrupt Collector is able to prioritize irqs.  Currently
	only level 0 is used.  So acking can use
	BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.

> +	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
> +			icoll_base + HW_ICOLL_LEVELACK);
> +}
> +
> +static void icoll_mask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
> +}
> +
> +static void icoll_unmask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
> +}
> +
> +static struct irq_chip mxs_icoll_chip = {
> +	.ack = icoll_ack_irq,
> +	.mask = icoll_mask_irq,
> +	.unmask = icoll_unmask_irq,
> +};
> +
> +void __init icoll_init_irq(void __iomem *irqbase)
> +{
> +	int i;
> +
> +	icoll_base = irqbase;
> +
> +	/* Reset icoll */
> +	mxs_reset_block(irqbase + HW_ICOLL_CTRL);
I assume this initializes the priority for each irq to level 0.  Maybe
this should be documented here.

> +
> +	for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
> +		set_irq_chip(i, &mxs_icoll_chip);
> +		set_irq_handler(i, handle_level_irq);
> +		set_irq_flags(i, IRQF_VALID);
> +	}
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..2c7755b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,44 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <mach/hardware.h>
> +
> +	.macro	disable_fiq
> +	.endm
I think is isn't needed.  Only when you start to actually use the fiq.

> +	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
> +	ldr	\irqnr, [\base, #0x70]
> +	cmp	\irqnr, #0x7F
> +	moveqs	\irqnr, #0
> +	.endm
> +
> +	.macro  get_irqnr_preamble, base, tmp
> +#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
no space between defined and ( please.

> +	ldr	\base, =icoll_base
> +	ldr	\base, [\base]
> +#elif defined (CONFIG_SOC_IMX23)
> +	ldr	\base, =MX23_ICOLL_BASE_ADDR
> +#else
> +	ldr	\base, =MX28_ICOLL_BASE_ADDR
> +#endif
Mhh, you said the base addresses are different.  Unless I'm mistaken
they are not.  So you can just remove icoll_base.

> +	.endm
> +
> +	.macro  arch_ret_to_user, tmp1, tmp2
> +	.endm

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-07 21:18   ` Uwe Kleine-König
  2010-12-08  5:58     ` Shawn Guo
  2010-12-08  8:30   ` Lothar Waßmann
  1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 21:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
> 
> As the result, we need two instances of timers with v1 for better
> implementation, one for clock_event and another for clocksource.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Use term clock_event over next_event and clocksource over get_cycles
>  - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
>  - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
>  - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
>  - Skip flag IRQF_DISABLED
>  - Remove unncessary IRQ disabling in mxs_set_mode()
>  - Change shift of clocksource_mxs to 17
> 
> Changes for v2:
>  - Fix a bug in timrot_set_next_event(). It should read
>    HW_TIMROT_RUNNING_COUNTn to get the current counts.
> 
>  arch/arm/mach-mxs/timer.c |  276 +++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 276 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/timer.c
> 
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..b0e7ffe
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
> @@ -0,0 +1,276 @@
> +/*
> + *  Copyright (C) 2000-2001 Deep Blue Solutions
> + *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
> + *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
> + *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
> + *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/clockchips.h>
> +#include <linux/clk.h>
> +
> +#include <mach/hardware.h>
> +#include <asm/mach/time.h>
> +#include <mach/common.h>
> +
> +/*
> + * There are 2 versions of the timrot on Freescale MXS-based SoCs.
> + * The v1 on MX23 only gets 16 bits counter and has no match function.
> + * The v2 on MX28 extends the counter to 32 bits and add the match function.
> + *
> + * As the result, we need two instances of timers with v1 for better
> + * implementation, one for clock_event and another for clocksource. Otherwise,
> + * get_cycles may get imprecise result after long time cumulating.
> + * With v2, one instance can serve two purposes well.
> + */
> +#define timrot_is_v1()	(cpu_is_mx23())
> +
> +#define HW_TIMROT_ROTCTRL			0x00
> +#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
> +#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
> +#define HW_TIMROT_MATCH_COUNTn(n)		(0x50 + (n) * 0x40)
> +#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
> +#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
> +#define BM_TIMROT_TIMCTRLn_MATCH_MODE		(1 << 11)
> +#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
> +#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
> +#define BP_TIMROT_TIMCTRLn_SELECT		0
> +#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL	0x8
> +#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL	0xb
> +
> +static struct clock_event_device clockevent_mxs;
> +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> +
> +static void __iomem *timer_base;
> +
> +static inline void timrot_irq_disable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
> +			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static cycle_t timrotv1_get_cycles(struct clocksource *cs)
> +{
> +	return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
> +			& 0xffff0000) >> 16);
> +}
> +
> +static cycle_t timrotv2_get_cycles(struct clocksource *cs)
> +{
> +	return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +}
> +
> +static int timrotv1_set_next_event(unsigned long evt,
> +					struct clock_event_device *dev)
> +{
> +	/* timrot decrements the count */
> +	__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +
> +	return 0;
> +}
> +
> +static int timrotv2_set_next_event(unsigned long evt,
> +					struct clock_event_device *dev)
> +{
> +	unsigned long match;
> +
> +	/* timrot decrements the count */
> +	match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
> +			- evt;
> +	__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> +
> +	return (int)(match - __raw_readl(timer_base +
> +			HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
Wouldn't it be easier to use the same approach as in timrotv1?  (i.e.
use two timers and then having a simpler set_next_event.)

> +}
> +
> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> +{
> +	struct clock_event_device *evt = &clockevent_mxs;
I assume dev_id is &clockevent_mxs
> +
> +	timrot_irq_acknowledge();
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mxs_timer_irq = {
> +	.name		= "MXS Timer Tick",
> +	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
> +	.handler	= mxs_timer_interrupt,
> +};
> +
> +#ifdef DEBUG
> +static const char *clock_event_mode_label[] = {
> +	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> +	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
> +	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
> +	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
> +};
> +#endif /* DEBUG */
> +
> +static void mxs_set_mode(enum clock_event_mode mode,
> +				struct clock_event_device *evt)
> +{
> +	/* Disable interrupt in timer module */
> +	timrot_irq_disable();
> +
> +	if (mode != clockevent_mode) {
> +		/* Set event time into far-far future */
> +		__raw_writel(__raw_readl(timer_base +
> +				HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> +				timer_base + HW_TIMROT_MATCH_COUNTn(0));
> +
> +		/* Clear pending interrupt */
> +		timrot_irq_acknowledge();
> +	}
> +
> +#ifdef DEBUG
> +	printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
> +		clock_event_mode_label[clockevent_mode],
> +		clock_event_mode_label[mode]);
> +#endif /* DEBUG */
> +
> +	/* Remember timer mode */
> +	clockevent_mode = mode;
> +
> +	switch (mode) {
> +	case CLOCK_EVT_MODE_PERIODIC:
> +		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> +				"supported for MXS-based\n");
It's more that it's not implemented.  (At least it could be provided
when a dedicated timer is used for clock_event.)

> +		break;
> +	case CLOCK_EVT_MODE_ONESHOT:
> +		timrot_irq_enable();
> +		break;
> +	case CLOCK_EVT_MODE_SHUTDOWN:
> +	case CLOCK_EVT_MODE_UNUSED:
> +	case CLOCK_EVT_MODE_RESUME:
> +		/* Left event sources disabled, no more interrupts appear */
> +		break;
> +	}
> +}
> +
> +static struct clock_event_device clockevent_mxs = {
> +	.name		= "mxs_timrot",
> +	.features	= CLOCK_EVT_FEAT_ONESHOT,
> +	.shift		= 32,
> +	.set_mode	= mxs_set_mode,
> +	.set_next_event	= timrotv2_set_next_event,
> +	.rating		= 200,
> +};
> +
> +static int __init mxs_clockevent_init(struct clk *timer_clk)
> +{
> +	unsigned int c = clk_get_rate(timer_clk);
> +
> +	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
> +	clockevent_mxs.cpumask = cpumask_of(0);
> +	if (timrot_is_v1()) {
> +		clockevent_mxs.set_next_event = timrotv1_set_next_event;
> +		clockevent_mxs.max_delta_ns =
> +			clockevent_delta2ns(0xfffe, &clockevent_mxs);
> +		clockevent_mxs.min_delta_ns =
> +			clockevent_delta2ns(0xf, &clockevent_mxs);
> +	} else {
> +		clockevent_mxs.max_delta_ns =
> +			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
> +		clockevent_mxs.min_delta_ns =
> +			clockevent_delta2ns(0xff, &clockevent_mxs);
Why is timrotv1's min_delta smaller than v2's?

> +	}
> +
> +	clockevents_register_device(&clockevent_mxs);
> +
> +	return 0;
> +}
> +
> +static struct clocksource clocksource_mxs = {
> +	.name 		= "mxs_timer",
> +	.rating		= 200,
> +	.read		= timrotv2_get_cycles,
> +	.mask		= CLOCKSOURCE_MASK(32),
> +	.shift 		= 17,
> +	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> +{
> +	unsigned int c = clk_get_rate(timer_clk);
> +
> +	if (timrot_is_v1()) {
> +		clocksource_mxs.read = timrotv1_get_cycles;
> +		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> +	}
> +	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
> +	clocksource_register(&clocksource_mxs);
> +
> +	return 0;
> +}
> +
> +void __init mxs_timer_init(struct clk *timer_clk,
> +				void __iomem *base, int irq)
> +{
> +	clk_enable(timer_clk);
> +
> +	timer_base = base;
> +
> +	/*
> +	 * Initialize timers to a known state
> +	 */
> +	mxs_reset_block(base + HW_TIMROT_ROTCTRL);
> +
> +	if (timrot_is_v1()) {
> +		/* timer0 is for clock_event */
> +		__raw_writel(
> +			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_UPDATE |
> +			BM_TIMROT_TIMCTRLn_IRQ_EN,
> +			base + HW_TIMROT_TIMCTRLn(0));
> +		/* timer1 is for clocksource */
> +		__raw_writel(
> +			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_RELOAD,
> +			base + HW_TIMROT_TIMCTRLn(1));
> +		__raw_writel(0xffff, timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
> +
> +	} else {
> +		__raw_writel(
> +			BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRLn_IRQ_EN |
> +			BM_TIMROT_TIMCTRLn_MATCH_MODE,
> +			timer_base + HW_TIMROT_TIMCTRLn(0));
> +	}
> +
> +	/* init and register the timer to the framework */
> +	mxs_clocksource_init(timer_clk);
> +	mxs_clockevent_init(timer_clk);
> +
> +	/* Make irqs happen */
> +	setup_irq(irq, &mxs_timer_irq);
> +}

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 01/15] ARM: mxs: Add core definitions
  2010-12-07 20:18   ` Uwe Kleine-König
@ 2010-12-08  4:50     ` Shawn Guo
  2010-12-08  9:17       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08  4:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
[...]
>> +#ifndef __MACH_MX23_H__
>> +#define __MACH_MX23_H__
>> +
>> +#ifndef __ASSEMBLER__
>> +#include <linux/io.h>
>> +#endif
> You don't need this, do you?
>
It can be removed after adding "#include <linux/io.h>" into icoll.c.

> #inclusion of hardware.h would be OK, then you could remove the
> #includes of mx23.h and mx28.h in there.
> (Believe me, this is better, mxc already made me headaches because of
> that.)
>
I do not get it.  Can you please help me understand what you want
exactly?  Remove includes of mx23.h and mx28.h from hardware.h, and
then include mx23.h, mx28.h, hardware.h individually when necessary?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-12-07 21:18   ` Uwe Kleine-König
@ 2010-12-08  5:58     ` Shawn Guo
  2010-12-08  9:25       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08  5:58 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
[...]
>> +static int timrotv2_set_next_event(unsigned long evt,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *dev)
>> +{
>> + ? ? unsigned long match;
>> +
>> + ? ? /* timrot decrements the count */
>> + ? ? match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
>> + ? ? ? ? ? ? ? ? ? ? - evt;
>> + ? ? __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
>> +
>> + ? ? return (int)(match - __raw_readl(timer_base +
>> + ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> Wouldn't it be easier to use the same approach as in timrotv1? ?(i.e.
> use two timers and then having a simpler set_next_event.)
>
Using two timrotv1 timers is not to make code look simpler. Instead,
we have to use two, because timrotv1 has no match function.  One most
significant improvement of v2 over v1 is adding match function, so
that one v2 timer can serve clock_event and clocksource without
problem.  I would keep the implementation to utilize v2 capability,
save timer resource and show the difference between v1 and v2.

>> +}
>> +
>> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
>> +{
>> + ? ? struct clock_event_device *evt = &clockevent_mxs;
> I assume dev_id is &clockevent_mxs
>
The assumption is only true if we assign &clockevent_mxs to dev_id.
So you want to see the following change?

 static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
 {
-       struct clock_event_device *evt = &clockevent_mxs;
+       struct clock_event_device *evt = dev_id;

        timrot_irq_acknowledge();
        evt->event_handler(evt);

 static struct irqaction mxs_timer_irq = {
        .name           = "MXS Timer Tick",
+       .dev_id         = &clockevent_mxs,
        .flags          = IRQF_TIMER | IRQF_IRQPOLL,
        .handler        = mxs_timer_interrupt,
 };


-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 07/15] ARM: mxs: Add gpio support
  2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-08  7:21   ` Lothar Waßmann
  0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08  7:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> MXS-based SoCs implement gpio support in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>  - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>  - Remove both edges IRQ support which is not needed
>  - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>  - Use pr_info over printk(KERN_INFO)
> 
>  arch/arm/mach-mxs/gpio.c              |  331 +++++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/gpio.h              |   36 ++++
>  arch/arm/mach-mxs/include/mach/gpio.h |   35 ++++
>  3 files changed, 402 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/gpio.c
>  create mode 100644 arch/arm/mach-mxs/gpio.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
> 
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..6db7541
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
[...]
> +static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> +{
> +	struct mxs_gpio_port *port =
> +		container_of(chip, struct mxs_gpio_port, chip);
> +	u32 l;
> +	unsigned long flags;
> +	void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> +	__raw_writel(l, reg);
> +	spin_unlock_irqrestore(&port->lock, flags);
Why not:
	__raw_writel(1 << offset, reg + (value ? MXS_SET_ADDR : MXS_CLR_ADDR));
which would not even need any locking.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-08  7:25   ` Lothar Waßmann
  2010-12-08 10:52     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08  7:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> MXS-based SoCs implements iomux functions in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Define iomux_cfg_t as u64
     ^^^^^^^^^^^^^^^^^^^^^^^^^
Really?

> +typedef struct pad_desc {
> +	unsigned bank:12;
> +	unsigned pin:20;
> +	unsigned muxsel:8;
> +	unsigned ma:12;
> +	unsigned vol:8;
> +	unsigned pull:4;
> +} iomux_cfg_t;
^^^^^^^^^^^^^^^^^


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
  2010-12-07 20:27   ` Uwe Kleine-König
@ 2010-12-08  7:33   ` Lothar Waßmann
  2010-12-08 20:31     ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08  7:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
>  - The mxs wdog is implemented in RTC block.
>  - There is a generic software reset routine for most modules on mxs.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Change wdog timeout to 10ms for safety
>  - Simplify function mxs_reset_block() to get it look better
> 
> Changes for v2:
>  - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> 
mxs_arch_reset_init() is currently being called from the .map_io hook
in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
registered.
But IMO this should be removed from the .map_io hook anyway (as well
as mxs_iomux_init()).


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
  2010-12-07 21:03   ` Uwe Kleine-König
@ 2010-12-08  8:24   ` Lothar Waßmann
  1 sibling, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08  8:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> Add Interrupt Collector (ICOLL) support for MXS-based.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Get icoll base in get_irqnr_preamble
>  - Check the case of single SoC build and use hard-coding address if possible
> 
>  arch/arm/mach-mxs/icoll.c                    |   77 ++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/entry-macro.S |   44 +++++++++++++++
>  2 files changed, 121 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/icoll.c
>  create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
> 
[...]
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..2c7755b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,44 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <mach/hardware.h>
> +
> +	.macro	disable_fiq
> +	.endm
> +
> +	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
> +	ldr	\irqnr, [\base, #0x70]
> +	cmp	\irqnr, #0x7F
> +	moveqs	\irqnr, #0
> +	.endm
> +
> +	.macro  get_irqnr_preamble, base, tmp
> +#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
> +	ldr	\base, =icoll_base
> +	ldr	\base, [\base]
> +#elif defined (CONFIG_SOC_IMX23)
> +	ldr	\base, =MX23_ICOLL_BASE_ADDR
>
MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR)

> +#else
> +	ldr	\base, =MX28_ICOLL_BASE_ADDR
>
MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR)


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-07 21:03   ` Uwe Kleine-König
@ 2010-12-08  8:27     ` Shawn Guo
  2010-12-08  9:39       ` Uwe Kleine-König
  2010-12-08  8:56     ` Shawn Guo
  1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08  8:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
[...]
>> +
>> +static void icoll_ack_irq(unsigned int irq)
>> +{
>> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> You need to write this before handling the irq, no? ?Note this question
> is a repetition. ?You answered "No need, indeed. ?Will remove it."
> According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> needed) the write should go into entry-macro.S. ?As I don't have
> hardware yet I cannot test that. ?Maybe it's only needed when the
> priority levels are used?!
>
Sorry. I made a mistake.  I thought I had tested the removal of line
and gave the comment, but actually not. The line is needed, and image
will stop working without the line.

Regarding to moving the writing to register VECTOR into entry-macro.S,
can you please help me understand the reason behind the suggestion?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
  2010-12-07 21:18   ` Uwe Kleine-König
@ 2010-12-08  8:30   ` Lothar Waßmann
  2010-12-08  9:31     ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08  8:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
> 
> As the result, we need two instances of timers with v1 for better
> implementation, one for clock_event and another for clocksource.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Use term clock_event over next_event and clocksource over get_cycles
>  - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
>  - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
>  - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
>  - Skip flag IRQF_DISABLED
>  - Remove unncessary IRQ disabling in mxs_set_mode()
>  - Change shift of clocksource_mxs to 17
> 
> Changes for v2:
>  - Fix a bug in timrot_set_next_event(). It should read
>    HW_TIMROT_RUNNING_COUNTn to get the current counts.
> 
>  arch/arm/mach-mxs/timer.c |  276 +++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 276 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/timer.c
> 
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..b0e7ffe
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
[...]
> +	switch (mode) {
> +	case CLOCK_EVT_MODE_PERIODIC:
> +		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> +				"supported for MXS-based\n");
>
Please do not line wrap message strings. Also, if you want the
function name to appear in the message, use __func__ or __FUNCTION__.
That way the name is always correct even if the function is renamed or
the printk() statement is copied to a different function.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-07 21:03   ` Uwe Kleine-König
  2010-12-08  8:27     ` Shawn Guo
@ 2010-12-08  8:56     ` Shawn Guo
  2010-12-08  9:14       ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08  8:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
[...]
>> +
>> + ? ? .macro ?disable_fiq
>> + ? ? .endm
> I think is isn't needed. ?Only when you start to actually use the fiq.
>
Without it, the compiler will complain when compiling
arch/arm/kernel/entry-armv.S.

[...]
>> + ? ? ldr ? ? \base, =icoll_base
>> + ? ? ldr ? ? \base, [\base]
>> +#elif defined (CONFIG_SOC_IMX23)
>> + ? ? ldr ? ? \base, =MX23_ICOLL_BASE_ADDR
>> +#else
>> + ? ? ldr ? ? \base, =MX28_ICOLL_BASE_ADDR
>> +#endif
> Mhh, you said the base addresses are different. ?Unless I'm mistaken
> they are not. ?So you can just remove icoll_base.
>
Something went wrong in my head.  The addresses are same.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-08  8:56     ` Shawn Guo
@ 2010-12-08  9:14       ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08  9:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Wed, Dec 08, 2010 at 04:56:40PM +0800, Shawn Guo wrote:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> [...]
> >> +
> >> + ? ? .macro ?disable_fiq
> >> + ? ? .endm
> > I think is isn't needed. ?Only when you start to actually use the fiq.
> >
> Without it, the compiler will complain when compiling
> arch/arm/kernel/entry-armv.S.
OK
 
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 01/15] ARM: mxs: Add core definitions
  2010-12-08  4:50     ` Shawn Guo
@ 2010-12-08  9:17       ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08  9:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 12:50:56PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
> [...]
> >> +#ifndef __MACH_MX23_H__
> >> +#define __MACH_MX23_H__
> >> +
> >> +#ifndef __ASSEMBLER__
> >> +#include <linux/io.h>
> >> +#endif
> > You don't need this, do you?
> >
> It can be removed after adding "#include <linux/io.h>" into icoll.c.
fine

> > #inclusion of hardware.h would be OK, then you could remove the
> > #includes of mx23.h and mx28.h in there.
> > (Believe me, this is better, mxc already made me headaches because of
> > that.)
> >
> I do not get it.  Can you please help me understand what you want
> exactly?  Remove includes of mx23.h and mx28.h from hardware.h, and
> then include mx23.h, mx28.h, hardware.h individually when necessary?
Yeap.  You will need hardware.h for mx2[38].h to get the macros
MXS_IO_P2V and IOMEM.

Best regards
UWe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-12-08  5:58     ` Shawn Guo
@ 2010-12-08  9:25       ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08  9:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 01:58:17PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
> [...]
> >> +static int timrotv2_set_next_event(unsigned long evt,
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *dev)
> >> +{
> >> + ? ? unsigned long match;
> >> +
> >> + ? ? /* timrot decrements the count */
> >> + ? ? match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
> >> + ? ? ? ? ? ? ? ? ? ? - evt;
> >> + ? ? __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> >> +
> >> + ? ? return (int)(match - __raw_readl(timer_base +
> >> + ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> > Wouldn't it be easier to use the same approach as in timrotv1? ?(i.e.
> > use two timers and then having a simpler set_next_event.)
> >
> Using two timrotv1 timers is not to make code look simpler. Instead,
> we have to use two, because timrotv1 has no match function.  One most
> significant improvement of v2 over v1 is adding match function, so
> that one v2 timer can serve clock_event and clocksource without
> problem.  I would keep the implementation to utilize v2 capability,
> save timer resource and show the difference between v1 and v2.
Is there an advantage of keeping one additional timer unused?  IMHO it
doesn't make much sense to use the match support just because it exists
if it doesn't make things easier.  Here the main impact is that it
complicates the set_next_event callback.

> >> +}
> >> +
> >> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> >> +{
> >> + ? ? struct clock_event_device *evt = &clockevent_mxs;
> > I assume dev_id is &clockevent_mxs
> >
> The assumption is only true if we assign &clockevent_mxs to dev_id.
> So you want to see the following change?
> 
>  static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
>  {
> -       struct clock_event_device *evt = &clockevent_mxs;
> +       struct clock_event_device *evt = dev_id;
This might save an instruction or two.

>         timrot_irq_acknowledge();
>         evt->event_handler(evt);
> 
>  static struct irqaction mxs_timer_irq = {
>         .name           = "MXS Timer Tick",
> +       .dev_id         = &clockevent_mxs,
>         .flags          = IRQF_TIMER | IRQF_IRQPOLL,
>         .handler        = mxs_timer_interrupt,
>  };
This looks more correct at least (IMHO).

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 06/15] ARM: mxs: Add timer support
  2010-12-08  8:30   ` Lothar Waßmann
@ 2010-12-08  9:31     ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08  9:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Lothar,

On Wed, Dec 08, 2010 at 09:30:39AM +0100, Lothar Wa?mann wrote:
> > +	switch (mode) {
> > +	case CLOCK_EVT_MODE_PERIODIC:
> > +		printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> > +				"supported for MXS-based\n");
> >
> Please do not line wrap message strings. Also, if you want the
> function name to appear in the message, use __func__ or __FUNCTION__.
> That way the name is always correct even if the function is renamed or
> the printk() statement is copied to a different function.
__FUNCTION__ isn't considered good, so please use __func__.
(__FUNCTION__ is a gcc extension, __func__ is c99 (I think)).
checkpatch warns about __FUNCTION__, too.

Shawn, you can also consider using pr_err.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-08  8:27     ` Shawn Guo
@ 2010-12-08  9:39       ` Uwe Kleine-König
  2010-12-08 10:46         ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08  9:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> [...]
> >> +
> >> +static void icoll_ack_irq(unsigned int irq)
> >> +{
> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> > You need to write this before handling the irq, no? ?Note this question
> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> > needed) the write should go into entry-macro.S. ?As I don't have
> > hardware yet I cannot test that. ?Maybe it's only needed when the
> > priority levels are used?!
> >
> Sorry. I made a mistake.  I thought I had tested the removal of line
> and gave the comment, but actually not. The line is needed, and image
> will stop working without the line.
> 
> Regarding to moving the writing to register VECTOR into entry-macro.S,
> can you please help me understand the reason behind the suggestion?
Section 5.2.1 of MCIMX28RM writes:

	After the CPU enters the interrupt service routine, it must
	notify the interrupt collector as soon as possible. Software
	indicates the in-service state by writing to the HW_ICOLL_VECTOR
	register.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-08  9:39       ` Uwe Kleine-König
@ 2010-12-08 10:46         ` Shawn Guo
  2010-12-08 12:09           ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 10:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
>> [...]
>> >> +
>> >> +static void icoll_ack_irq(unsigned int irq)
>> >> +{
>> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
>> > You need to write this before handling the irq, no? ?Note this question
>> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
>> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
>> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
>> > needed) the write should go into entry-macro.S. ?As I don't have
>> > hardware yet I cannot test that. ?Maybe it's only needed when the
>> > priority levels are used?!
>> >
>> Sorry. I made a mistake. ?I thought I had tested the removal of line
>> and gave the comment, but actually not. The line is needed, and image
>> will stop working without the line.
>>
>> Regarding to moving the writing to register VECTOR into entry-macro.S,
>> can you please help me understand the reason behind the suggestion?
> Section 5.2.1 of MCIMX28RM writes:
>
> ? ? ? ?After the CPU enters the interrupt service routine, it must
> ? ? ? ?notify the interrupt collector as soon as possible. Software
> ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
> ? ? ? ?register.
>
In case you will ask why, I would give the fact here.  I'm not sure
what is your first thought.  Mine is to add it into get_irqnr_preamble
as below.

        .macro  get_irqnr_preamble, base, tmp
        ldr     \base, =ICOLL_ADDR
        mov     \tmp, #0
        str     \tmp, [\base]
        .endm

But I got the following error.

[...]
VFS: Mounted root (nfs filesystem) on device 0:11.
Freeing init memory: 92K
irq 101: nobody cared (try booting with the "irqpoll" option)
[<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
4/0x8c)
[<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
c/0x1d8)
[<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
108/0x198)
[<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
x94)
[<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
Exception stack(0xc02e7d38 to 0xc02e7d80)
7d20:                                                       c02e7db0 00000000
7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
[<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
c)
[<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
/0x1e8)
[<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
c/0xb0)
[<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
d+0x484/0x610)
[<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
0x28/0x1c8)
[<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
c)
[<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
0x1fc)
[<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
c)
[<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
x388)
[<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
g+0x80/0x140)
[<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
0x180)
[<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
10)
[<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
[<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
[<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
Exception stack(0xc02e7f80 to 0xc02e7fc8)
7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
7fc0: 60000013 ffffffff
[<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
[<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
[<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
[<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
handlers:
[<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
Disabling IRQ #101

However, when I add it into get_irqnr_and_base as below.

        .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
        mov     \tmp, #0
        str     \tmp, [\base]
        ldr     \irqnr, [\base, #0x70]
        cmp     \irqnr, #0x7F
        moveqs  \irqnr, #0
        .endm

Everything seems fine.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-08  7:25   ` Lothar Waßmann
@ 2010-12-08 10:52     ` Shawn Guo
  2010-12-08 10:56       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 10:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar,

Thanks for the review.

On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Hi,
>
> Shawn Guo writes:
>> MXS-based SoCs implements iomux functions in block PINCTRL.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Define iomux_cfg_t as u64
> ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> Really?
>
>> +typedef struct pad_desc {
>> + ? ? unsigned bank:12;
>> + ? ? unsigned pin:20;
>> + ? ? unsigned muxsel:8;
>> + ? ? unsigned ma:12;
>> + ? ? unsigned vol:8;
>> + ? ? unsigned pull:4;
>> +} iomux_cfg_t;
> ^^^^^^^^^^^^^^^^^
>
I did not pick the correct word.  What I meant is 64 bits.  Since this
error is in change log, I would fix it if there is v3 of the patch.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-08 10:52     ` Shawn Guo
@ 2010-12-08 10:56       ` Uwe Kleine-König
  2010-12-08 11:29         ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
> Hi Lothar,
> 
> Thanks for the review.
> 
> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> > Hi,
> >
> > Shawn Guo writes:
> >> MXS-based SoCs implements iomux functions in block PINCTRL.
> >>
> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> >> ---
> >> Changes for v2:
> >> ?- Define iomux_cfg_t as u64
> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> > Really?
> >
> >> +typedef struct pad_desc {
> >> + ? ? unsigned bank:12;
> >> + ? ? unsigned pin:20;
> >> + ? ? unsigned muxsel:8;
> >> + ? ? unsigned ma:12;
> >> + ? ? unsigned vol:8;
> >> + ? ? unsigned pull:4;
> >> +} iomux_cfg_t;
> > ^^^^^^^^^^^^^^^^^
> >
> I did not pick the correct word.  What I meant is 64 bits.  Since this
> error is in change log, I would fix it if there is v3 of the patch.
the idea was to really use an u64 to have the pin definitions modifyable.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-08 10:56       ` Uwe Kleine-König
@ 2010-12-08 11:29         ` Shawn Guo
  2010-12-08 11:32           ` Lothar Waßmann
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
> On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
>> Hi Lothar,
>>
>> Thanks for the review.
>>
>> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> > Hi,
>> >
>> > Shawn Guo writes:
>> >> MXS-based SoCs implements iomux functions in block PINCTRL.
>> >>
>> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> >> ---
>> >> Changes for v2:
>> >> ?- Define iomux_cfg_t as u64
>> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
>> > Really?
>> >
>> >> +typedef struct pad_desc {
>> >> + ? ? unsigned bank:12;
>> >> + ? ? unsigned pin:20;
>> >> + ? ? unsigned muxsel:8;
>> >> + ? ? unsigned ma:12;
>> >> + ? ? unsigned vol:8;
>> >> + ? ? unsigned pull:4;
>> >> +} iomux_cfg_t;
>> > ^^^^^^^^^^^^^^^^^
>> >
>> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
>> error is in change log, I would fix it if there is v3 of the patch.
> the idea was to really use an u64 to have the pin definitions modifyable.
>
Ah, I misunderstood the comments.  But I did not see mxc switches to
u64.  Do you have example to show what you want exactly?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-08 11:29         ` Shawn Guo
@ 2010-12-08 11:32           ` Lothar Waßmann
  2010-12-09  6:15             ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 11:32 UTC (permalink / raw)
  To: linux-arm-kernel

Shawn Guo writes:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> > On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
> >> Hi Lothar,
> >>
> >> Thanks for the review.
> >>
> >> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> >> > Hi,
> >> >
> >> > Shawn Guo writes:
> >> >> MXS-based SoCs implements iomux functions in block PINCTRL.
> >> >>
> >> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> >> >> ---
> >> >> Changes for v2:
> >> >> ?- Define iomux_cfg_t as u64
> >> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> >> > Really?
> >> >
> >> >> +typedef struct pad_desc {
> >> >> + ? ? unsigned bank:12;
> >> >> + ? ? unsigned pin:20;
> >> >> + ? ? unsigned muxsel:8;
> >> >> + ? ? unsigned ma:12;
> >> >> + ? ? unsigned vol:8;
> >> >> + ? ? unsigned pull:4;
> >> >> +} iomux_cfg_t;
> >> > ^^^^^^^^^^^^^^^^^
> >> >
> >> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
> >> error is in change log, I would fix it if there is v3 of the patch.
> > the idea was to really use an u64 to have the pin definitions modifyable.
> >
> Ah, I misunderstood the comments.  But I did not see mxc switches to
> u64.  Do you have example to show what you want exactly?
> 
See:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-08 10:46         ` Shawn Guo
@ 2010-12-08 12:09           ` Uwe Kleine-König
  2010-12-08 12:31             ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 06:46:49PM +0800, Shawn Guo wrote:
> Hi Uwe,
> 
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn,
> >
> > On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
> >> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> >> [...]
> >> >> +
> >> >> +static void icoll_ack_irq(unsigned int irq)
> >> >> +{
> >> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> >> > You need to write this before handling the irq, no? ?Note this question
> >> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
> >> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> >> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> >> > needed) the write should go into entry-macro.S. ?As I don't have
> >> > hardware yet I cannot test that. ?Maybe it's only needed when the
> >> > priority levels are used?!
> >> >
> >> Sorry. I made a mistake. ?I thought I had tested the removal of line
> >> and gave the comment, but actually not. The line is needed, and image
> >> will stop working without the line.
> >>
> >> Regarding to moving the writing to register VECTOR into entry-macro.S,
> >> can you please help me understand the reason behind the suggestion?
> > Section 5.2.1 of MCIMX28RM writes:
> >
> > ? ? ? ?After the CPU enters the interrupt service routine, it must
> > ? ? ? ?notify the interrupt collector as soon as possible. Software
> > ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
> > ? ? ? ?register.
> >
> In case you will ask why, I would give the fact here.  I'm not sure
> what is your first thought.  Mine is to add it into get_irqnr_preamble
> as below.
> 
>         .macro  get_irqnr_preamble, base, tmp
>         ldr     \base, =ICOLL_ADDR
>         mov     \tmp, #0
>         str     \tmp, [\base]
>         .endm
It's wrong to do that in get_irqnr_preamble.

> But I got the following error.
> 
> [...]
> VFS: Mounted root (nfs filesystem) on device 0:11.
> Freeing init memory: 92K
> irq 101: nobody cared (try booting with the "irqpoll" option)
> [<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
> 4/0x8c)
> [<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
> c/0x1d8)
> [<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
> 108/0x198)
> [<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
> x94)
> [<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
> Exception stack(0xc02e7d38 to 0xc02e7d80)
> 7d20:                                                       c02e7db0 00000000
> 7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
> 7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
> c)
> [<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
> /0x1e8)
> [<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
> c/0xb0)
> [<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
> d+0x484/0x610)
> [<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
> 0x28/0x1c8)
> [<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
> c)
> [<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
> 0x1fc)
> [<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
> c)
> [<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
> x388)
> [<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
> g+0x80/0x140)
> [<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
> 0x180)
> [<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
> 10)
> [<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
> [<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
> [<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
> Exception stack(0xc02e7f80 to 0xc02e7fc8)
> 7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
> 7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
> 7fc0: 60000013 ffffffff
> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
> [<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
> [<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
> [<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
> handlers:
> [<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
> Disabling IRQ #101
> 
> However, when I add it into get_irqnr_and_base as below.
> 
>         .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
>         mov     \tmp, #0
>         str     \tmp, [\base]
>         ldr     \irqnr, [\base, #0x70]
>         cmp     \irqnr, #0x7F
>         moveqs  \irqnr, #0
>         .endm
> 
> Everything seems fine.

I think you need to do the following:

	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
	ldr     \irqnr, [\base, #0x70]
	cmp     \irqnr, #0x7F
	strne	\irqnr, [\base]
	moveq	\irqnr, #0
	.endm

(i.e. only write to VECTOR if there is an irq pending).

As before this is completely untested.

Another thing I just noticed is that you don't really want to hardcode
the 0x70, take a look into
arch/arm/mach-ns9xxx/include/mach/entry-macro.S for an example to avoid
it.
 
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 04/15] ARM: mxs: Add interrupt support
  2010-12-08 12:09           ` Uwe Kleine-König
@ 2010-12-08 12:31             ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 12:31 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 06:46:49PM +0800, Shawn Guo wrote:
>> Hi Uwe,
>>
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shawn,
>> >
>> > On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
>> >> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
>> >> [...]
>> >> >> +
>> >> >> +static void icoll_ack_irq(unsigned int irq)
>> >> >> +{
>> >> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
>> >> > You need to write this before handling the irq, no? ?Note this question
>> >> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
>> >> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
>> >> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
>> >> > needed) the write should go into entry-macro.S. ?As I don't have
>> >> > hardware yet I cannot test that. ?Maybe it's only needed when the
>> >> > priority levels are used?!
>> >> >
>> >> Sorry. I made a mistake. ?I thought I had tested the removal of line
>> >> and gave the comment, but actually not. The line is needed, and image
>> >> will stop working without the line.
>> >>
>> >> Regarding to moving the writing to register VECTOR into entry-macro.S,
>> >> can you please help me understand the reason behind the suggestion?
>> > Section 5.2.1 of MCIMX28RM writes:
>> >
>> > ? ? ? ?After the CPU enters the interrupt service routine, it must
>> > ? ? ? ?notify the interrupt collector as soon as possible. Software
>> > ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
>> > ? ? ? ?register.
>> >
>> In case you will ask why, I would give the fact here. ?I'm not sure
>> what is your first thought. ?Mine is to add it into get_irqnr_preamble
>> as below.
>>
>> ? ? ? ? .macro ?get_irqnr_preamble, base, tmp
>> ? ? ? ? ldr ? ? \base, =ICOLL_ADDR
>> ? ? ? ? mov ? ? \tmp, #0
>> ? ? ? ? str ? ? \tmp, [\base]
>> ? ? ? ? .endm
> It's wrong to do that in get_irqnr_preamble.
>
>> But I got the following error.
>>
>> [...]
>> VFS: Mounted root (nfs filesystem) on device 0:11.
>> Freeing init memory: 92K
>> irq 101: nobody cared (try booting with the "irqpoll" option)
>> [<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
>> 4/0x8c)
>> [<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
>> c/0x1d8)
>> [<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
>> 108/0x198)
>> [<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
>> x94)
>> [<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
>> Exception stack(0xc02e7d38 to 0xc02e7d80)
>> 7d20: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c02e7db0 00000000
>> 7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
>> 7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
>> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
>> c)
>> [<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
>> /0x1e8)
>> [<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
>> c/0xb0)
>> [<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
>> d+0x484/0x610)
>> [<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
>> 0x28/0x1c8)
>> [<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
>> c)
>> [<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
>> 0x1fc)
>> [<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
>> c)
>> [<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
>> x388)
>> [<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
>> g+0x80/0x140)
>> [<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
>> 0x180)
>> [<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
>> 10)
>> [<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
>> [<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
>> [<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
>> Exception stack(0xc02e7f80 to 0xc02e7fc8)
>> 7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
>> 7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
>> 7fc0: 60000013 ffffffff
>> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
>> [<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
>> [<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
>> [<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
>> handlers:
>> [<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
>> Disabling IRQ #101
>>
>> However, when I add it into get_irqnr_and_base as below.
>>
>> ? ? ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
>> ? ? ? ? mov ? ? \tmp, #0
>> ? ? ? ? str ? ? \tmp, [\base]
>> ? ? ? ? ldr ? ? \irqnr, [\base, #0x70]
>> ? ? ? ? cmp ? ? \irqnr, #0x7F
>> ? ? ? ? moveqs ?\irqnr, #0
>> ? ? ? ? .endm
>>
>> Everything seems fine.
>
> I think you need to do the following:
>
> ? ? ? ?.macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
> ? ? ? ?ldr ? ? \irqnr, [\base, #0x70]
> ? ? ? ?cmp ? ? \irqnr, #0x7F
> ? ? ? ?strne ? \irqnr, [\base]
> ? ? ? ?moveq ? \irqnr, #0
> ? ? ? ?.endm
>
> (i.e. only write to VECTOR if there is an irq pending).
>
> As before this is completely untested.
>
Tested.  It's OK.  Thanks Uwe.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
  2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-08 20:27   ` Uwe Kleine-König
  2010-12-09  2:02     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 12:31:55AM +0800, Shawn Guo wrote:
>  - DEBUG_LL support, which is incompatible with single MXS image
maybe better: s/single/multi-soc/

>    because of different DUART base address on MX23 and MX28
>  - uncompress message support
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Remove incorrect comments
> 
>  arch/arm/mach-mxs/include/mach/debug-macro.S |   51 +++++++++++++++++
>  arch/arm/mach-mxs/include/mach/uncompress.h  |   78 ++++++++++++++++++++++++++
>  2 files changed, 129 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
>  create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
> new file mode 100644
> index 0000000..efb3173
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
> @@ -0,0 +1,51 @@
> +/* arch/arm/mach-mxs/include/mach/debug-macro.S
> + *
> + * Debugging macro include header
> + *
> + *  Copyright (C) 1994-1999 Russell King
> + *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#include <mach/hardware.h>
> +
> +#ifdef CONFIG_SOC_IMX23
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR	MX23_DUART_BASE_ADDR
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR	MX28_DUART_BASE_ADDR
> +#endif
> +
> +#define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR)
> +
> +		.macro	addruart, rp, rv
> +		ldr	\rp, =UART_PADDR	@ physical
> +		ldr	\rv, =UART_VADDR	@ virtual
> +		.endm
> +
> +		.macro	senduart, rd, rx
> +		str	\rd, [\rx, #0x0]	@ DR
> +		.endm
> +
> +		.macro	waituart, rd, rx
> +1001:		ldr	\rd, [\rx, #0x18]	@ FR
> +		tst	\rd, #1 << 5		@ FR_TXFF
> +		bne	1001b
> +		.endm
> +
> +		.macro	busyuart, rd, rx
> +1002:		ldr	\rd, [\rx, #0x18]	@ FR
> +		tst	\rd, #1 << 3		@ FR_BUSY
> +		beq	1002b
> +		.endm
> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
> new file mode 100644
> index 0000000..efdacc7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
> @@ -0,0 +1,78 @@
> +/*
> + *  arch/arm/mach-mxs/include/mach/uncompress.h
> + *
> + *  Copyright (C) 1999 ARM Limited
> + *  Copyright (C) Shane Nay (shane at minirl.com)
> + *  Copyright 2010 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.
> + */
> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> +#define __MACH_MXS_UNCOMPRESS_H__
> +
> +#define __MXS_BOOT_UNCOMPRESS
> +
> +#include <asm/mach-types.h>
> +
> +static unsigned long uart_base;
> +
> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> +
> +#define DR		0x00
> +#define FR		0x18
> +#define FR_BUSY		(1 << 3)
> +#define FR_TXFE		(1 << 7)
> +#define CR		0x30
> +#define CR_UARTEN	1
Maybe namespace these?  Maybe better define CR_UARTEN as (1 << 0) for
consistency?

> +
> +/*
> + * The following code assumes the serial port has already been
> + * initialized by the bootloader.
Maybe add:
    * If it's not, the output is simply discarded.
> + */
> +
> +static void putc(int ch)
> +{
> +	if (!uart_base)
> +		return;
> +	if (!(UART(CR) & CR_UARTEN))
> +		return;
> +
> +	while (!(UART(FR) & FR_TXFE))
> +		barrier();
> +
> +	UART(DR) = ch;
> +}
> +
> +static inline void flush(void)
> +{
> +}
> +
> +#define MX23_DUART_BASE_ADDR	0x80070000
> +#define MX28_DUART_BASE_ADDR	0x80074000
> +
> +static __inline__ void __arch_decomp_setup(unsigned long arch_id)
> +{
> +	switch (arch_id) {
> +	case MACH_TYPE_MX23EVK:
> +		uart_base = MX23_DUART_BASE_ADDR;
> +		break;
> +	case MACH_TYPE_MX28EVK:
> +		uart_base = MX28_DUART_BASE_ADDR;
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
> +#define arch_decomp_wdog()
> +
> +#endif /* __MACH_MXS_UNCOMPRESS_H__ */
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-12-08 20:28   ` Uwe Kleine-König
  2010-12-09  7:04     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> Add initial mx28evk support with duart and fec0.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Change function mx28evk_fec_reset() from inline to __init
>  - Enable pll2 clock before phy operation
>  - Add error checking for gpio_direction_output()
>  - Save bytes by passing parameter into pr_err format string
>  - Change mx28_add_fec0() to mx28_add_fec(0)
>  - Remove boot_params
> 
>  arch/arm/mach-mxs/mach-mx28evk.c |  126 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 126 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
> 
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> new file mode 100644
> index 0000000..3e8e37a
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright 2010 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.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/irq.h>
> +#include <linux/clk.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx28.h>
> +
> +#include "devices-mx28.h"
> +#include "gpio.h"
> +
> +#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
> +#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
> +
> +static iomux_cfg_t mx28evk_pads[] = {
This can be const and __initconst, ditto for mx23evk

> +	/* duart */
> +	MX28_PAD_PWM0__DUART_RX,
> +	MX28_PAD_PWM1__DUART_TX,
> +
> +	/* fec0 */
> +	MX28_PAD_ENET0_MDC__ENET0_MDC,
> +	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
> +	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
> +	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
> +	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
> +	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
> +	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
> +	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
> +	MX28_PAD_ENET_CLK__ENET_CLK,
> +	/* phy power line */
> +	MX28_PAD_SSP1_DATA3__GPIO_2_15,
> +	/* phy reset line */
> +	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
> +};
> +
> +/* fec */
> +static void __init mx28evk_fec_reset(void)
> +{
> +	int ret;
> +	struct clk *clk;
> +
> +	/* Enable fec phy clock */
> +	clk = clk_get_sys("pll2", NULL);
> +	if (!IS_ERR(clk))
> +		clk_enable(clk);
> +
> +	/* Power up fec phy */
> +	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
> +	if (ret) {
> +		pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
> +		return;
> +	}
> +
> +	ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
> +	if (ret) {
> +		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
> +		return;
> +	}
> +
> +	/* Reset fec phy */
> +	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
> +	if (ret) {
> +		pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
> +		return;
> +	}
> +
> +	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> +	if (ret) {
> +		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
> +		return;
> +	}
> +
> +	mdelay(1);
> +	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> +        .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static void __init mx28evk_init(void)
> +{
> +	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
> +
> +	mx28_add_duart();
> +
> +	mx28evk_fec_reset();
> +	mx28_add_fec(0, &mx28_fec_pdata);
> +}
> +
> +static void __init mx28evk_timer_init(void)
> +{
> +	mx28_clocks_init();
> +}
> +
> +static struct sys_timer mx28evk_timer = {
> +	.init	= mx28evk_timer_init,
> +};
> +
> +MACHINE_START(MX28EVK, "Freescale MX28 EVK")
> +	/* Maintainer: Freescale Semiconductor, Inc. */
> +	.map_io         = mx28_map_io,
> +	.init_irq       = mx28_init_irq,
> +	.init_machine   = mx28evk_init,
> +	.timer          = &mx28evk_timer,
> +MACHINE_END
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-12-08  7:33   ` Lothar Waßmann
@ 2010-12-08 20:31     ` Uwe Kleine-König
  2010-12-09  8:51       ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar,

On Wed, Dec 08, 2010 at 08:33:32AM +0100, Lothar Wa?mann wrote:
> Hi,
> 
> Shawn Guo writes:
> >  - The mxs wdog is implemented in RTC block.
> >  - There is a generic software reset routine for most modules on mxs.
> > 
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v3:
> >  - Change wdog timeout to 10ms for safety
> >  - Simplify function mxs_reset_block() to get it look better
> > 
> > Changes for v2:
> >  - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> > 
> mxs_arch_reset_init() is currently being called from the .map_io hook
> in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
> registered.
> But IMO this should be removed from the .map_io hook anyway (as well
> as mxs_iomux_init()).
I assume you want to make this an initcall?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-08 20:57   ` Uwe Kleine-König
  2010-12-09  1:44     ` Shawn Guo
  2010-12-09  8:41   ` Uwe Kleine-König
  1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 08, 2010 at 12:31:59AM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
>  - Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
really?

> [...]
> +/*
> + * pll_clk
> + */
> +static unsigned long pll_clk_get_rate(struct clk *clk)
> +{
> +	return 480000000;
pll's get_rate still returns 0x1c9c3800

> [...]
> +/*
> + * ref_clk
> + */
> +#define _CLK_GET_RATE_REF(name, sr, ss)					\
> +static unsigned long name##_get_rate(struct clk *clk)			\
> +{									\
> +	unsigned long parent_rate;					\
> +	u32 reg, div;							\
> +									\
> +	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
> +	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
> +	parent_rate = clk_get_rate(clk->parent);			\
> +									\
> +	return parent_rate * 18 / div;					\
> +}
> +
> +_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
ref_cpu_clk's get_rate still uses parent_rate * 18

> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
> +
> +#define _DEFINE_CLOCK_REF(name, er, es)					\
> +	static struct clk name = {					\
> +		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
> +		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
> +		.get_rate	= name##_get_rate,			\
> +		.enable		= _raw_clk_enable,			\
> +		.disable	= _raw_clk_disable,			\
> +		.parent		= &pll_clk,				\
> +	}
> +
> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
ref_cpu_clk's parent still is pll_clk

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-12-08 20:57   ` Uwe Kleine-König
@ 2010-12-09  1:44     ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  1:44 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:59AM +0800, Shawn Guo wrote:
>> Add clock for MXS-based SoCs, MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
> really?
>
>> [...]
>> +/*
>> + * pll_clk
>> + */
>> +static unsigned long pll_clk_get_rate(struct clk *clk)
>> +{
>> + ? ? return 480000000;
> pll's get_rate still returns 0x1c9c3800
>
>> [...]
>> +/*
>> + * ref_clk
>> + */
>> +#define _CLK_GET_RATE_REF(name, sr, ss) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +static unsigned long name##_get_rate(struct clk *clk) ? ? ? ? ? ? ? ? ? ? ? ?\
>> +{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? unsigned long parent_rate; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? u32 reg, div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); ? ? ? ? \
>> + ? ? div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; ? ? ? ? ? ? \
>> + ? ? parent_rate = clk_get_rate(clk->parent); ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? return parent_rate * 18 / div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +}
>> +
>> +_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
> ref_cpu_clk's get_rate still uses parent_rate * 18
>
>> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
>> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
>> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
>> +
>> +#define _DEFINE_CLOCK_REF(name, er, es) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? static struct clk name = { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .enable_reg ? ? = CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er, ?\
>> + ? ? ? ? ? ? .enable_shift ? = BP_CLKCTRL_##er##_CLKGATE##es, ? ? ? ?\
>> + ? ? ? ? ? ? .get_rate ? ? ? = name##_get_rate, ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .enable ? ? ? ? = _raw_clk_enable, ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? .disable ? ? ? ?= _raw_clk_disable, ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? .parent ? ? ? ? = &pll_clk, ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? }
>> +
>> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
> ref_cpu_clk's parent still is pll_clk
>
My mistake.  I only fixed clock-mx28.c and forgot clock-mx23.c.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
  2010-12-08 20:27   ` Uwe Kleine-König
@ 2010-12-09  2:02     ` Shawn Guo
  2010-12-09  8:42       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  2:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:55AM +0800, Shawn Guo wrote:
[...]
>> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
>> new file mode 100644
>> index 0000000..efdacc7
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
>> @@ -0,0 +1,78 @@
>> +/*
>> + * ?arch/arm/mach-mxs/include/mach/uncompress.h
>> + *
>> + * ?Copyright (C) 1999 ARM Limited
>> + * ?Copyright (C) Shane Nay (shane at minirl.com)
>> + * ?Copyright 2010 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.
>> + */
>> +#ifndef __MACH_MXS_UNCOMPRESS_H__
>> +#define __MACH_MXS_UNCOMPRESS_H__
>> +
>> +#define __MXS_BOOT_UNCOMPRESS
>> +
>> +#include <asm/mach-types.h>
>> +
>> +static unsigned long uart_base;
>> +
>> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
>> +
>> +#define DR ? ? ? ? ? 0x00
>> +#define FR ? ? ? ? ? 0x18
>> +#define FR_BUSY ? ? ? ? ? ? ?(1 << 3)
>> +#define FR_TXFE ? ? ? ? ? ? ?(1 << 7)
>> +#define CR ? ? ? ? ? 0x30
>> +#define CR_UARTEN ? ?1
> Maybe namespace these? ?Maybe better define CR_UARTEN as (1 << 0) for
> consistency?
>
Are you expecting namespace "MXS_" or "DUART_" for better?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-08 11:32           ` Lothar Waßmann
@ 2010-12-09  6:15             ` Shawn Guo
  2010-12-09  8:43               ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  6:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Dec 8, 2010 at 7:32 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Shawn Guo writes:
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello,
>> >
>> > On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
>> >> Hi Lothar,
>> >>
>> >> Thanks for the review.
>> >>
>> >> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> >> > Hi,
>> >> >
>> >> > Shawn Guo writes:
>> >> >> MXS-based SoCs implements iomux functions in block PINCTRL.
>> >> >>
>> >> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> >> >> ---
>> >> >> Changes for v2:
>> >> >> ?- Define iomux_cfg_t as u64
>> >> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
>> >> > Really?
>> >> >
>> >> >> +typedef struct pad_desc {
>> >> >> + ? ? unsigned bank:12;
>> >> >> + ? ? unsigned pin:20;
>> >> >> + ? ? unsigned muxsel:8;
>> >> >> + ? ? unsigned ma:12;
>> >> >> + ? ? unsigned vol:8;
>> >> >> + ? ? unsigned pull:4;
>> >> >> +} iomux_cfg_t;
>> >> > ^^^^^^^^^^^^^^^^^
>> >> >
>> >> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
>> >> error is in change log, I would fix it if there is v3 of the patch.
>> > the idea was to really use an u64 to have the pin definitions modifyable.
>> >
>> Ah, I misunderstood the comments. ?But I did not see mxc switches to
>> u64. ?Do you have example to show what you want exactly?
>>
> See:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html
>
Thanks, Lothar.

Hi Uwe,

Looking at the page Lothar gave, the patch is to facilitate adding
platform specific pad_ctrl settings to an
existing pad definition.  In this case, it might be reasonable to keep
EXPORT_SYMBOL(mxs_iomux_setup_pad), which you asked me to remove.
What do you think?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-08 20:28   ` Uwe Kleine-König
@ 2010-12-09  7:04     ` Shawn Guo
  2010-12-09  8:32       ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  7:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> Add initial mx28evk support with duart and fec0.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Change function mx28evk_fec_reset() from inline to __init
>> ?- Enable pll2 clock before phy operation
>> ?- Add error checking for gpio_direction_output()
>> ?- Save bytes by passing parameter into pr_err format string
>> ?- Change mx28_add_fec0() to mx28_add_fec(0)
>> ?- Remove boot_params
>>
>> ?arch/arm/mach-mxs/mach-mx28evk.c | ?126 ++++++++++++++++++++++++++++++++++++++
>> ?1 files changed, 126 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
>>
>> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
>> new file mode 100644
>> index 0000000..3e8e37a
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
>> @@ -0,0 +1,126 @@
>> +/*
>> + * Copyright 2010 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.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/gpio.h>
>> +#include <linux/irq.h>
>> +#include <linux/clk.h>
>> +
>> +#include <asm/mach-types.h>
>> +#include <asm/mach/arch.h>
>> +#include <asm/mach/time.h>
>> +
>> +#include <mach/hardware.h>
>> +#include <mach/common.h>
>> +#include <mach/iomux-mx28.h>
>> +
>> +#include "devices-mx28.h"
>> +#include "gpio.h"
>> +
>> +#define MX28EVK_FEC_PHY_POWER ? ? ? ?MXS_GPIO_NR(2, 15)
>> +#define MX28EVK_FEC_PHY_RESET ? ? ? ?MXS_GPIO_NR(4, 13)
>> +
>> +static iomux_cfg_t mx28evk_pads[] = {
> This can be const and __initconst, ditto for mx23evk
>
With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09  7:04     ` Shawn Guo
@ 2010-12-09  8:32       ` Uwe Kleine-König
  2010-12-09  9:03         ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  8:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shwan,

On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> +static iomux_cfg_t mx28evk_pads[] = {
> > This can be const and __initconst, ditto for mx23evk
> >
> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
Really? Why?

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
  2010-12-08 20:57   ` Uwe Kleine-König
@ 2010-12-09  8:41   ` Uwe Kleine-König
  2010-12-09 10:04     ` Shawn Guo
  2010-12-09 10:30     ` Shawn Guo
  1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  8:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

> +static unsigned long name##_get_rate(struct clk *clk)			\
> +{									\
> +	unsigned long parent_rate;					\
> +	u32 reg, div;							\
> +									\
> +	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
> +	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
> +	parent_rate = clk_get_rate(clk->parent);			\
> +									\
> +	return parent_rate / 1000 * 18 / div * 1000;			\
> +}
1000 isn't the most clever choice.  It might be for a human, but not for
a machine.

I'd suggest (untested):

	return SH_DIV((parent_rate >> 8) * 18, div, 8);

(don't know if 8 is a good value).  What is the range of div here?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
  2010-12-09  2:02     ` Shawn Guo
@ 2010-12-09  8:42       ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  8:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Thu, Dec 09, 2010 at 10:02:48AM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> >> +#define __MACH_MXS_UNCOMPRESS_H__
> >> +
> >> +#define __MXS_BOOT_UNCOMPRESS
is this used, BTW?

> >> +
> >> +#include <asm/mach-types.h>
> >> +
> >> +static unsigned long uart_base;
> >> +
> >> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> >> +
> >> +#define DR ? ? ? ? ? 0x00
> >> +#define FR ? ? ? ? ? 0x18
> >> +#define FR_BUSY ? ? ? ? ? ? ?(1 << 3)
> >> +#define FR_TXFE ? ? ? ? ? ? ?(1 << 7)
> >> +#define CR ? ? ? ? ? 0x30
> >> +#define CR_UARTEN ? ?1
> > Maybe namespace these? ?Maybe better define CR_UARTEN as (1 << 0) for
> > consistency?
> >
> Are you expecting namespace "MXS_" or "DUART_" for better?
both?

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 08/15] ARM: mxs: Add iomux support
  2010-12-09  6:15             ` Shawn Guo
@ 2010-12-09  8:43               ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  8:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On Thu, Dec 09, 2010 at 02:15:27PM +0800, Shawn Guo wrote:
> >> Ah, I misunderstood the comments. ?But I did not see mxc switches to
> >> u64. ?Do you have example to show what you want exactly?
> >>
> > See:
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html
> >
> Thanks, Lothar.
> 
> Hi Uwe,
> 
> Looking at the page Lothar gave, the patch is to facilitate adding
> platform specific pad_ctrl settings to an
> existing pad definition.  In this case, it might be reasonable to keep
> EXPORT_SYMBOL(mxs_iomux_setup_pad), which you asked me to remove.
> What do you think?
Just don't make it static.  There is no need for EXPORT_SYMBOL.  Ditto
for the multiple variant.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-12-08 20:31     ` Uwe Kleine-König
@ 2010-12-09  8:51       ` Shawn Guo
  2010-12-09  8:55         ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hi Lothar,
>
> On Wed, Dec 08, 2010 at 08:33:32AM +0100, Lothar Wa?mann wrote:
>> Hi,
>>
>> Shawn Guo writes:
>> > ?- The mxs wdog is implemented in RTC block.
>> > ?- There is a generic software reset routine for most modules on mxs.
>> >
>> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> > ---
>> > Changes for v3:
>> > ?- Change wdog timeout to 10ms for safety
>> > ?- Simplify function mxs_reset_block() to get it look better
>> >
>> > Changes for v2:
>> > ?- Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
>> >
>> mxs_arch_reset_init() is currently being called from the .map_io hook
>> in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
>> registered.
>> But IMO this should be removed from the .map_io hook anyway (as well
>> as mxs_iomux_init()).
> I assume you want to make this an initcall?
>
Here is how they look.

static int __init mxs_arch_reset_init(void)
{
        struct clk *clk;

        wdog_base = cpu_is_mx23() ? MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR) :
                                    MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR);

        clk = clk_get_sys("rtc", NULL);
        if (!IS_ERR(clk))
                clk_enable(clk);
        else

        return 0;
}
core_initcall(mxs_arch_reset_init);

static int __init mxs_iomux_init(void)
{
        iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);

        return 0;
}
core_initcall(mxs_iomux_init);

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 03/15] ARM: mxs: Add reset routines
  2010-12-09  8:51       ` Shawn Guo
@ 2010-12-09  8:55         ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  8:55 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 09, 2010 at 04:51:08PM +0800, Shawn Guo wrote:
> static int __init mxs_iomux_init(void)
> {
>         iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
> 
>         return 0;
> }
> core_initcall(mxs_iomux_init);
why not simply initialize iomux_base statically?

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09  8:32       ` Uwe Kleine-König
@ 2010-12-09  9:03         ` Shawn Guo
  2010-12-09  9:37           ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shwan,
>
> On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> +static iomux_cfg_t mx28evk_pads[] = {
>> > This can be const and __initconst, ditto for mx23evk
>> >
>> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> Really? Why?
>
I'm confused by the compiling error below when adding __initconst for
mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.

arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
section type conflict
make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
make: *** [arch/arm/mach-mxs] Error 2

Actually it can be fixed by the following change.

-static const struct fec_platform_data mx28_fec_pdata __initconst = {
+static struct fec_platform_data mx28_fec_pdata __initconst = {
         .phy = PHY_INTERFACE_MODE_RMII,
 };

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09  9:03         ` Shawn Guo
@ 2010-12-09  9:37           ` Uwe Kleine-König
  2010-12-09 10:17             ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn
On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shwan,
ups, sorry for mistyping your name.

> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> >> +static iomux_cfg_t mx28evk_pads[] = {
> >> > This can be const and __initconst, ditto for mx23evk
> >> >
> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> > Really? Why?
> >
> I'm confused by the compiling error below when adding __initconst for
> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
> 
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
> section type conflict
> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
> make: *** [arch/arm/mach-mxs] Error 2
> 
> Actually it can be fixed by the following change.
> 
> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>          .phy = PHY_INTERFACE_MODE_RMII,
>  };
this change is wrong.  You need to assert that all data being marked
with __initconst is const, too.

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-12-09  8:41   ` Uwe Kleine-König
@ 2010-12-09 10:04     ` Shawn Guo
  2010-12-09 10:30     ` Shawn Guo
  1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> +static unsigned long name##_get_rate(struct clk *clk) ? ? ? ? ? ? ? ? ? ? ? ?\
>> +{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? unsigned long parent_rate; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? u32 reg, div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); ? ? ? ? \
>> + ? ? div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; ? ? ? ? ? ? \
>> + ? ? parent_rate = clk_get_rate(clk->parent); ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? return parent_rate / 1000 * 18 / div * 1000; ? ? ? ? ? ? ? ? ? ?\
>> +}
> 1000 isn't the most clever choice. ?It might be for a human, but not for
> a machine.
>
> I'd suggest (untested):
>
> ? ? ? ?return SH_DIV((parent_rate >> 8) * 18, div, 8);
>
> (don't know if 8 is a good value). ?What is the range of div here?
>
The div range is 18 ~ 35.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09  9:37           ` Uwe Kleine-König
@ 2010-12-09 10:17             ` Shawn Guo
  2010-12-09 12:27               ` Lothar Waßmann
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:17 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn
> On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shwan,
> ups, sorry for mistyping your name.
>
>> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>> >> > This can be const and __initconst, ditto for mx23evk
>> >> >
>> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>> > Really? Why?
>> >
>> I'm confused by the compiling error below when adding __initconst for
>> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>>
>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>> section type conflict
>> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>> make: *** [arch/arm/mach-mxs] Error 2
>>
>> Actually it can be fixed by the following change.
>>
>> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>> ?};
> this change is wrong. ?You need to assert that all data being marked
> with __initconst is const, too.
>
After adding const for mx28evk_pads[], I got the following error.

  CC      arch/arm/mach-mxs/mach-mx28evk.o
arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
target type
arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?

This takes me back to my first judgment.  Is it proper to add
__initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
making pad definition modifiable.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 09/15] ARM: mxs: Add clock support
  2010-12-09  8:41   ` Uwe Kleine-König
  2010-12-09 10:04     ` Shawn Guo
@ 2010-12-09 10:30     ` Shawn Guo
  1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:30 UTC (permalink / raw)
  To: linux-arm-kernel

2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> +static unsigned long name##_get_rate(struct clk *clk) ? ? ? ? ? ? ? ? ? ? ? ?\
>> +{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? unsigned long parent_rate; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? u32 reg, div; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr); ? ? ? ? \
>> + ? ? div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f; ? ? ? ? ? ? \
>> + ? ? parent_rate = clk_get_rate(clk->parent); ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? return parent_rate / 1000 * 18 / div * 1000; ? ? ? ? ? ? ? ? ? ?\
>> +}
> 1000 isn't the most clever choice. ?It might be for a human, but not for
> a machine.
>
> I'd suggest (untested):
>
> ? ? ? ?return SH_DIV((parent_rate >> 8) * 18, div, 8);
>
> (don't know if 8 is a good value). ?What is the range of div here?
>
Tested.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09 10:17             ` Shawn Guo
@ 2010-12-09 12:27               ` Lothar Waßmann
  2010-12-09 13:38                 ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

Shawn Guo writes:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn
> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > Hello Shwan,
> > ups, sorry for mistyping your name.
> >
> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
> >> >> > This can be const and __initconst, ditto for mx23evk
> >> >> >
> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> >> > Really? Why?
> >> >
> >> I'm confused by the compiling error below when adding __initconst for
> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
> >>
> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
> >> section type conflict
> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
> >> make: *** [arch/arm/mach-mxs] Error 2
> >>
> >> Actually it can be fixed by the following change.
> >>
> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
> >> ?};
> > this change is wrong. ?You need to assert that all data being marked
> > with __initconst is const, too.
> >
> After adding const for mx28evk_pads[], I got the following error.
> 
>   CC      arch/arm/mach-mxs/mach-mx28evk.o
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
> target type
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
> 
The argument of mxs_iomux_setup_multiple_pads() should get the const
attribute:
-int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)

> This takes me back to my first judgment.  Is it proper to add
> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
> making pad definition modifiable.
> 
Modifiable in the sense that you can add platform specific PAD
settings by simply ORing them to the original pad definition so that
there is no need for runtime modifications like:
|	iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
...
|	power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
|	mxc_iomux_v3_setup_pad(&power_key);
but you can do:
|	iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
|				~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
...
|	mxc_iomux_v3_setup_pad(power_key);
instead. You can also augment the pad desc in a static table:
|static iomux_cfg_t pad_desc[] = {
|	(MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09 12:27               ` Lothar Waßmann
@ 2010-12-09 13:38                 ` Shawn Guo
  2010-12-09 13:54                   ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar,

On Thu, Dec 9, 2010 at 8:27 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Shawn Guo writes:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shawn
>> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > Hello Shwan,
>> > ups, sorry for mistyping your name.
>> >
>> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>> >> >> > This can be const and __initconst, ditto for mx23evk
>> >> >> >
>> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>> >> > Really? Why?
>> >> >
>> >> I'm confused by the compiling error below when adding __initconst for
>> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>> >>
>> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>> >> section type conflict
>> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>> >> make: *** [arch/arm/mach-mxs] Error 2
>> >>
>> >> Actually it can be fixed by the following change.
>> >>
>> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>> >> ?};
>> > this change is wrong. ?You need to assert that all data being marked
>> > with __initconst is const, too.
>> >
>> After adding const for mx28evk_pads[], I got the following error.
>>
>> ? CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
>> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
>> target type
>> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
>> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>>
> The argument of mxs_iomux_setup_multiple_pads() should get the const
> attribute:
> -int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>
>> This takes me back to my first judgment. ?Is it proper to add
>> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
>> making pad definition modifiable.
>>
> Modifiable in the sense that you can add platform specific PAD
> settings by simply ORing them to the original pad definition so that
> there is no need for runtime modifications like:
> | ? ? ? iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
> ...
> | ? ? ? power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
> | ? ? ? mxc_iomux_v3_setup_pad(&power_key);
> but you can do:
> | ? ? ? iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
> ...
> | ? ? ? mxc_iomux_v3_setup_pad(power_key);
> instead. You can also augment the pad desc in a static table:
> |static iomux_cfg_t pad_desc[] = {
> | ? ? ? (MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,
>
>
Thanks for the explanation.  But I'm a little puzzled by the use of
"const" here. Per your suggestion, I have the following.

mach-28evk.c
static const iomux_cfg_t mx28evk_pads[] __initconst = {

iomux.h
int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);

iomux.c
int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)

Compiler complains as below.

  CC      arch/arm/mach-mxs/iomux.o
arch/arm/mach-mxs/iomux.c:89: error: conflicting types for
?mxs_iomux_setup_multiple_pads?
arch/arm/mach-mxs/include/mach/iomux.h:115: note: previous declaration
of ?mxs_iomux_setup_multiple_pads? was here
make[1]: *** [arch/arm/mach-mxs/iomux.o] Error 1
make: *** [arch/arm/mach-mxs] Error 2

If I remove the "const" in iomux.h as below.

iomux.h
int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);

Compiler gives the following warning.

  CC      arch/arm/mach-mxs/mach-mx28evk.o
arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
target type
arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?

What's wrong here?

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
  2010-12-09 13:38                 ` Shawn Guo
@ 2010-12-09 13:54                   ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 13:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Dec 9, 2010 at 9:38 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> Hi Lothar,
>
> On Thu, Dec 9, 2010 at 8:27 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> Shawn Guo writes:
>>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> > Hello Shawn
>>> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> >> > Hello Shwan,
>>> > ups, sorry for mistyping your name.
>>> >
>>> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>>> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>>> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>>> >> >> > This can be const and __initconst, ditto for mx23evk
>>> >> >> >
>>> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>>> >> > Really? Why?
>>> >> >
>>> >> I'm confused by the compiling error below when adding __initconst for
>>> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>>> >>
>>> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>>> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>>> >> section type conflict
>>> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>>> >> make: *** [arch/arm/mach-mxs] Error 2
>>> >>
>>> >> Actually it can be fixed by the following change.
>>> >>
>>> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>>> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>>> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>>> >> ?};
>>> > this change is wrong. ?You need to assert that all data being marked
>>> > with __initconst is const, too.
>>> >
>>> After adding const for mx28evk_pads[], I got the following error.
>>>
>>> ? CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
>>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>>> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
>>> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
>>> target type
>>> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
>>> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>>>
>> The argument of mxs_iomux_setup_multiple_pads() should get the const
>> attribute:
>> -int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
>> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>>
>>> This takes me back to my first judgment. ?Is it proper to add
>>> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
>>> making pad definition modifiable.
>>>
>> Modifiable in the sense that you can add platform specific PAD
>> settings by simply ORing them to the original pad definition so that
>> there is no need for runtime modifications like:
>> | ? ? ? iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
>> ...
>> | ? ? ? power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
>> | ? ? ? mxc_iomux_v3_setup_pad(&power_key);
>> but you can do:
>> | ? ? ? iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
>> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
>> ...
>> | ? ? ? mxc_iomux_v3_setup_pad(power_key);
>> instead. You can also augment the pad desc in a static table:
>> |static iomux_cfg_t pad_desc[] = {
>> | ? ? ? (MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,
>>
>>
> Thanks for the explanation. ?But I'm a little puzzled by the use of
> "const" here. Per your suggestion, I have the following.
>
> mach-28evk.c
> static const iomux_cfg_t mx28evk_pads[] __initconst = {
>
> iomux.h
> int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
>
> iomux.c
> int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>
> Compiler complains as below.
>
> ?CC ? ? ?arch/arm/mach-mxs/iomux.o
> arch/arm/mach-mxs/iomux.c:89: error: conflicting types for
> ?mxs_iomux_setup_multiple_pads?
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: previous declaration
> of ?mxs_iomux_setup_multiple_pads? was here
> make[1]: *** [arch/arm/mach-mxs/iomux.o] Error 1
> make: *** [arch/arm/mach-mxs] Error 2
>
> If I remove the "const" in iomux.h as below.
>
> iomux.h
> int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
>
> Compiler gives the following warning.
>
> ?CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
> target type
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>
> What's wrong here?
>
Sorry.  Please ignore this message.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v4 01/15] ARM: mxs: Add core definitions
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (32 preceding siblings ...)
  2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 17:37   ` Russell King - ARM Linux
  2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
                   ` (12 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add core definitions for MXS-based SoC MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Move all MXS related definitions from hardware.h into mxs.h,
   but have to keep hardware.h which is required by external file.
 - Define IO addresses common to MXS-based in mxs.h
 - Include hardware.h in mxs.h, include mxs.h in mx23.h and mx28.h,
   so that files can include mxs.h, mx23.h, mx28.h individually
   when necessary.
 - Remove #include <linux/io.h> from mx23.h and mx28.h, since it's
   not necessary.

Changes for v3:
 - Update MXS_IO_P2V definition and comment to get them matched
 - Sort mx23 base address definitions by offset
 - Remove mx28 reserved IRQ definitions
 - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()

Changes for v2:
 - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
 - Simplify MXS_IO_P2V_MODULE definition in hardware.h
 - Remove unnecessary inclusion protection from hardware.h
 - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx

 arch/arm/mach-mxs/include/mach/hardware.h |   29 +++++
 arch/arm/mach-mxs/include/mach/irqs.h     |   32 +++++
 arch/arm/mach-mxs/include/mach/memory.h   |   24 ++++
 arch/arm/mach-mxs/include/mach/mx23.h     |  145 ++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mx28.h     |  188 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/mxs.h      |   85 +++++++++++++
 6 files changed, 503 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
 create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
 create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h

diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..53e89a0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr)	(addr)
+#else
+#define IOMEM(addr)	((void __force __iomem *)(addr))
+#endif
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS	128
+
+#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS		(32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes.  Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS		16
+
+#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET		UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..9edd02e
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX23_H__
+#define __MACH_MX23_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR		0x00000000
+#define MX23_OCRAM_SIZE			SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR		0x80000000
+#define MX23_IO_SIZE			SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART			0
+#define MX23_INT_COMMS_RX		1
+#define MX23_INT_COMMS_TX		1
+#define MX23_INT_SSP2_ERROR		2
+#define MX23_INT_VDD5V			3
+#define MX23_INT_HEADPHONE_SHORT	4
+#define MX23_INT_DAC_DMA		5
+#define MX23_INT_DAC_ERROR		6
+#define MX23_INT_ADC_DMA		7
+#define MX23_INT_ADC_ERROR		8
+#define MX23_INT_SPDIF_DMA		9
+#define MX23_INT_SAIF2_DMA		9
+#define MX23_INT_SPDIF_ERROR		10
+#define MX23_INT_SAIF1_IRQ		10
+#define MX23_INT_SAIF2_IRQ		10
+#define MX23_INT_USB_CTRL		11
+#define MX23_INT_USB_WAKEUP		12
+#define MX23_INT_GPMI_DMA		13
+#define MX23_INT_SSP1_DMA		14
+#define MX23_INT_SSP_ERROR		15
+#define MX23_INT_GPIO0			16
+#define MX23_INT_GPIO1			17
+#define MX23_INT_GPIO2			18
+#define MX23_INT_SAIF1_DMA		19
+#define MX23_INT_SSP2_DMA		20
+#define MX23_INT_ECC8_IRQ		21
+#define MX23_INT_RTC_ALARM		22
+#define MX23_INT_UARTAPP_TX_DMA		23
+#define MX23_INT_UARTAPP_INTERNAL	24
+#define MX23_INT_UARTAPP_RX_DMA		25
+#define MX23_INT_I2C_DMA		26
+#define MX23_INT_I2C_ERROR		27
+#define MX23_INT_TIMER0			28
+#define MX23_INT_TIMER1			29
+#define MX23_INT_TIMER2			30
+#define MX23_INT_TIMER3			31
+#define MX23_INT_BATT_BRNOUT		32
+#define MX23_INT_VDDD_BRNOUT		33
+#define MX23_INT_VDDIO_BRNOUT		34
+#define MX23_INT_VDD18_BRNOUT		35
+#define MX23_INT_TOUCH_DETECT		36
+#define MX23_INT_LRADC_CH0		37
+#define MX23_INT_LRADC_CH1		38
+#define MX23_INT_LRADC_CH2		39
+#define MX23_INT_LRADC_CH3		40
+#define MX23_INT_LRADC_CH4		41
+#define MX23_INT_LRADC_CH5		42
+#define MX23_INT_LRADC_CH6		43
+#define MX23_INT_LRADC_CH7		44
+#define MX23_INT_LCDIF_DMA		45
+#define MX23_INT_LCDIF_ERROR		46
+#define MX23_INT_DIGCTL_DEBUG_TRAP	47
+#define MX23_INT_RTC_1MSEC		48
+#define MX23_INT_DRI_DMA		49
+#define MX23_INT_DRI_ATTENTION		50
+#define MX23_INT_GPMI_ATTENTION		51
+#define MX23_INT_IR			52
+#define MX23_INT_DCP_VMI		53
+#define MX23_INT_DCP			54
+#define MX23_INT_BCH			56
+#define MX23_INT_PXP			57
+#define MX23_INT_UARTAPP2_TX_DMA	58
+#define MX23_INT_UARTAPP2_INTERNAL	59
+#define MX23_INT_UARTAPP2_RX_DMA	60
+#define MX23_INT_VDAC_DETECT		61
+#define MX23_INT_VDD5V_DROOP		64
+#define MX23_INT_DCDC4P2_BO		65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..0716745
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR		0x00000000
+#define MX28_OCRAM_SIZE			SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR		0x80000000
+#define MX28_IO_SIZE			SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT		0
+#define MX28_INT_VDDD_BRNOUT		1
+#define MX28_INT_VDDIO_BRNOUT		2
+#define MX28_INT_VDDA_BRNOUT		3
+#define MX28_INT_VDD5V_DROOP		4
+#define MX28_INT_DCDC4P2_BRNOUT		5
+#define MX28_INT_VDD5V			6
+#define MX28_INT_CAN0			8
+#define MX28_INT_CAN1			9
+#define MX28_INT_LRADC_TOUCH		10
+#define MX28_INT_HSADC			13
+#define MX28_INT_IRADC_THRESH0		14
+#define MX28_INT_IRADC_THRESH1		15
+#define MX28_INT_LRADC_CH0		16
+#define MX28_INT_LRADC_CH1		17
+#define MX28_INT_LRADC_CH2		18
+#define MX28_INT_LRADC_CH3		19
+#define MX28_INT_LRADC_CH4		20
+#define MX28_INT_LRADC_CH5		21
+#define MX28_INT_LRADC_CH6		22
+#define MX28_INT_LRADC_CH7		23
+#define MX28_INT_LRADC_BUTTON0		24
+#define MX28_INT_LRADC_BUTTON1		25
+#define MX28_INT_PERFMON		27
+#define MX28_INT_RTC_1MSEC		28
+#define MX28_INT_RTC_ALARM		29
+#define MX28_INT_COMMS			31
+#define MX28_INT_EMI_ERR		32
+#define MX28_INT_LCDIF			38
+#define MX28_INT_PXP			39
+#define MX28_INT_BCH			41
+#define MX28_INT_GPMI			42
+#define MX28_INT_SPDIF_ERROR		45
+#define MX28_INT_DUART			47
+#define MX28_INT_TIMER0			48
+#define MX28_INT_TIMER1			49
+#define MX28_INT_TIMER2			50
+#define MX28_INT_TIMER3			51
+#define MX28_INT_DCP_VMI		52
+#define MX28_INT_DCP			53
+#define MX28_INT_DCP_SECURE		54
+#define MX28_INT_SAIF1			58
+#define MX28_INT_SAIF0			59
+#define MX28_INT_SPDIF_DMA		66
+#define MX28_INT_I2C0_DMA		68
+#define MX28_INT_I2C1_DMA		69
+#define MX28_INT_AUART0_RX_DMA		70
+#define MX28_INT_AUART0_TX_DMA		71
+#define MX28_INT_AUART1_RX_DMA		72
+#define MX28_INT_AUART1_TX_DMA		73
+#define MX28_INT_AUART2_RX_DMA		74
+#define MX28_INT_AUART2_TX_DMA		75
+#define MX28_INT_AUART3_RX_DMA		76
+#define MX28_INT_AUART3_TX_DMA		77
+#define MX28_INT_AUART4_RX_DMA		78
+#define MX28_INT_AUART4_TX_DMA		79
+#define MX28_INT_SAIF0_DMA		80
+#define MX28_INT_SAIF1_DMA		81
+#define MX28_INT_SSP0_DMA		82
+#define MX28_INT_SSP1_DMA		83
+#define MX28_INT_SSP2_DMA		84
+#define MX28_INT_SSP3_DMA		85
+#define MX28_INT_LCDIF_DMA		86
+#define MX28_INT_HSADC_DMA		87
+#define MX28_INT_GPMI_DMA		88
+#define MX28_INT_DIGCTL_DEBUG_TRAP	89
+#define MX28_INT_USB1			92
+#define MX28_INT_USB0			93
+#define MX28_INT_USB1_WAKEUP		94
+#define MX28_INT_USB0_WAKEUP		95
+#define MX28_INT_SSP0			96
+#define MX28_INT_SSP1			97
+#define MX28_INT_SSP2			98
+#define MX28_INT_SSP3			99
+#define MX28_INT_ENET_SWI		100
+#define MX28_INT_ENET_MAC0		101
+#define MX28_INT_ENET_MAC1		102
+#define MX28_INT_ENET_MAC0_1588		103
+#define MX28_INT_ENET_MAC1_1588		104
+#define MX28_INT_I2C1_ERROR		110
+#define MX28_INT_I2C0_ERROR		111
+#define MX28_INT_AUART0			112
+#define MX28_INT_AUART1			113
+#define MX28_INT_AUART2			114
+#define MX28_INT_AUART3			115
+#define MX28_INT_AUART4			116
+#define MX28_INT_GPIO4			123
+#define MX28_INT_GPIO3			124
+#define MX28_INT_GPIO2			125
+#define MX28_INT_GPIO1			126
+#define MX28_INT_GPIO0			127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..4212ab0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+/*
+ * MXS CPU types
+ */
+#define cpu_is_mx23()		(machine_is_mx23evk())
+#define cpu_is_mx28()		(machine_is_mx28evk())
+
+#define MXS_SET_ADDR		0x4
+#define MXS_CLR_ADDR		0x8
+#define MXS_TOG_ADDR		0xc
+
+/*
+ * IO addresses common to MXS-based
+ */
+#define MXS_IO_BASE_ADDR		0x80000000
+#define MXS_IO_SIZE			SZ_1M
+
+#define MXS_ICOLL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x000000)
+#define MXS_APBH_DMA_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x004000)
+#define MXS_BCH_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x00a000)
+#define MXS_GPMI_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x00c000)
+#define MXS_PINCTRL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x018000)
+#define MXS_DIGCTL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x01c000)
+#define MXS_APBX_DMA_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x024000)
+#define MXS_DCP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x028000)
+#define MXS_PXP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02a000)
+#define MXS_OCOTP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02c000)
+#define MXS_AXI_AHB0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02e000)
+#define MXS_LCDIF_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x030000)
+#define MXS_CLKCTRL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x040000)
+#define MXS_SAIF0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x042000)
+#define MXS_POWER_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x044000)
+#define MXS_SAIF1_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x046000)
+#define MXS_LRADC_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x050000)
+#define MXS_SPDIF_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x054000)
+#define MXS_I2C0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x058000)
+#define MXS_PWM_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x064000)
+#define MXS_TIMROT_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x068000)
+#define MXS_AUART1_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x06c000)
+#define MXS_AUART2_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x06e000)
+#define MXS_DRAM_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x0e0000)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf50fffff].
+ *
+ *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
+ *	IO	0x80000000+0x100000	->	0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x)	(0xf4000000 +					\
+			(((x) & 0x80000000) >> 7) +			\
+			(((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
+
+#define mxs_map_entry(soc, name, _type)	{				\
+	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
+	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
+	.length = soc ## _ ## name ## _SIZE,				\
+	.type = _type,							\
+}
+
+#endif /* __MACH_MXS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 02/15] ARM: mxs: Add helper definition and function
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (33 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
                   ` (11 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add helper definition and function for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Remove reference to mxs_arch_reset_init() from common.h,
   since it becomes __initcall.
 - icoll_init_irq() does not need to carry on icoll base address,
   since MX23 and MX28 share the same one.
 - mxs_timer_init() does not need to carry on timrot base address,
   since MX23 and MX28 share the same one.

Changes for v2:
 - Remove cpu.c and reference to mxs_set_cpu_type() from common.h

 arch/arm/mach-mxs/include/mach/common.h  |   31 ++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/io.h      |   22 +++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/timex.h   |   21 ++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/vmalloc.h |   22 +++++++++++++++++++++
 4 files changed, 96 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/common.h
 create mode 100644 arch/arm/mach-mxs/include/mach/io.h
 create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
 create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h

diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..59133eb
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_timer_init(struct clk *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright 2004-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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a)		__typesafe_io(a)
+
+#define __mem_pci(a)	(a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ * Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE		32000	/* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ *  Copyright (C) 2000 Russell King.
+ *  Copyright 2004-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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END       0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v4 03/15] ARM: mxs: Add reset routines
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (34 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
                   ` (10 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

 - The mxs wdog is implemented in RTC block.
 - There is a generic software reset routine for most modules on mxs.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Add blank line above comment to make the code easy to read
 - Tell compiler unlikely(ret)
 - Make mxs_arch_reset_init __initcall

Changes for v3:
 - Change wdog timeout to 10ms for safety
 - Simplify function mxs_reset_block() to get it look better

Changes for v2:
 - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()

 arch/arm/mach-mxs/include/mach/system.h |   27 ++++++
 arch/arm/mach-mxs/system.c              |  142 +++++++++++++++++++++++++++++++
 2 files changed, 169 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/system.h
 create mode 100644 arch/arm/mach-mxs/system.c

diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+	cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..bc73f9f
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG	0x50
+#define MXS_WATCHDOG_EN		(1 << 4)
+
+#define MXS_MODULE_CLKGATE	(1 << 30)
+#define MXS_MODULE_SFTRST	(1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+	/* Set wdog timer 10 ms */
+	__raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
+
+	/* Enable wdog reset */
+	__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+	/* Wait for reset to assert... */
+	mdelay(10);
+
+	pr_err("Watchdog reset failed to assert reset\n");
+
+	/* Delay to allow the serial port to show the message */
+	mdelay(50);
+
+	/* We'll take a jump through zero as a poor second */
+	cpu_reset(0);
+}
+
+static int __init mxs_arch_reset_init(void)
+{
+	struct clk *clk;
+
+	wdog_base = cpu_is_mx23() ? MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR) :
+				    MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR);
+
+	clk = clk_get_sys("rtc", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+
+	return 0;
+}
+core_initcall(mxs_arch_reset_init);
+
+/*
+ * Clear the bit and poll it cleared.  This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+	int timeout = 0x400;
+
+	/* clear the bit */
+	__raw_writel(mask, addr + MXS_CLR_ADDR);
+
+	/*
+	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
+	 * recommends to wait 1us.
+	 */
+	udelay(1);
+
+	/* poll the bit becoming clear */
+	while ((__raw_readl(addr) & mask) && --timeout)
+		/* nothing */;
+
+	return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+	int ret;
+	int timeout = 0x400;
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+	if (unlikely(ret))
+		goto error;
+
+	/* clear CLKGATE */
+	__raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+
+	/* set SFTRST to reset the block */
+	__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
+	udelay(1);
+
+	/* poll CLKGATE becoming set */
+	while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+		/* nothing */;
+	if (unlikely(!timeout))
+		goto error;
+
+	/* clear and poll SFTRST */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+	if (unlikely(ret))
+		goto error;
+
+	/* clear and poll CLKGATE */
+	ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+	if (unlikely(ret))
+		goto error;
+
+	return 0;
+
+error:
+	pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+	return -ETIMEDOUT;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 04/15] ARM: mxs: Add interrupt support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (35 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
                   ` (9 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add Interrupt Collector (ICOLL) support for MXS-based.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - icoll.c: add #include <linux/io.h> as it's removed from mx23.h
   and mx28.h
 - Change inclusion of hardware.h to mxs.h
 - Move writing to HW_ICOLL_VECTOR from icoll.c icoll_ack_irq()
   into entry-macro.S get_irqnr_and_base
 - icoll.c: add more words into comments for level 0 irq ack
 - mx23 and mx28 share the same icoll base address, so hard-coding
   of the address is ok
 - entry-macro.S: define and use HW_ICOLL_STAT_OFFSET over 0x70

Changes for v2:
 - Get icoll base in get_irqnr_preamble
 - Check the case of single SoC build and use hard-coding address if possible

 arch/arm/mach-mxs/icoll.c                    |   81 ++++++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/entry-macro.S |   41 +++++++++++++
 2 files changed, 122 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/icoll.c
 create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S

diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..5dd43ba
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR				0x0000
+#define HW_ICOLL_LEVELACK			0x0010
+#define HW_ICOLL_CTRL				0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
+
+static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
+
+static void icoll_ack_irq(unsigned int irq)
+{
+	/*
+	 * The Interrupt Collector is able to prioritize irqs.
+	 * Currently only level 0 is used. So acking can use
+	 * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+	 */
+	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+			icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+	.ack = icoll_ack_irq,
+	.mask = icoll_mask_irq,
+	.unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void)
+{
+	int i;
+
+	/*
+	 * Interrupt Collector reset, which initializes the priority
+	 * for each irq to level 0.
+	 */
+	mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+	for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxs_icoll_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..2f2a7cf
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/mxs.h>
+
+#define ICOLL_VBASE		MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR)
+#define HW_ICOLL_STAT_OFFSET	0x70
+
+	.macro	disable_fiq
+	.endm
+
+	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr	\irqnr, [\base, #HW_ICOLL_STAT_OFFSET]
+	cmp	\irqnr, #0x7F
+	strne	\irqnr, [\base]
+	moveqs	\irqnr, #0
+	.endm
+
+	.macro  get_irqnr_preamble, base, tmp
+	ldr	\base, =ICOLL_VBASE
+	.endm
+
+	.macro  arch_ret_to_user, tmp1, tmp2
+	.endm
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (36 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
                   ` (8 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

 - DEBUG_LL support, which is incompatible with multi-soc MXS image
   because of different DUART base address on MX23 and MX28
 - uncompress message support

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - debug-macro.S: change inclusion of hardware.h to mx23.h plus mx28.h
 - Remove #define __MXS_BOOT_UNCOMPRESS
 - Add namespace MXS_DUART_ for macros
 - Add comment "If it's not, the output is simply discarded."

Changes for v2:
 - Remove incorrect comments

 arch/arm/mach-mxs/include/mach/debug-macro.S |   52 ++++++++++++++++++
 arch/arm/mach-mxs/include/mach/uncompress.h  |   76 ++++++++++++++++++++++++++
 2 files changed, 128 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
 create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h

diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..a1522fd
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,52 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ *  Copyright (C) 1994-1999 Russell King
+ *  Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR	MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR	MXS_IO_ADDRESS(UART_PADDR)
+
+		.macro	addruart, rp, rv
+		ldr	\rp, =UART_PADDR	@ physical
+		ldr	\rv, =UART_VADDR	@ virtual
+		.endm
+
+		.macro	senduart, rd, rx
+		str	\rd, [\rx, #0x0]	@ DR
+		.endm
+
+		.macro	waituart, rd, rx
+1001:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 5		@ FR_TXFF
+		bne	1001b
+		.endm
+
+		.macro	busyuart, rd, rx
+1002:		ldr	\rd, [\rx, #0x18]	@ FR
+		tst	\rd, #1 << 3		@ FR_BUSY
+		beq	1002b
+		.endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..793d92e
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ *  arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) Shane Nay (shane@minirl.com)
+ *  Copyright 2010 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define MXS_DUART_DR		0x00
+#define MXS_DUART_FR		0x18
+#define MXS_DUART_FR_TXFE	(1 << 7)
+#define MXS_DUART_CR		0x30
+#define MXS_DUART_CR_UARTEN	(1 << 0)
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If it's not, the output is
+ * simply discarded.
+ */
+
+static void putc(int ch)
+{
+	if (!uart_base)
+		return;
+	if (!(UART(MXS_DUART_CR) & MXS_DUART_CR_UARTEN))
+		return;
+
+	while (!(UART(MXS_DUART_FR) & MXS_DUART_FR_TXFE))
+		barrier();
+
+	UART(MXS_DUART_DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR	0x80070000
+#define MX28_DUART_BASE_ADDR	0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+	switch (arch_id) {
+	case MACH_TYPE_MX23EVK:
+		uart_base = MX23_DUART_BASE_ADDR;
+		break;
+	case MACH_TYPE_MX28EVK:
+		uart_base = MX28_DUART_BASE_ADDR;
+		break;
+	default:
+		break;
+	}
+}
+
+#define arch_decomp_setup()	__arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v4 06/15] ARM: mxs: Add timer support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (37 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
                   ` (7 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

There are 2 versions of the timrot on Freescale MXS-based SoCs.
The v1 on MX23 only gets 16 bits counter, while v2 on MX28
extends the counter to 32 bits.

The implementation uses two timers, one for clock_event and
another for clocksource. MX28 uses timer0 and timer1, while
MX23 uses timer0 and timer3.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
 - Change inclusion of hardware.h to mxs.h
 - Use two timers on MX28 also to simpify timrotv2_set_next_event()
 - MX23 and MX28 share the common timrot base address, so it can be
   a hard-assignment.
 - Pass &clockevent_mxs to mxs_timer_interrupt via mxs_timer_irq.dev_id
 - Fix code of setting far-far future
 - Change printk to pr_info and pr_err
 - Change timrotv2 min_delta_ns to 0xf

Changes for v3:
 - Use term clock_event over next_event and clocksource over get_cycles
 - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
 - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
 - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
 - Skip flag IRQF_DISABLED
 - Remove unncessary IRQ disabling in mxs_set_mode()
 - Change shift of clocksource_mxs to 17

Changes for v2:
 - Fix a bug in timrot_set_next_event(). It should read
   HW_TIMROT_RUNNING_COUNTn to get the current counts.

 arch/arm/mach-mxs/timer.c |  270 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 270 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/timer.c

diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..75f2805
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,270 @@
+/*
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ *  Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timer0 and timer1, while
+ * MX23 uses timer0 and timer3.
+ */
+#define timrot_is_v1()	(cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL			0x00
+#define HW_TIMROT_TIMCTRLn(n)			(0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n)		(0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n)		(0x40 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD		(1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE		(1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN		(1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ			(1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT		0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL	0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL	0xb
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
+
+static inline void timrot_irq_disable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+			timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+	return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+			& 0xffff0000) >> 16);
+}
+
+static cycle_t timrotv2_get_cycles(struct clocksource *cs)
+{
+	return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	/* timrot decrements the count */
+	__raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+
+	return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	/* timrot decrements the count */
+	__raw_writel(evt, timer_base + HW_TIMROT_FIXED_COUNTn(0));
+
+	return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	timrot_irq_acknowledge();
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+	.name		= "MXS Timer Tick",
+	.dev_id		= &clockevent_mxs,
+	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+	[CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+	[CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+	[CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+	/* Disable interrupt in timer module */
+	timrot_irq_disable();
+
+	if (mode != clockevent_mode) {
+		/* Set event time into the furthest future */
+		if (timrot_is_v1())
+			__raw_writel(0xffff,
+				timer_base  + HW_TIMROT_RUNNING_COUNTn(1));
+		else
+			__raw_writel(0xffffffff,
+				timer_base  + HW_TIMROT_FIXED_COUNTn(1));
+
+		/* Clear pending interrupt */
+		timrot_irq_acknowledge();
+	}
+
+#ifdef DEBUG
+	pr_info("%s: changing mode from %s to %s\n", __func__,
+		clock_event_mode_label[clockevent_mode],
+		clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+	/* Remember timer mode */
+	clockevent_mode = mode;
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		pr_err("%s: Periodic mode is not implemented\n", __func__);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		timrot_irq_enable();
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Left event sources disabled, no more interrupts appear */
+		break;
+	}
+}
+
+static struct clock_event_device clockevent_mxs = {
+	.name		= "mxs_timrot",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 32,
+	.set_mode	= mxs_set_mode,
+	.set_next_event	= timrotv2_set_next_event,
+	.rating		= 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+	clockevent_mxs.cpumask = cpumask_of(0);
+	if (timrot_is_v1()) {
+		clockevent_mxs.set_next_event = timrotv1_set_next_event;
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xf, &clockevent_mxs);
+	} else {
+		clockevent_mxs.max_delta_ns =
+			clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+		clockevent_mxs.min_delta_ns =
+			clockevent_delta2ns(0xf, &clockevent_mxs);
+	}
+
+	clockevents_register_device(&clockevent_mxs);
+
+	return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+	.name 		= "mxs_timer",
+	.rating		= 200,
+	.read		= timrotv2_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.shift 		= 17,
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+	unsigned int c = clk_get_rate(timer_clk);
+
+	if (timrot_is_v1()) {
+		clocksource_mxs.read = timrotv1_get_cycles;
+		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+	}
+	clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+	clocksource_register(&clocksource_mxs);
+
+	return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk, int irq)
+{
+	clk_enable(timer_clk);
+
+	/*
+	 * Initialize timers to a known state
+	 */
+	mxs_reset_block(timer_base + HW_TIMROT_ROTCTRL);
+
+	/* timer0 is for clock_event */
+	__raw_writel((timrot_is_v1() ?
+			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+			BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+			BM_TIMROT_TIMCTRLn_UPDATE |
+			BM_TIMROT_TIMCTRLn_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRLn(0));
+
+	/* timer1 is for clocksource */
+	__raw_writel((timrot_is_v1() ?
+			BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+			BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+			BM_TIMROT_TIMCTRLn_RELOAD,
+			timer_base + HW_TIMROT_TIMCTRLn(1));
+
+	/* set timer1 fixed count to the maximum */
+	if (timrot_is_v1())
+		__raw_writel(0xffff,
+			timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+	else
+		__raw_writel(0xffffffff,
+			timer_base + HW_TIMROT_FIXED_COUNTn(1));
+
+	/* init and register the timer to the framework */
+	mxs_clocksource_init(timer_clk);
+	mxs_clockevent_init(timer_clk);
+
+	/* Make irqs happen */
+	setup_irq(irq, &mxs_timer_irq);
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (38 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 16:47   ` Lothar Waßmann
  2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
                   ` (6 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implement gpio support in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - include/mach/gpio.h: remove the inclusion of hardware.h
 - gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
 - Remove spinlock totally since SET/CLE can be used in all the
   gpio register access

Changes for v2:
 - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
 - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
 - Remove both edges IRQ support which is not needed
 - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
 - Use pr_info over printk(KERN_INFO)

 arch/arm/mach-mxs/gpio.c              |  321 +++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/gpio.h              |   33 ++++
 arch/arm/mach-mxs/include/mach/gpio.h |   34 ++++
 3 files changed, 388 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/gpio.c
 create mode 100644 arch/arm/mach-mxs/gpio.h
 create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h

diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..d88acf3
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,321 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n)		((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n)		((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n)		((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n)	((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n)	((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n)	((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n)	((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n)	((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE	0x0
+#define GPIO_INT_LOW_LEV	0x1
+#define GPIO_INT_RISE_EDGE	0x2
+#define GPIO_INT_HIGH_LEV	0x3
+#define GPIO_INT_LEV_MASK	(1 << 0)
+#define GPIO_INT_POL_MASK	(1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+	__raw_writel(1 << index,
+			port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+				int enable)
+{
+	if (enable == 0) {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+	} else {
+		__raw_writel(1 << index,
+			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+		__raw_writel(1 << index,
+			port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+	}
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+	u32 gpio = irq_to_gpio(irq);
+	_set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+	u32 gpio = irq_to_gpio(irq);
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+	int edge;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_RISING:
+		edge = GPIO_INT_RISE_EDGE;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		edge = GPIO_INT_FALL_EDGE;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		edge = GPIO_INT_LOW_LEV;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		edge = GPIO_INT_HIGH_LEV;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set level or edge */
+	if (edge & GPIO_INT_LEV_MASK)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+	/* set polarity */
+	if (edge & GPIO_INT_POL_MASK)
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << (gpio & 31),
+			port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+	_clear_gpio_irqstatus(port, gpio & 0x1f);
+
+	return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_stat;
+	struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+	u32 gpio_irq_no_base = port->virtual_irq_start;
+
+	irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+			__raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+			__raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
+		irq_stat &= ~(1 << irqoffset);
+	}
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * @return       This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+	u32 gpio = irq_to_gpio(irq);
+	u32 gpio_idx = gpio & 0x1f;
+	struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+	if (enable) {
+		if (port->irq_high && (gpio_idx >= 16))
+			enable_irq_wake(port->irq_high);
+		else
+			enable_irq_wake(port->irq);
+	} else {
+		if (port->irq_high && (gpio_idx >= 16))
+			disable_irq_wake(port->irq_high);
+		else
+			disable_irq_wake(port->irq);
+	}
+
+	return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.ack = gpio_ack_irq,
+	.mask = gpio_mask_irq,
+	.unmask = gpio_unmask_irq,
+	.set_type = gpio_set_irq_type,
+	.set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+				int dir)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+
+	if (dir)
+		__raw_writel(1 << offset,
+			port->base + PINCTRL_DOE(port->id) + MXS_SET_ADDR);
+	else
+		__raw_writel(1 << offset,
+			port->base + PINCTRL_DOE(port->id) + MXS_CLR_ADDR);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+
+	__raw_writel(1 << offset, port->base + PINCTRL_DOUT(port->id) +
+			 (value ? MXS_SET_ADDR : MXS_CLR_ADDR));
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct mxs_gpio_port *port =
+		container_of(chip, struct mxs_gpio_port, chip);
+
+	return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	_set_gpio_direction(chip, offset, 0);
+	return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+				     unsigned offset, int value)
+{
+	mxs_gpio_set(chip, offset, value);
+	_set_gpio_direction(chip, offset, 1);
+	return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+	int i, j;
+
+	/* save for local usage */
+	mxs_gpio_ports = port;
+	gpio_table_size = cnt;
+
+	pr_info("MXS GPIO hardware\n");
+
+	for (i = 0; i < cnt; i++) {
+		/* disable the interrupt and clear the status */
+		__raw_writel(0, port[i].base +
+				PINCTRL_PIN2IRQ(i));
+		__raw_writel(0, port[i].base +
+				PINCTRL_IRQEN(i));
+		__raw_writel(~0, port[i].base +
+				PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+		for (j = port[i].virtual_irq_start;
+			j < port[i].virtual_irq_start + 32; j++) {
+			set_irq_chip(j, &gpio_irq_chip);
+			set_irq_handler(j, handle_level_irq);
+			set_irq_flags(j, IRQF_VALID);
+		}
+
+		/* register gpio chip */
+		port[i].chip.direction_input = mxs_gpio_direction_input;
+		port[i].chip.direction_output = mxs_gpio_direction_output;
+		port[i].chip.get = mxs_gpio_get;
+		port[i].chip.set = mxs_gpio_set;
+		port[i].chip.base = i * 32;
+		port[i].chip.ngpio = 32;
+
+		/* its a serious configuration bug when it fails */
+		BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+		/* setup one handler for each entry */
+		set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+		set_irq_data(port[i].irq, &port[i]);
+	}
+
+	return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id)					\
+	{								\
+		.chip.label = "gpio-" #_id,				\
+		.id = _id,						\
+		.irq = soc ## _INT_GPIO ## _id,				\
+		.base = soc ## _IO_ADDRESS(				\
+				soc ## _PINCTRL ## _BASE_ADDR),		\
+		.virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32,	\
+	}
+
+#define DEFINE_REGISTER_FUNCTION(prefix)				\
+int __init prefix ## _register_gpios(void)				\
+{									\
+	return mxs_gpio_init(prefix ## _gpio_ports,			\
+			ARRAY_SIZE(prefix ## _gpio_ports));		\
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX23, 0),
+	DEFINE_MXS_GPIO_PORT(MX23, 1),
+	DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+	DEFINE_MXS_GPIO_PORT(MX28, 0),
+	DEFINE_MXS_GPIO_PORT(MX28, 1),
+	DEFINE_MXS_GPIO_PORT(MX28, 2),
+	DEFINE_MXS_GPIO_PORT(MX28, 3),
+	DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 0000000..49ed668
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+struct mxs_gpio_port {
+	void __iomem *base;
+	int id;
+	int irq;
+	int irq_high;
+	int virtual_irq_start;
+	struct gpio_chip chip;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..0a80c32
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr)	((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value		__gpio_get_value
+#define gpio_set_value		__gpio_set_value
+#define gpio_cansleep		__gpio_cansleep
+
+#define gpio_to_irq(gpio)	(MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq)	((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 08/15] ARM: mxs: Add iomux support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (39 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 16:12   ` Lothar Waßmann
  2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
                   ` (5 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

MXS-based SoCs implements iomux functions in block PINCTRL.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Change iomux_cfg_t to u64 to facilitate adding platform specific
   pad_ctrl settings to an existing pad definition
 - Change inclusion of hardware.h to mxs.h
 - Get iomux_base a hard-assignment in mxs_iomux_setup_pad(), since
   mx23 and mx28 share the common pinctrl base adress and it's only
   used in mxs_iomux_setup_pad().
 - Remove EXPORT_SYMBOL and the static of mxs_iomux_setup_pad()

Changes for v2:
 - Define iomux_cfg_t as u64
 - Turn mxs_iomux_setup_pad() into a static function
 - Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.

 arch/arm/mach-mxs/include/mach/iomux-mx23.h |   29 +++++++
 arch/arm/mach-mxs/include/mach/iomux-mx28.h |   44 ++++++++++
 arch/arm/mach-mxs/include/mach/iomux.h      |  117 +++++++++++++++++++++++++++
 arch/arm/mach-mxs/iomux.c                   |  103 +++++++++++++++++++++++
 4 files changed, 293 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
 create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
 create mode 100644 arch/arm/mach-mxs/iomux.c

diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX			IOMUX_PAD(1, 26, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX			IOMUX_PAD(1, 27, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..226bf41
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..0939446
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *			<armlinux@phytec.de>
+ * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+/*
+ * IOMUX/PAD Bit field definitions
+ *
+ * PAD_BANK:	 0..2	(3)
+ * PAD_PIN:	 3..7	(5)
+ * PAD_MUXSEL:	 8..9	(2)
+ * PAD_MA:	10..12	(3)
+ * PAD_VOL:	13..14	(2)
+ * PAD_PULL:	15	(1)
+ * RESERVED:	16..63	(48)
+ */
+typedef u64 iomux_cfg_t;
+
+#define PAD_BANK_SHIFT		0
+#define PAD_BANK_MASK		((iomux_cfg_t)0x7 << PAD_BANK_SHIFT)
+#define PAD_PIN_SHIFT		3
+#define PAD_PIN_MASK		((iomux_cfg_t)0x1f << PAD_PIN_SHIFT)
+#define PAD_MUXSEL_SHIFT	8
+#define PAD_MUXSEL_MASK		((iomux_cfg_t)0x3 << PAD_MUXSEL_SHIFT)
+#define PAD_MA_SHIFT		10
+#define PAD_MA_MASK		((iomux_cfg_t)0x7 << PAD_MA_SHIFT)
+#define PAD_VOL_SHIFT		13
+#define PAD_VOL_MASK		((iomux_cfg_t)0x3 << PAD_VOL_SHIFT)
+#define PAD_PULL_SHIFT		15
+#define PAD_PULL_MASK		((iomux_cfg_t)0x1 << PAD_PULL_SHIFT)
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)		\
+		(((iomux_cfg_t)(_bank) << PAD_BANK_SHIFT) |		\
+		((iomux_cfg_t)(_pin) << PAD_PIN_SHIFT) |		\
+		((iomux_cfg_t)(_muxsel) << PAD_MUXSEL_SHIFT) |		\
+		((iomux_cfg_t)(_vol) << PAD_VOL_SHIFT) |		\
+		((iomux_cfg_t)(_ma) << PAD_MA_SHIFT) |			\
+		((iomux_cfg_t)(_pull) << PAD_PULL_SHIFT))
+
+#define PAD_MUXSEL_0		0
+#define PAD_MUXSEL_1		1
+#define PAD_MUXSEL_2		2
+#define PAD_MUXSEL_GPIO		3
+
+#define PAD_1V8			0
+#define PAD_3V3			1
+#define PAD_VOL_NONE		2
+
+#define PAD_4MA			0
+#define PAD_8MA			1
+#define PAD_12MA		2
+#define PAD_16MA		3
+#define PAD_MA_NONE		4
+
+#define PAD_NOPULL		0
+#define PAD_PULLUP		1
+
+static inline unsigned int PAD_BANK(iomux_cfg_t pad)
+{
+	return (pad & PAD_BANK_MASK) >> PAD_BANK_SHIFT;
+}
+
+static inline unsigned int PAD_PIN(iomux_cfg_t pad)
+{
+	return (pad & PAD_PIN_MASK) >> PAD_PIN_SHIFT;
+}
+
+static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
+{
+	return (pad & PAD_MUXSEL_MASK) >> PAD_MUXSEL_SHIFT;
+}
+
+static inline unsigned int PAD_MA(iomux_cfg_t pad)
+{
+	return (pad & PAD_MA_MASK) >> PAD_MA_SHIFT;
+}
+
+static inline unsigned int PAD_VOL(iomux_cfg_t pad)
+{
+	return (pad & PAD_VOL_MASK) >> PAD_VOL_SHIFT;
+}
+
+static inline unsigned int PAD_PULL(iomux_cfg_t pad)
+{
+	return (pad & PAD_PULL_MASK) >> PAD_PULL_SHIFT;
+}
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad);
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..b6e63a4
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *                       <armlinux@phytec.de>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mxs.h>
+#include <mach/iomux.h>
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+	u32 reg, ofs, bp, bm;
+	void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
+
+	/* muxsel */
+	ofs = 0x100;
+	ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+	bp = PAD_PIN(pad) % 16 * 2;
+	bm = 0x3 << bp;
+	reg = __raw_readl(iomux_base + ofs);
+	reg &= ~bm;
+	reg |= PAD_MUXSEL(pad) << bp;
+	__raw_writel(reg, iomux_base + ofs);
+
+	/* drive */
+	ofs = cpu_is_mx23() ? 0x200 : 0x300;
+	ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+	/* ma */
+	if (PAD_MA(pad) != PAD_MA_NONE)
+	{
+		bp = PAD_PIN(pad) % 8 * 4;
+		bm = 0x3 << bp;
+		reg = __raw_readl(iomux_base + ofs);
+		reg &= ~bm;
+		reg |= PAD_MA(pad) << bp;
+		__raw_writel(reg, iomux_base + ofs);
+	}
+	/* vol */
+	if (PAD_VOL(pad) != PAD_VOL_NONE)
+	{
+		bp = PAD_PIN(pad) % 8 * 4 + 2;
+		bm = 0x1 << bp;
+		reg = __raw_readl(iomux_base + ofs);
+		reg &= ~bm;
+		reg |= PAD_VOL(pad) << bp;
+		__raw_writel(reg, iomux_base + ofs);
+	}
+
+	/* pull */
+	ofs = cpu_is_mx23() ? 0x400 : 0x600;
+	ofs += PAD_BANK(pad) * 0x10;
+	bp = PAD_PIN(pad);
+	bm = 0x1 << bp;
+	reg = __raw_readl(iomux_base + ofs);
+	reg &= ~bm;
+	reg |= PAD_PULL(pad) << bp;
+	__raw_writel(reg, iomux_base + ofs);
+
+	return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+	const iomux_cfg_t *p = pad_list;
+	int i;
+	int ret;
+
+	for (i = 0; i < count; i++) {
+		ret = mxs_iomux_setup_pad(*p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 09/15] ARM: mxs: Add clock support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (40 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 21:11   ` Uwe Kleine-König
  2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
                   ` (4 subsequent siblings)
  46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add clock for MXS-based SoCs, MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Fix freq overflow in clock-mx23.c as well
 - Fix the overflow using SH_DIV and shifting 8 bits
 - Remove the inclusion of hardware.h and include mx23.h/mx28.h

Changes for v2:
 - Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
 - Fix fec_clk to stand for fec clock than IEEE1588 time clock
 - Add pll2_clk into clock lookups, as it's fec phy clock and needs to be on before reset phy

 arch/arm/mach-mxs/clock-mx23.c          |  526 ++++++++++++++++++++++
 arch/arm/mach-mxs/clock-mx28.c          |  734 +++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/clock.c               |  200 +++++++++
 arch/arm/mach-mxs/include/mach/clkdev.h |    7 +
 arch/arm/mach-mxs/include/mach/clock.h  |   64 +++
 arch/arm/mach-mxs/regs-clkctrl-mx23.h   |  455 +++++++++++++++++++
 arch/arm/mach-mxs/regs-clkctrl-mx28.h   |  663 ++++++++++++++++++++++++++++
 7 files changed, 2649 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/clock-mx23.c
 create mode 100644 arch/arm/mach-mxs/clock-mx28.c
 create mode 100644 arch/arm/mach-mxs/clock.c
 create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
 create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
 create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h

diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..b2923da
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT	8
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+	/* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+	 * and is incorrect (excessive). Per definition of the PLLCTRL0
+	 * POWER field, waiting at least 10us.
+	 */
+	udelay(10);
+
+	return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+	__raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+			BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+	 .get_rate = pll_clk_get_rate,
+	 .enable = pll_clk_enable,
+	 .disable = pll_clk_disable,
+	 .parent = &ref_xtal_clk,
+};
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18,		\
+			div, PARENT_RATE_SHIFT);			\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, bm_busy, div_max, d, f, div, frac;
+	unsigned long diff, parent_rate, calc_rate;
+	int i;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &ref_xtal_clk) {
+		div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+		div = DIV_ROUND_UP(parent_rate, rate);
+		if (div == 0 || div > div_max)
+			return -EINVAL;
+	} else {
+		div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+		bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+		rate <<= PARENT_RATE_SHIFT;
+		parent_rate <<= PARENT_RATE_SHIFT;
+		diff = parent_rate;
+		div = frac = 1;
+		for (d = 1; d <= div_max; d++) {
+			f = parent_rate * 18 / d / rate;
+			if ((parent_rate * 18 / d) % rate)
+				f++;
+			if (f < 18 || f > 35)
+				continue;
+
+			calc_rate = parent_rate * 18 / f / d;
+			if (calc_rate > rate)
+				continue;
+
+			if (rate - calc_rate < diff) {
+				frac = f;
+				div = d;
+				diff = rate - calc_rate;
+			}
+
+			if (diff == 0)
+				break;
+		}
+
+		if (diff == parent_rate)
+			return -EINVAL;
+
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+		reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+		reg |= frac;
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+	}
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+	reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+	reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+					HW_CLKCTRL_CPU) & bm_busy))
+			break;
+	if (!i)	{
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+#define _CLK_SET_RATE(name, dr)						\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "usb", usb_clk)
+	_REGISTER_CLOCK(NULL, "audio", audio_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+			&ref_xtal_clk : &ref_io_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_io_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+			&ref_xtal_clk : &ref_pix_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+	reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+	reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..4a5c518
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2009-2010 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx28.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT	8
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+	return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g)					\
+static int name##_enable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	udelay(10);							\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+									\
+	return 0;							\
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g)					\
+static void name##_disable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name)						\
+	static struct clk name = {					\
+		.get_rate	= name##_get_rate,			\
+		.enable		= name##_enable,			\
+		.disable	= name##_disable,			\
+		.parent		= &ref_xtal_clk,			\
+	}
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18,		\
+			div, PARENT_RATE_SHIFT);			\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll0_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	if (clk == &saif0_clk || clk == &saif1_clk)			\
+		return (clk_get_rate(clk->parent) >> 16 * div);		\
+	else								\
+		return clk_get_rate(clk->parent) / div;			\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+_CLK_GET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV	0
+#define BP_CLKCTRL_CPU_DIV	0
+#define BM_CLKCTRL_CPU_BUSY	0
+
+#define _CLK_SET_RATE(name, dr, fr, fs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, bm_busy, div_max, d, f, div, frac;			\
+	unsigned long diff, parent_rate, calc_rate;			\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+	bm_busy = BM_CLKCTRL_##dr##_BUSY;				\
+									\
+	if (clk->parent == &ref_xtal_clk) {				\
+		div = DIV_ROUND_UP(parent_rate, rate);			\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_XTAL >>		\
+				BP_CLKCTRL_CPU_DIV_XTAL;		\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;		\
+		}							\
+		if (div == 0 || div > div_max)				\
+			return -EINVAL;					\
+	} else {							\
+		rate <<= PARENT_RATE_SHIFT;				\
+		parent_rate <<= PARENT_RATE_SHIFT;			\
+		diff = parent_rate;					\
+		div = frac = 1;						\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_CPU >>		\
+				BP_CLKCTRL_CPU_DIV_CPU;			\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;		\
+		}							\
+		for (d = 1; d <= div_max; d++) {			\
+			f = parent_rate * 18 / d / rate;		\
+			if ((parent_rate * 18 / d) % rate)		\
+				f++;					\
+			if (f < 18 || f > 35)				\
+				continue;				\
+									\
+			calc_rate = parent_rate * 18 / f / d;		\
+			if (calc_rate > rate)				\
+				continue;				\
+									\
+			if (rate - calc_rate < diff) {			\
+				frac = f;				\
+				div = d;				\
+				diff = rate - calc_rate;		\
+			}						\
+									\
+			if (diff == 0)					\
+				break;					\
+		}							\
+									\
+		if (diff == parent_rate)				\
+			return -EINVAL;					\
+									\
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+		reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC;			\
+		reg |= frac;						\
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+	}								\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	if (clk == &cpu_clk) {						\
+		reg &= ~BM_CLKCTRL_CPU_DIV_CPU;				\
+		reg |= div << BP_CLKCTRL_CPU_DIV_CPU;			\
+	} else {							\
+		reg &= ~BM_CLKCTRL_##dr##_DIV;				\
+		reg |= div << BP_CLKCTRL_##dr##_DIV;			\
+		if (reg | (1 << clk->enable_shift)) {			\
+			pr_err("%s: clock is gated\n", __func__);	\
+			return -EINVAL;					\
+		}							\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & bm_busy))			\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u16 div;							\
+	u32 reg;							\
+	u64 lrate;							\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	if (rate > parent_rate)						\
+		return -EINVAL;						\
+									\
+	lrate = (u64)rate << 16;					\
+	do_div(lrate, parent_rate);					\
+	div = (u16)lrate;						\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	reg &= ~BM_CLKCTRL_##rs##_DIV;					\
+	reg |= div << BP_CLKCTRL_##rs##_DIV;				\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))	\
+			break;						\
+	if (!i) {							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+_CLK_SET_RATE_STUB(fec_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+	.get_rate = lradc_clk_get_rate,
+	.parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 16,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK("pll2", NULL, pll2_clk)
+	_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+	_REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+	_REGISTER_CLOCK(NULL, "can0", can0_clk)
+	_REGISTER_CLOCK(NULL, "can1", can1_clk)
+	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+	_REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+			&ref_xtal_clk : &ref_pix_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_gpmi_clk;
+	saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+			&ref_xtal_clk : &pll0_clk;
+	saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+			&ref_xtal_clk : &pll0_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+	reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+	reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+	reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+	reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+	reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+	/* SAIF has to use frac div for functional operation */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+	reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+	reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	/* Extra fec clock setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg &= ~BM_CLKCTRL_ENET_SLEEP;
+	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e7d2269
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,200 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+	WARN_ON(!clk->usecount);
+
+	if (!(--clk->usecount)) {
+		if (clk->disable)
+			clk->disable(clk);
+		__clk_disable(clk->parent);
+		__clk_disable(clk->secondary);
+	}
+}
+
+static int __clk_enable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	if (clk->usecount++ == 0) {
+		__clk_enable(clk->parent);
+		__clk_enable(clk->secondary);
+
+		if (clk->enable)
+			clk->enable(clk);
+	}
+	return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+	int ret = 0;
+
+	if (clk == NULL || IS_ERR(clk))
+		return -EINVAL;
+
+	mutex_lock(&clocks_mutex);
+	ret = __clk_enable(clk);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return;
+
+	mutex_lock(&clocks_mutex);
+	__clk_disable(clk);
+	mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (clk == NULL || IS_ERR(clk))
+		return 0UL;
+
+	if (clk->get_rate)
+		return clk->get_rate(clk);
+
+	return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+		return 0;
+
+	return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int ret = -EINVAL;
+
+	if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+		return ret;
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_rate(clk, rate);
+	mutex_unlock(&clocks_mutex);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	int ret = -EINVAL;
+	struct clk *old;
+
+	if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+	    IS_ERR(parent) || clk->set_parent == NULL)
+		return ret;
+
+	if (clk->usecount)
+		clk_enable(parent);
+
+	mutex_lock(&clocks_mutex);
+	ret = clk->set_parent(clk, parent);
+	if (ret == 0) {
+		old = clk->parent;
+		clk->parent = parent;
+	} else {
+		old = parent;
+	}
+	mutex_unlock(&clocks_mutex);
+
+	if (clk->usecount)
+		clk_disable(old);
+
+	return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+	struct clk *ret = NULL;
+
+	if (clk == NULL || IS_ERR(clk))
+		return ret;
+
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA  02110-1301, USA.
+ */
+
+#ifndef __MACH_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+	int id;
+	/* Source clock this clk depends on */
+	struct clk *parent;
+	/* Secondary clock to enable/disable with this clock */
+	struct clk *secondary;
+	/* Reference count of clock enable/disable */
+	__s8 usecount;
+	/* Register bit position for clock's enable/disable control. */
+	u8 enable_shift;
+	/* Register address for clock's enable/disable control. */
+	void __iomem *enable_reg;
+	u32 flags;
+	/* get the current clock rate (always a fresh value) */
+	unsigned long (*get_rate) (struct clk *);
+	/* Function ptr to set the clock to a new rate. The rate must match a
+	   supported rate returned from round_rate. Leave blank if clock is not
+	   programmable */
+	int (*set_rate) (struct clk *, unsigned long);
+	/* Function ptr to round the requested clock rate to the nearest
+	   supported rate that is less than or equal to the requested rate. */
+	unsigned long (*round_rate) (struct clk *, unsigned long);
+	/* Function ptr to enable the clock. Leave blank if clock can not
+	   be gated. */
+	int (*enable) (struct clk *);
+	/* Function ptr to disable the clock. Leave blank if clock can not
+	   be gated. */
+	void (*disable) (struct clk *);
+	/* Function ptr to set the parent clock of the clock. */
+	int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0	(0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2	0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER	0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU	(0x00000020)
+#define HW_CLKCTRL_CPU_SET	(0x00000024)
+#define HW_CLKCTRL_CPU_CLR	(0x00000028)
+#define HW_CLKCTRL_CPU_TOG	(0x0000002c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000030)
+#define HW_CLKCTRL_HBUS_SET	(0x00000034)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000038)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4	30
+#define BM_CLKCTRL_HBUS_RSRVD4	0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+		(((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY	0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x10000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_AUTO_SLOW_MODE	0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	11
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000050)
+#define HW_CLKCTRL_XTAL_SET	(0x00000054)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000058)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE	30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE	0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE	0x08000000
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_PIX	(0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE	31
+#define BM_CLKCTRL_PIX_CLKGATE	0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2	0x40000000
+#define BM_CLKCTRL_PIX_BUSY	0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1	13
+#define BM_CLKCTRL_PIX_RSRVD1	0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v)  \
+		(((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN	0x00001000
+#define BP_CLKCTRL_PIX_DIV	0
+#define BM_CLKCTRL_PIX_DIV	0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP	(0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE	31
+#define BM_CLKCTRL_SSP_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP_BUSY	0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1	10
+#define BM_CLKCTRL_SSP_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP_DIV	0
+#define BM_CLKCTRL_SSP_DIV	0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x00000080)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x00000090)
+
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000a0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_IR	(0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE	0x80000000
+#define BM_CLKCTRL_IR_RSRVD3	0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV	0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY	0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY	0x08000000
+#define BP_CLKCTRL_IR_RSRVD2	25
+#define BM_CLKCTRL_IR_RSRVD2	0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v)  \
+		(((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV	16
+#define BM_CLKCTRL_IR_IROV_DIV	0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1	10
+#define BM_CLKCTRL_IR_RSRVD1	0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV	0
+#define BM_CLKCTRL_IR_IR_DIV	0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF	(0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1	17
+#define BM_CLKCTRL_SAIF_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF_DIV	0
+#define BM_CLKCTRL_SAIF_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV	(0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE	0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE	0x40000000
+#define BP_CLKCTRL_TV_RSRVD	0
+#define BM_CLKCTRL_TV_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM	(0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	7
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000040
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC	(0x000000f0)
+#define HW_CLKCTRL_FRAC_SET	(0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR	(0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG	(0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO	31
+#define BM_CLKCTRL_FRAC_CLKGATEIO	0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC	24
+#define BM_CLKCTRL_FRAC_IOFRAC	0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX	23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX	0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC	16
+#define BM_CLKCTRL_FRAC_PIXFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC	8
+#define BM_CLKCTRL_FRAC_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC	0
+#define BM_CLKCTRL_FRAC_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x00000100)
+#define HW_CLKCTRL_FRAC1_SET	(0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR	(0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG	(0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID	0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1	0
+#define BM_CLKCTRL_FRAC1_RSRVD1	0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ	(0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR	0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD	2
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x00000130)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000140)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2009-2010 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
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_H__
+
+#define HW_CLKCTRL_PLL0CTRL0	(0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0	(0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET	(0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR	(0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG	(0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI	0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6	0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1	(0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0	(0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET	(0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR	(0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG	(0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE	0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3	0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2	0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B	0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER	0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1	0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU	(0x00000050)
+#define HW_CLKCTRL_CPU_SET	(0x00000054)
+#define HW_CLKCTRL_CPU_CLR	(0x00000058)
+#define HW_CLKCTRL_CPU_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000060)
+#define HW_CLKCTRL_HBUS_SET	(0x00000064)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000068)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY	0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE	0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	12
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE	0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000080)
+#define HW_CLKCTRL_XTAL_SET	(0x00000084)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000088)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2	27
+#define BM_CLKCTRL_XTAL_RSRVD2	0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v)  \
+		(((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0	(0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE	31
+#define BM_CLKCTRL_SSP0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP0_BUSY	0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1	10
+#define BM_CLKCTRL_SSP0_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP0_DIV	0
+#define BM_CLKCTRL_SSP0_DIV	0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1	(0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE	31
+#define BM_CLKCTRL_SSP1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP1_BUSY	0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1	10
+#define BM_CLKCTRL_SSP1_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP1_DIV	0
+#define BM_CLKCTRL_SSP1_DIV	0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2	(0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE	31
+#define BM_CLKCTRL_SSP2_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP2_BUSY	0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1	10
+#define BM_CLKCTRL_SSP2_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP2_DIV	0
+#define BM_CLKCTRL_SSP2_DIV	0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3	(0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE	31
+#define BM_CLKCTRL_SSP3_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP3_BUSY	0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1	10
+#define BM_CLKCTRL_SSP3_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP3_DIV	0
+#define BM_CLKCTRL_SSP3_DIV	0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE	31
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0	(0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE	31
+#define BM_CLKCTRL_SAIF0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1	17
+#define BM_CLKCTRL_SAIF0_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF0_DIV	0
+#define BM_CLKCTRL_SAIF0_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1	(0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE	31
+#define BM_CLKCTRL_SAIF1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1	17
+#define BM_CLKCTRL_SAIF1_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF1_DIV	0
+#define BM_CLKCTRL_SAIF1_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF	(0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE	31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY	0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1	14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1	0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v)  \
+		(((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN	0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV	0
+#define BM_CLKCTRL_DIS_LCDIF_DIV	0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM	(0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	8
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000080
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET	(0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP	0x80000000
+#define BP_CLKCTRL_ENET_DISABLE	30
+#define BM_CLKCTRL_ENET_DISABLE	0x40000000
+#define BM_CLKCTRL_ENET_STATUS	0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1	0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME	0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME	21
+#define BM_CLKCTRL_ENET_DIV_TIME	0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY	0x08000000
+#define BP_CLKCTRL_ENET_DIV	21
+#define BM_CLKCTRL_ENET_DIV	0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL	19
+#define BM_CLKCTRL_ENET_TIME_SEL	0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v)  \
+		(((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL      0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL       0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK  0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN	0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP	0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW	0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0	0
+#define BM_CLKCTRL_ENET_RSRVD0	0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v)  \
+		(((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC	(0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2	0x80000000
+#define BM_CLKCTRL_HSADC_RESETB	0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV	28
+#define BM_CLKCTRL_HSADC_FREQDIV	0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v)  \
+		(((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1	0
+#define BM_CLKCTRL_HSADC_RSRVD1	0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN	(0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2	0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0	30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0	0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS	0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1	28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1	0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS	0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1	0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1	0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0	(0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET	(0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR	(0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG	(0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0	31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0	0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC	24
+#define BM_CLKCTRL_FRAC0_IO0FRAC	0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1	23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1	0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC	16
+#define BM_CLKCTRL_FRAC0_IO1FRAC	0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC	8
+#define BM_CLKCTRL_FRAC0_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC	0
+#define BM_CLKCTRL_FRAC0_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET	(0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR	(0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG	(0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2	24
+#define BM_CLKCTRL_FRAC1_RSRVD2	0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+		(((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI	23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI	0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC	16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC	15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC	0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC	8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX	7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX	0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC	0
+#define BM_CLKCTRL_FRAC1_PIXFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ	(0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0	19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+		(((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v)  \
+		(((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF	0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD    0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2	0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v)  \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0	0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD	6
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE	0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE	0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE	0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT	0x00000004
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+
+#endif /* __REGS_CLKCTRL_MX28_H__ */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 10/15] ARM: mxs: Add static memory mapping
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (41 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
                   ` (3 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Create static memory mapping for MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Change the inclusion of hardware.h to mx23.h and mx28.h respectively
 - Remove the call to mxs_iomux_init() and mxs_arch_reset_init() from
   map_io callback, and turn them into __initcall, as the call here is
   a little late.

 arch/arm/mach-mxs/mm-mx23.c |   45 +++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/mm-mx28.c |   45 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mm-mx23.c
 create mode 100644 arch/arm/mach-mxs/mm-mx28.c

diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..5148cd6
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+	mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX23, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx23_map_io(void)
+{
+	iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+	icoll_init_irq();
+	mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..7e4cea3
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/mx28.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+	mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+	mxs_map_entry(MX28, IO, MT_DEVICE),
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx28_map_io(void)
+{
+	iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+	icoll_init_irq();
+	mx28_register_gpios();
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (42 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
                   ` (2 subsequent siblings)
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Dynamically allocate duart devices for MX23 and MX28.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
 - Change inclusion of hardware.h to mx23.h plus mx28.h

 arch/arm/mach-mxs/devices-mx23.h                |   16 +++++
 arch/arm/mach-mxs/devices-mx28.h                |   16 +++++
 arch/arm/mach-mxs/devices.c                     |   75 +++++++++++++++++++++++
 arch/arm/mach-mxs/devices/platform-duart.c      |   48 ++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   34 ++++++++++
 5 files changed, 189 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices-mx23.h
 create mode 100644 arch/arm/mach-mxs/devices-mx28.h
 create mode 100644 arch/arm/mach-mxs/devices.c
 create mode 100644 arch/arm/mach-mxs/devices/platform-duart.c
 create mode 100644 arch/arm/mach-mxs/include/mach/devices-common.h

diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 0000000..d0f49fc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx23_duart_data __initconst;
+#define mx23_add_duart() \
+	mxs_add_duart(&mx23_duart_data)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 0000000..47c2f04
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx28_duart_data __initconst;
+#define mx28_add_duart() \
+	mxs_add_duart(&mx28_duart_data)
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 0000000..6b60f02
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel at pengutronix.de
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data, u64 dmamask)
+{
+	int ret = -ENOMEM;
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc(name, id);
+	if (!pdev)
+		goto err;
+
+	if (dmamask) {
+		/*
+		 * This memory isn't freed when the device is put,
+		 * I don't have a nice idea for that though.  Conceptually
+		 * dma_mask in struct device should not be a pointer.
+		 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+		 */
+		pdev->dev.dma_mask =
+			kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+		if (!pdev->dev.dma_mask)
+			/* ret is still -ENOMEM; */
+			goto err;
+
+		*pdev->dev.dma_mask = dmamask;
+		pdev->dev.coherent_dma_mask = dmamask;
+	}
+
+	if (res) {
+		ret = platform_device_add_resources(pdev, res, num_resources);
+		if (ret)
+			goto err;
+	}
+
+	if (data) {
+		ret = platform_device_add_data(pdev, data, size_data);
+		if (ret)
+			goto err;
+	}
+
+	ret = platform_device_add(pdev);
+	if (ret) {
+err:
+		platform_device_put(pdev);
+		return ERR_PTR(ret);
+	}
+
+	return pdev;
+}
diff --git a/arch/arm/mach-mxs/devices/platform-duart.c b/arch/arm/mach-mxs/devices/platform-duart.c
new file mode 100644
index 0000000..2fe0df5
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-duart.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 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 version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_duart_data_entry(soc)					\
+	{								\
+		.iobase = soc ## _DUART_BASE_ADDR,			\
+		.irq = soc ## _INT_DUART,				\
+	}
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_duart_data mx23_duart_data __initconst =
+	mxs_duart_data_entry(MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_duart_data mx28_duart_data __initconst =
+	mxs_duart_data_entry(MX28);
+#endif
+
+struct platform_device *__init mxs_add_duart(
+		const struct mxs_duart_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_8K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("mxs-duart", 0, res, ARRAY_SIZE(res),
+					NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 0000000..07b4439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+		const char *name, int id,
+		const struct resource *res, unsigned int num_resources,
+		const void *data, size_t size_data)
+{
+	return mxs_add_platform_device_dmamask(
+			name, id, res, num_resources, data, size_data, 0);
+}
+
+/* duart */
+struct mxs_duart_data {
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_duart(
+		const struct mxs_duart_data *data);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (43 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Dynamically allocate fec devices for MX28, which gets dual
fec interface.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Change inclusion of hardware.h to mx28.h

Changes for v2:
 - Remove the use of mx28_add_fec0 and mx28_add_fec1
 - Remove unnessary passing of data->iosize

 arch/arm/mach-mxs/devices-mx28.h                |    4 ++
 arch/arm/mach-mxs/devices/platform-fec.c        |   50 +++++++++++++++++++++++
 arch/arm/mach-mxs/include/mach/devices-common.h |   12 +++++
 3 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c

diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..00b736c 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,7 @@
 extern const struct mxs_duart_data mx28_duart_data __initconst;
 #define mx28_add_duart() \
 	mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+	mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..c08168c
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id)				\
+	{								\
+		.id = _id,						\
+		.iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR,	\
+		.irq = soc ## _INT_ENET_MAC ## _id,			\
+	}
+
+#define mxs_fec_data_entry(soc, _id)					\
+	[_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id)					\
+	mxs_fec_data_entry(MX28, _id)
+	mx28_fec_data_entry(0),
+	mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_16K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return mxs_add_platform_device("fec", data->id,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
 };
 struct platform_device *__init mxs_add_duart(
 		const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+		const struct mxs_fec_data *data,
+		const struct fec_platform_data *pdata);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (44 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx23evk support with duart.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Remove inclusion of hardware.h
 - Add __initconst for mx23evk_pads[]

Changes for v2:
 - Remove boot_params

 arch/arm/mach-mxs/mach-mx23evk.c |   57 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c

diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..c34b840
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+static const iomux_cfg_t mx23evk_pads[] __initconst = {
+	/* duart */
+	MX23_PAD_PWM0__DUART_RX,
+	MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+	mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+	mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+	.init	= mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.map_io         = mx23_map_io,
+	.init_irq       = mx23_init_irq,
+	.init_machine   = mx23evk_init,
+	.timer          = &mx23evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support
  2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
                   ` (45 preceding siblings ...)
  2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
  46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

Add initial mx28evk support with duart and fec0.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
 - Remove inclusion of hardware.h
 - Add __initconst for mx28evk_pads[]

Changes for v2:
 - Change function mx28evk_fec_reset() from inline to __init
 - Enable pll2 clock before phy operation
 - Add error checking for gpio_direction_output()
 - Save bytes by passing parameter into pr_err format string
 - Change mx28_add_fec0() to mx28_add_fec(0)
 - Remove boot_params

 arch/arm/mach-mxs/mach-mx28evk.c |  125 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 125 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c

diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..226d374
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER	MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+
+static const iomux_cfg_t mx28evk_pads[] __initconst = {
+	/* duart */
+	MX28_PAD_PWM0__DUART_RX,
+	MX28_PAD_PWM1__DUART_TX,
+
+	/* fec0 */
+	MX28_PAD_ENET0_MDC__ENET0_MDC,
+	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
+	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
+	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
+	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
+	MX28_PAD_ENET_CLK__ENET_CLK,
+	/* phy power line */
+	MX28_PAD_SSP1_DATA3__GPIO_2_15,
+	/* phy reset line */
+	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
+};
+
+/* fec */
+static void __init mx28evk_fec_reset(void)
+{
+	int ret;
+	struct clk *clk;
+
+	/* Enable fec phy clock */
+	clk = clk_get_sys("pll2", NULL);
+	if (!IS_ERR(clk))
+		clk_enable(clk);
+
+	/* Power up fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+	if (ret) {
+		pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+		return;
+	}
+
+	ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+		return;
+	}
+
+	/* Reset fec phy */
+	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+	if (ret) {
+		pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+		return;
+	}
+
+	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+	if (ret) {
+		pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+		return;
+	}
+
+	mdelay(1);
+	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+        .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+	mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+	mx28_add_duart();
+
+	mx28evk_fec_reset();
+	mx28_add_fec(0, &mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+	mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+	.init	= mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.map_io         = mx28_map_io,
+	.init_irq       = mx28_init_irq,
+	.init_machine   = mx28evk_init,
+	.timer          = &mx28evk_timer,
+MACHINE_END
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v3 08/15] ARM: mxs: Add iomux support
  2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-09 16:12   ` Lothar Waßmann
  0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 16:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> MXS-based SoCs implements iomux functions in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - Change iomux_cfg_t to u64 to facilitate adding platform specific
>    pad_ctrl settings to an existing pad definition
>  - Change inclusion of hardware.h to mxs.h
>  - Get iomux_base a hard-assignment in mxs_iomux_setup_pad(), since
>    mx23 and mx28 share the common pinctrl base adress and it's only
>    used in mxs_iomux_setup_pad().
>  - Remove EXPORT_SYMBOL and the static of mxs_iomux_setup_pad()
> 
> Changes for v2:
>  - Define iomux_cfg_t as u64
>  - Turn mxs_iomux_setup_pad() into a static function
>  - Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.
> 
>  arch/arm/mach-mxs/include/mach/iomux-mx23.h |   29 +++++++
>  arch/arm/mach-mxs/include/mach/iomux-mx28.h |   44 ++++++++++
>  arch/arm/mach-mxs/include/mach/iomux.h      |  117 +++++++++++++++++++++++++++
>  arch/arm/mach-mxs/iomux.c                   |  103 +++++++++++++++++++++++
>  4 files changed, 293 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
>  create mode 100644 arch/arm/mach-mxs/iomux.c
> 
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> new file mode 100644
> index 0000000..3fc0439
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#ifndef __MACH_IOMUX_MX23_H__
> +#define __MACH_IOMUX_MX23_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + *					 		BANK PIN     MUX            VOL          MA            PULL
                                        ^
TAB/SPACE mixup (emacs can highlight those ;)

> + */
> +/* DUART */
> +#define MX23_PAD_PWM0__DUART_RX			IOMUX_PAD(1, 26, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
> +#define MX23_PAD_PWM1__DUART_TX			IOMUX_PAD(1, 27, PAD_MUXSEL_2,    PAD_VOL_NONE, PAD_4MA,      PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..226bf41
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#ifndef __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + *					 		BANK PIN     MUX            VOL          MA            PULL
                                        ^
TAB/SPACE mixup

> + */
> +/* DUART */
> +#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +/* FEC */
> +#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULLUP)
> +
> +/* GPIO */
> +#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
> new file mode 100644
> index 0000000..0939446
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux.h
> @@ -0,0 +1,117 @@
> +/*
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *			<armlinux@phytec.de>
> + * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_IOMUX_H__
> +#define __MACH_MXS_IOMUX_H__
> +
> +/*
> + * IOMUX/PAD Bit field definitions
> + *
> + * PAD_BANK:	 0..2	(3)
> + * PAD_PIN:	 3..7	(5)
> + * PAD_MUXSEL:	 8..9	(2)
> + * PAD_MA:	10..12	(3)
> + * PAD_VOL:	13..14	(2)
> + * PAD_PULL:	15	(1)
> + * RESERVED:	16..63	(48)
> + */
> +typedef u64 iomux_cfg_t;
> +
Only because i.MX5 has so many bits to remember does not mean we have
to waste space on this arch too. No need for u64 here (could obviously
even be u16).

> +#define PAD_BANK_SHIFT		0
> +#define PAD_BANK_MASK		((iomux_cfg_t)0x7 << PAD_BANK_SHIFT)
> +#define PAD_PIN_SHIFT		3
> +#define PAD_PIN_MASK		((iomux_cfg_t)0x1f << PAD_PIN_SHIFT)
> +#define PAD_MUXSEL_SHIFT	8
> +#define PAD_MUXSEL_MASK		((iomux_cfg_t)0x3 << PAD_MUXSEL_SHIFT)
> +#define PAD_MA_SHIFT		10
> +#define PAD_MA_MASK		((iomux_cfg_t)0x7 << PAD_MA_SHIFT)
> +#define PAD_VOL_SHIFT		13
> +#define PAD_VOL_MASK		((iomux_cfg_t)0x3 << PAD_VOL_SHIFT)
> +#define PAD_PULL_SHIFT		15
> +#define PAD_PULL_MASK		((iomux_cfg_t)0x1 << PAD_PULL_SHIFT)
> +
> +#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)		\
> +		(((iomux_cfg_t)(_bank) << PAD_BANK_SHIFT) |		\
> +		((iomux_cfg_t)(_pin) << PAD_PIN_SHIFT) |		\
> +		((iomux_cfg_t)(_muxsel) << PAD_MUXSEL_SHIFT) |		\
> +		((iomux_cfg_t)(_vol) << PAD_VOL_SHIFT) |		\
> +		((iomux_cfg_t)(_ma) << PAD_MA_SHIFT) |			\
> +		((iomux_cfg_t)(_pull) << PAD_PULL_SHIFT))
> +
These also should have a namespace prefix like:
MXS_PAD_*, MXS_IOMUX_PAD()

> +#define PAD_MUXSEL_0		0
> +#define PAD_MUXSEL_1		1
> +#define PAD_MUXSEL_2		2
> +#define PAD_MUXSEL_GPIO		3
> +
> +#define PAD_1V8			0
> +#define PAD_3V3			1
> +#define PAD_VOL_NONE		2
> +
> +#define PAD_4MA			0
> +#define PAD_8MA			1
> +#define PAD_12MA		2
> +#define PAD_16MA		3
> +#define PAD_MA_NONE		4
> +
> +#define PAD_NOPULL		0
> +#define PAD_PULLUP		1
> +
> +static inline unsigned int PAD_BANK(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_BANK_MASK) >> PAD_BANK_SHIFT;
> +}
> +
> +static inline unsigned int PAD_PIN(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_PIN_MASK) >> PAD_PIN_SHIFT;
> +}
> +
> +static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_MUXSEL_MASK) >> PAD_MUXSEL_SHIFT;
> +}
> +
> +static inline unsigned int PAD_MA(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_MA_MASK) >> PAD_MA_SHIFT;
> +}
> +
> +static inline unsigned int PAD_VOL(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_VOL_MASK) >> PAD_VOL_SHIFT;
> +}
> +
> +static inline unsigned int PAD_PULL(iomux_cfg_t pad)
> +{
> +	return (pad & PAD_PULL_MASK) >> PAD_PULL_SHIFT;
> +}
> +
> +/*
> + * setups a single pad in the iomuxer
s/setups/configures/

> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t pad);
> +
> +/*
> + * setups multiple pads
dto.

> + * convenient way to call the above function with tables
> + */
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
> +
> +#endif /* __MACH_MXS_IOMUX_H__*/
> diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
> new file mode 100644
> index 0000000..b6e63a4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/iomux.c
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright 2004-2006,2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *                       <armlinux@phytec.de>
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/string.h>
> +#include <linux/gpio.h>
> +
> +#include <asm/mach/map.h>
> +
> +#include <mach/mxs.h>
> +#include <mach/iomux.h>
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t pad)
> +{
> +	u32 reg, ofs, bp, bm;
> +	void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
> +
> +	/* muxsel */
> +	ofs = 0x100;
> +	ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
> +	bp = PAD_PIN(pad) % 16 * 2;
> +	bm = 0x3 << bp;
> +	reg = __raw_readl(iomux_base + ofs);
> +	reg &= ~bm;
> +	reg |= PAD_MUXSEL(pad) << bp;
> +	__raw_writel(reg, iomux_base + ofs);
> +
> +	/* drive */
> +	ofs = cpu_is_mx23() ? 0x200 : 0x300;
> +	ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
> +	/* ma */
'mA' would make it much clearer that milliamps are meant.

> +	if (PAD_MA(pad) != PAD_MA_NONE)
> +	{
'{' should be at the end of the 'if' line.

> +		bp = PAD_PIN(pad) % 8 * 4;
> +		bm = 0x3 << bp;
> +		reg = __raw_readl(iomux_base + ofs);
> +		reg &= ~bm;
> +		reg |= PAD_MA(pad) << bp;
> +		__raw_writel(reg, iomux_base + ofs);
> +	}
> +	/* vol */
> +	if (PAD_VOL(pad) != PAD_VOL_NONE)
> +	{
dto.

> +		bp = PAD_PIN(pad) % 8 * 4 + 2;
> +		bm = 0x1 << bp;
> +		reg = __raw_readl(iomux_base + ofs);
> +		reg &= ~bm;
> +		reg |= PAD_VOL(pad) << bp;
> +		__raw_writel(reg, iomux_base + ofs);
You could use a write to the SET/CLR address here instead of read/modify/write.

> +	}
> +
> +	/* pull */
> +	ofs = cpu_is_mx23() ? 0x400 : 0x600;
> +	ofs += PAD_BANK(pad) * 0x10;
> +	bp = PAD_PIN(pad);
> +	bm = 0x1 << bp;
> +	reg = __raw_readl(iomux_base + ofs);
> +	reg &= ~bm;
> +	reg |= PAD_PULL(pad) << bp;
> +	__raw_writel(reg, iomux_base + ofs);
dto.

> +
> +	return 0;
> +}
> +
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
> +{
> +	const iomux_cfg_t *p = pad_list;
> +	int i;
> +	int ret;
> +
> +	for (i = 0; i < count; i++) {
> +		ret = mxs_iomux_setup_pad(*p);
> +		if (ret)
> +			return ret;
> +		p++;
> +	}
> +
> +	return 0;
> +}
> -- 
> 1.7.1
> 
> 
Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-09 16:47   ` Lothar Waßmann
  2010-12-10  7:06     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Shawn Guo writes:
> MXS-based SoCs implement gpio support in block PINCTRL.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
>  - include/mach/gpio.h: remove the inclusion of hardware.h
>  - gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
>  - Remove spinlock totally since SET/CLE can be used in all the
>    gpio register access
> 
> Changes for v2:
>  - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>  - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>  - Remove both edges IRQ support which is not needed
>  - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>  - Use pr_info over printk(KERN_INFO)
> 
>  arch/arm/mach-mxs/gpio.c              |  321 +++++++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/gpio.h              |   33 ++++
>  arch/arm/mach-mxs/include/mach/gpio.h |   34 ++++
>  3 files changed, 388 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/gpio.c
>  create mode 100644 arch/arm/mach-mxs/gpio.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
> 
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..d88acf3
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
> @@ -0,0 +1,321 @@
> +/*
> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * Based on code from Freescale,
> + * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/gpio.h>
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <asm-generic/bug.h>
> +
> +#include "gpio.h"
> +
> +static struct mxs_gpio_port *mxs_gpio_ports;
> +static int gpio_table_size;
> +
> +#define PINCTRL_DOUT(n)		((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
> +#define PINCTRL_DIN(n)		((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
> +#define PINCTRL_DOE(n)		((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
> +#define PINCTRL_PIN2IRQ(n)	((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
> +#define PINCTRL_IRQEN(n)	((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
> +#define PINCTRL_IRQLEV(n)	((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
> +#define PINCTRL_IRQPOL(n)	((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
> +#define PINCTRL_IRQSTAT(n)	((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
> +
> +#define GPIO_INT_FALL_EDGE	0x0
> +#define GPIO_INT_LOW_LEV	0x1
> +#define GPIO_INT_RISE_EDGE	0x2
> +#define GPIO_INT_HIGH_LEV	0x3
> +#define GPIO_INT_LEV_MASK	(1 << 0)
> +#define GPIO_INT_POL_MASK	(1 << 1)
> +
> +/* Note: This driver assumes 32 GPIOs are handled in one register */
> +
> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
> +{
> +	__raw_writel(1 << index,
> +			port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
> +}
> +
> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> +				int enable)
> +{
> +	if (enable == 0) {
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> +		__raw_writel(1 << index,
> +			port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
This will loose interrupt pulses that happen while IRQs are disabled.
IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
is disabled.


Lothar Wa?mann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v4 01/15] ARM: mxs: Add core definitions
  2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-09 17:37   ` Russell King - ARM Linux
  0 siblings, 0 replies; 146+ messages in thread
From: Russell King - ARM Linux @ 2010-12-09 17:37 UTC (permalink / raw)
  To: linux-arm-kernel

A word of advice, merely as an on-looker.  Don't thread your new
versions of patches into the old thread.  I now have a total mixture
of v4, v3, v2, etc of these patches and it's not obvious what's the
latest, even if I switch to unsorted or received date.

It might be better to version the series, so that anyone can see which
patches related to the last series - and if you want per patch version
information, include that in the body of the message.

2190     Dec 08 Shawn Guo       ( 112) ??>[PATCH v2 12/15] ARM: mxs: Dynamically
2191     Dec 08 Shawn Guo       (  84) ??>[PATCH v2 13/15] ARM: mxs: Add initial
2192     Dec 08 Shawn Guo       ( 157) ??>[PATCH v2 14/15] ARM: mxs: Add initial
2193     Dec 08 Uwe Kleine-K?ni ( 183) ? ??>
2194     Dec 09 Shawn Guo       (  78) ?   ??>
2195     Dec 09 Uwe Kleine-K?ni (  22) ?     ??>
2196     Dec 09 Shawn Guo       (  39) ?       ??>
2197     Dec 09 Uwe Kleine-K?ni (  30) ?         ??>
2198     Dec 09 Shawn Guo       (  58) ?           ??>
2199     Dec 09 Lothar Wa?mann  (  93) ?             ??>
2200     Dec 09 Shawn Guo       ( 130) ?               ??>
2201     Dec 09 Shawn Guo       ( 133) ?                 ??>
2202     Dec 08 Shawn Guo       ( 155) ??>[PATCH v3 15/15] ARM: mxs: Add build c
2203 N   Dec 09 Shawn Guo       ( 588) ??>[PATCH v4 01/15] ARM: mxs: Add core de
2204 N   Dec 09 Shawn Guo       ( 154) ??>[PATCH v3 02/15] ARM: mxs: Add helper
2205 N   Dec 09 Shawn Guo       ( 213) ??>[PATCH v4 03/15] ARM: mxs: Add reset r
2206 N   Dec 09 Shawn Guo       ( 168) ??>[PATCH v3 04/15] ARM: mxs: Add interru
2207 N   Dec 09 Shawn Guo       ( 170) ??>[PATCH v3 05/15] ARM: mxs: Add low-lev
2208 N   Dec 09 Shawn Guo       ( 322) ??>[PATCH v4 06/15] ARM: mxs: Add timer s
2209 N   Dec 09 Shawn Guo       ( 440) ??>[PATCH v3 07/15] ARM: mxs: Add gpio su
2210 N   Dec 09 Lothar Wa?mann  ( 135) ? ??>
2211 N   Dec 09 Shawn Guo       (2730) ??>[PATCH v3 09/15] ARM: mxs: Add clock s
2212 N   Dec 09 Shawn Guo       ( 127) ??>[PATCH v2 10/15] ARM: mxs: Add static
2213 N   Dec 09 Shawn Guo       ( 247) ??>[PATCH v2 11/15] ARM: mxs: Dynamically
2214 N   Dec 09 Shawn Guo       ( 115) ??>[PATCH v3 12/15] ARM: mxs: Dynamically
2215 N   Dec 09 Shawn Guo       (  87) ??>[PATCH v3 13/15] ARM: mxs: Add initial
2216 N   Dec 09 Shawn Guo       ( 160) ??>[PATCH v3 14/15] ARM: mxs: Add initial
2217     Dec 09 Lothar Wa?mann  ( 432) ??>Re: [PATCH v3 08/15] ARM: mxs: Add iom

And we're currently on message number 3200 in this mailbox... so these
messages are buried about 1000 mails back.  Not good.

On Thu, Dec 09, 2010 at 11:12:36PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
>  - Move all MXS related definitions from hardware.h into mxs.h,
>    but have to keep hardware.h which is required by external file.
>  - Define IO addresses common to MXS-based in mxs.h
>  - Include hardware.h in mxs.h, include mxs.h in mx23.h and mx28.h,
>    so that files can include mxs.h, mx23.h, mx28.h individually
>    when necessary.
>  - Remove #include <linux/io.h> from mx23.h and mx28.h, since it's
>    not necessary.
> 
> Changes for v3:
>  - Update MXS_IO_P2V definition and comment to get them matched
>  - Sort mx23 base address definitions by offset
>  - Remove mx28 reserved IRQ definitions
>  - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
> 
> Changes for v2:
>  - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
>  - Simplify MXS_IO_P2V_MODULE definition in hardware.h
>  - Remove unnecessary inclusion protection from hardware.h
>  - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
> 
>  arch/arm/mach-mxs/include/mach/hardware.h |   29 +++++
>  arch/arm/mach-mxs/include/mach/irqs.h     |   32 +++++
>  arch/arm/mach-mxs/include/mach/memory.h   |   24 ++++
>  arch/arm/mach-mxs/include/mach/mx23.h     |  145 ++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mx28.h     |  188 +++++++++++++++++++++++++++++
>  arch/arm/mach-mxs/include/mach/mxs.h      |   85 +++++++++++++
>  6 files changed, 503 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>  create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
> 
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..53e89a0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * 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., 51 Franklin Street, Fifth Floor, Boston,
> + * MA  02110-1301, USA.
> + */
> +
> +#ifndef __MACH_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr)	(addr)
> +#else
> +#define IOMEM(addr)	((void __force __iomem *)(addr))
> +#endif
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + *  Copyright 2004-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 version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS	128
> +
> +#define MXS_GPIO_IRQ_START	MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS		(32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes.  Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these.  If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START	(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS		16
> +
> +#define NR_IRQS			(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET		UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..9edd02e
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,145 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#include <mach/mxs.h>
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR		0x00000000
> +#define MX23_OCRAM_SIZE			SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR		0x80000000
> +#define MX23_IO_SIZE			SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_PINCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_SSP2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_TVENC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x)		IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART			0
> +#define MX23_INT_COMMS_RX		1
> +#define MX23_INT_COMMS_TX		1
> +#define MX23_INT_SSP2_ERROR		2
> +#define MX23_INT_VDD5V			3
> +#define MX23_INT_HEADPHONE_SHORT	4
> +#define MX23_INT_DAC_DMA		5
> +#define MX23_INT_DAC_ERROR		6
> +#define MX23_INT_ADC_DMA		7
> +#define MX23_INT_ADC_ERROR		8
> +#define MX23_INT_SPDIF_DMA		9
> +#define MX23_INT_SAIF2_DMA		9
> +#define MX23_INT_SPDIF_ERROR		10
> +#define MX23_INT_SAIF1_IRQ		10
> +#define MX23_INT_SAIF2_IRQ		10
> +#define MX23_INT_USB_CTRL		11
> +#define MX23_INT_USB_WAKEUP		12
> +#define MX23_INT_GPMI_DMA		13
> +#define MX23_INT_SSP1_DMA		14
> +#define MX23_INT_SSP_ERROR		15
> +#define MX23_INT_GPIO0			16
> +#define MX23_INT_GPIO1			17
> +#define MX23_INT_GPIO2			18
> +#define MX23_INT_SAIF1_DMA		19
> +#define MX23_INT_SSP2_DMA		20
> +#define MX23_INT_ECC8_IRQ		21
> +#define MX23_INT_RTC_ALARM		22
> +#define MX23_INT_UARTAPP_TX_DMA		23
> +#define MX23_INT_UARTAPP_INTERNAL	24
> +#define MX23_INT_UARTAPP_RX_DMA		25
> +#define MX23_INT_I2C_DMA		26
> +#define MX23_INT_I2C_ERROR		27
> +#define MX23_INT_TIMER0			28
> +#define MX23_INT_TIMER1			29
> +#define MX23_INT_TIMER2			30
> +#define MX23_INT_TIMER3			31
> +#define MX23_INT_BATT_BRNOUT		32
> +#define MX23_INT_VDDD_BRNOUT		33
> +#define MX23_INT_VDDIO_BRNOUT		34
> +#define MX23_INT_VDD18_BRNOUT		35
> +#define MX23_INT_TOUCH_DETECT		36
> +#define MX23_INT_LRADC_CH0		37
> +#define MX23_INT_LRADC_CH1		38
> +#define MX23_INT_LRADC_CH2		39
> +#define MX23_INT_LRADC_CH3		40
> +#define MX23_INT_LRADC_CH4		41
> +#define MX23_INT_LRADC_CH5		42
> +#define MX23_INT_LRADC_CH6		43
> +#define MX23_INT_LRADC_CH7		44
> +#define MX23_INT_LCDIF_DMA		45
> +#define MX23_INT_LCDIF_ERROR		46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP	47
> +#define MX23_INT_RTC_1MSEC		48
> +#define MX23_INT_DRI_DMA		49
> +#define MX23_INT_DRI_ATTENTION		50
> +#define MX23_INT_GPMI_ATTENTION		51
> +#define MX23_INT_IR			52
> +#define MX23_INT_DCP_VMI		53
> +#define MX23_INT_DCP			54
> +#define MX23_INT_BCH			56
> +#define MX23_INT_PXP			57
> +#define MX23_INT_UARTAPP2_TX_DMA	58
> +#define MX23_INT_UARTAPP2_INTERNAL	59
> +#define MX23_INT_UARTAPP2_RX_DMA	60
> +#define MX23_INT_VDAC_DETECT		61
> +#define MX23_INT_VDD5V_DROOP		64
> +#define MX23_INT_DCDC4P2_BO		65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..0716745
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,188 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#include <mach/mxs.h>
> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR		0x00000000
> +#define MX28_OCRAM_SIZE			SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR		0x80000000
> +#define MX28_IO_SIZE			SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_MAC0_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x)			MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x)		IOMEM(MX28_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT		0
> +#define MX28_INT_VDDD_BRNOUT		1
> +#define MX28_INT_VDDIO_BRNOUT		2
> +#define MX28_INT_VDDA_BRNOUT		3
> +#define MX28_INT_VDD5V_DROOP		4
> +#define MX28_INT_DCDC4P2_BRNOUT		5
> +#define MX28_INT_VDD5V			6
> +#define MX28_INT_CAN0			8
> +#define MX28_INT_CAN1			9
> +#define MX28_INT_LRADC_TOUCH		10
> +#define MX28_INT_HSADC			13
> +#define MX28_INT_IRADC_THRESH0		14
> +#define MX28_INT_IRADC_THRESH1		15
> +#define MX28_INT_LRADC_CH0		16
> +#define MX28_INT_LRADC_CH1		17
> +#define MX28_INT_LRADC_CH2		18
> +#define MX28_INT_LRADC_CH3		19
> +#define MX28_INT_LRADC_CH4		20
> +#define MX28_INT_LRADC_CH5		21
> +#define MX28_INT_LRADC_CH6		22
> +#define MX28_INT_LRADC_CH7		23
> +#define MX28_INT_LRADC_BUTTON0		24
> +#define MX28_INT_LRADC_BUTTON1		25
> +#define MX28_INT_PERFMON		27
> +#define MX28_INT_RTC_1MSEC		28
> +#define MX28_INT_RTC_ALARM		29
> +#define MX28_INT_COMMS			31
> +#define MX28_INT_EMI_ERR		32
> +#define MX28_INT_LCDIF			38
> +#define MX28_INT_PXP			39
> +#define MX28_INT_BCH			41
> +#define MX28_INT_GPMI			42
> +#define MX28_INT_SPDIF_ERROR		45
> +#define MX28_INT_DUART			47
> +#define MX28_INT_TIMER0			48
> +#define MX28_INT_TIMER1			49
> +#define MX28_INT_TIMER2			50
> +#define MX28_INT_TIMER3			51
> +#define MX28_INT_DCP_VMI		52
> +#define MX28_INT_DCP			53
> +#define MX28_INT_DCP_SECURE		54
> +#define MX28_INT_SAIF1			58
> +#define MX28_INT_SAIF0			59
> +#define MX28_INT_SPDIF_DMA		66
> +#define MX28_INT_I2C0_DMA		68
> +#define MX28_INT_I2C1_DMA		69
> +#define MX28_INT_AUART0_RX_DMA		70
> +#define MX28_INT_AUART0_TX_DMA		71
> +#define MX28_INT_AUART1_RX_DMA		72
> +#define MX28_INT_AUART1_TX_DMA		73
> +#define MX28_INT_AUART2_RX_DMA		74
> +#define MX28_INT_AUART2_TX_DMA		75
> +#define MX28_INT_AUART3_RX_DMA		76
> +#define MX28_INT_AUART3_TX_DMA		77
> +#define MX28_INT_AUART4_RX_DMA		78
> +#define MX28_INT_AUART4_TX_DMA		79
> +#define MX28_INT_SAIF0_DMA		80
> +#define MX28_INT_SAIF1_DMA		81
> +#define MX28_INT_SSP0_DMA		82
> +#define MX28_INT_SSP1_DMA		83
> +#define MX28_INT_SSP2_DMA		84
> +#define MX28_INT_SSP3_DMA		85
> +#define MX28_INT_LCDIF_DMA		86
> +#define MX28_INT_HSADC_DMA		87
> +#define MX28_INT_GPMI_DMA		88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP	89
> +#define MX28_INT_USB1			92
> +#define MX28_INT_USB0			93
> +#define MX28_INT_USB1_WAKEUP		94
> +#define MX28_INT_USB0_WAKEUP		95
> +#define MX28_INT_SSP0			96
> +#define MX28_INT_SSP1			97
> +#define MX28_INT_SSP2			98
> +#define MX28_INT_SSP3			99
> +#define MX28_INT_ENET_SWI		100
> +#define MX28_INT_ENET_MAC0		101
> +#define MX28_INT_ENET_MAC1		102
> +#define MX28_INT_ENET_MAC0_1588		103
> +#define MX28_INT_ENET_MAC1_1588		104
> +#define MX28_INT_I2C1_ERROR		110
> +#define MX28_INT_I2C0_ERROR		111
> +#define MX28_INT_AUART0			112
> +#define MX28_INT_AUART1			113
> +#define MX28_INT_AUART2			114
> +#define MX28_INT_AUART3			115
> +#define MX28_INT_AUART4			116
> +#define MX28_INT_GPIO4			123
> +#define MX28_INT_GPIO3			124
> +#define MX28_INT_GPIO2			125
> +#define MX28_INT_GPIO1			126
> +#define MX28_INT_GPIO0			127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..4212ab0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (C) 2009-2010 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.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +#include <mach/hardware.h>
> +
> +/*
> + * MXS CPU types
> + */
> +#define cpu_is_mx23()		(machine_is_mx23evk())
> +#define cpu_is_mx28()		(machine_is_mx28evk())
> +
> +#define MXS_SET_ADDR		0x4
> +#define MXS_CLR_ADDR		0x8
> +#define MXS_TOG_ADDR		0xc
> +
> +/*
> + * IO addresses common to MXS-based
> + */
> +#define MXS_IO_BASE_ADDR		0x80000000
> +#define MXS_IO_SIZE			SZ_1M
> +
> +#define MXS_ICOLL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x000000)
> +#define MXS_APBH_DMA_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x004000)
> +#define MXS_BCH_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x00a000)
> +#define MXS_GPMI_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x00c000)
> +#define MXS_PINCTRL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x018000)
> +#define MXS_DIGCTL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x01c000)
> +#define MXS_APBX_DMA_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x024000)
> +#define MXS_DCP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x028000)
> +#define MXS_PXP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02a000)
> +#define MXS_OCOTP_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02c000)
> +#define MXS_AXI_AHB0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x02e000)
> +#define MXS_LCDIF_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x030000)
> +#define MXS_CLKCTRL_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x040000)
> +#define MXS_SAIF0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x042000)
> +#define MXS_POWER_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x044000)
> +#define MXS_SAIF1_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x046000)
> +#define MXS_LRADC_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x050000)
> +#define MXS_SPDIF_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x054000)
> +#define MXS_I2C0_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x058000)
> +#define MXS_PWM_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x064000)
> +#define MXS_TIMROT_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x068000)
> +#define MXS_AUART1_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x06c000)
> +#define MXS_AUART2_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x06e000)
> +#define MXS_DRAM_BASE_ADDR		(MXS_IO_BASE_ADDR + 0x0e0000)
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf50fffff].
> + *
> + *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
> + *	IO	0x80000000+0x100000	->	0xf5000000+0x100000
> + */
> +#define MXS_IO_P2V(x)	(0xf4000000 +					\
> +			(((x) & 0x80000000) >> 7) +			\
> +			(((x) & 0x000fffff)))
> +
> +#define MXS_IO_ADDRESS(x)	IOMEM(MXS_IO_P2V(x))
> +
> +#define mxs_map_entry(soc, name, _type)	{				\
> +	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
> +	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
> +	.length = soc ## _ ## name ## _SIZE,				\
> +	.type = _type,							\
> +}
> +
> +#endif /* __MACH_MXS_H__ */
> -- 
> 1.7.1
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 09/15] ARM: mxs: Add clock support
  2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-09 21:11   ` Uwe Kleine-König
  0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 21:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Thu, Dec 09, 2010 at 11:12:44PM +0800, Shawn Guo wrote:
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..b2923da
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,526 @@
> +[...]
> +static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +[...]
> +		rate <<= PARENT_RATE_SHIFT;
> +		parent_rate <<= PARENT_RATE_SHIFT;
You're making the problem worse here.  You need to shift right!

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-12-09 16:47   ` Lothar Waßmann
@ 2010-12-10  7:06     ` Shawn Guo
  2010-12-10  7:23       ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-10  7:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lothar,

On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Hi,
>
> Shawn Guo writes:
>> MXS-based SoCs implement gpio support in block PINCTRL.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v3:
>> ?- include/mach/gpio.h: remove the inclusion of hardware.h
>> ?- gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
>> ?- Remove spinlock totally since SET/CLE can be used in all the
>> ? ?gpio register access
>>
>> Changes for v2:
>> ?- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>> ?- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>> ?- Remove both edges IRQ support which is not needed
>> ?- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>> ?- Use pr_info over printk(KERN_INFO)
>>
>> ?arch/arm/mach-mxs/gpio.c ? ? ? ? ? ? ?| ?321 +++++++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/gpio.h ? ? ? ? ? ? ?| ? 33 ++++
>> ?arch/arm/mach-mxs/include/mach/gpio.h | ? 34 ++++
>> ?3 files changed, 388 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/gpio.c
>> ?create mode 100644 arch/arm/mach-mxs/gpio.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>>
>> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
>> new file mode 100644
>> index 0000000..d88acf3
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/gpio.c
>> @@ -0,0 +1,321 @@
>> +/*
>> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
>> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>> + *
>> + * Based on code from Freescale,
>> + * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA ?02110-1301, USA.
>> + */
>> +
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/irq.h>
>> +#include <linux/gpio.h>
>> +#include <mach/mx23.h>
>> +#include <mach/mx28.h>
>> +#include <asm-generic/bug.h>
>> +
>> +#include "gpio.h"
>> +
>> +static struct mxs_gpio_port *mxs_gpio_ports;
>> +static int gpio_table_size;
>> +
>> +#define PINCTRL_DOUT(n) ? ? ? ? ? ? ?((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
>> +#define PINCTRL_DIN(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
>> +#define PINCTRL_DOE(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
>> +#define PINCTRL_PIN2IRQ(n) ? ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
>> +#define PINCTRL_IRQEN(n) ? ? ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
>> +#define PINCTRL_IRQLEV(n) ? ?((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
>> +#define PINCTRL_IRQPOL(n) ? ?((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
>> +#define PINCTRL_IRQSTAT(n) ? ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
>> +
>> +#define GPIO_INT_FALL_EDGE ? 0x0
>> +#define GPIO_INT_LOW_LEV ? ? 0x1
>> +#define GPIO_INT_RISE_EDGE ? 0x2
>> +#define GPIO_INT_HIGH_LEV ? ?0x3
>> +#define GPIO_INT_LEV_MASK ? ?(1 << 0)
>> +#define GPIO_INT_POL_MASK ? ?(1 << 1)
>> +
>> +/* Note: This driver assumes 32 GPIOs are handled in one register */
>> +
>> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
>> +{
>> + ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
>> +}
>> +
>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> +{
>> + ? ? if (enable == 0) {
>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> This will loose interrupt pulses that happen while IRQs are disabled.
> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
> is disabled.
>
What about leaving PIN2IRQ always be 1 and only using IRQEN to
enable/disable IRQ?  I consulted the designer it's no problem no
matter what the pin function is.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-12-10  7:06     ` Shawn Guo
@ 2010-12-10  7:23       ` Shawn Guo
  2010-12-10  8:11         ` Uwe Kleine-König
  0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-10  7:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> Hi Lothar,
>
> On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> Hi,
>>
>> Shawn Guo writes:
>>> MXS-based SoCs implement gpio support in block PINCTRL.
>>>
>>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>>> ---
>>> Changes for v3:
>>> ?- include/mach/gpio.h: remove the inclusion of hardware.h
>>> ?- gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
>>> ?- Remove spinlock totally since SET/CLE can be used in all the
>>> ? ?gpio register access
>>>
>>> Changes for v2:
>>> ?- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>>> ?- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>>> ?- Remove both edges IRQ support which is not needed
>>> ?- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>>> ?- Use pr_info over printk(KERN_INFO)
>>>
>>> ?arch/arm/mach-mxs/gpio.c ? ? ? ? ? ? ?| ?321 +++++++++++++++++++++++++++++++++
>>> ?arch/arm/mach-mxs/gpio.h ? ? ? ? ? ? ?| ? 33 ++++
>>> ?arch/arm/mach-mxs/include/mach/gpio.h | ? 34 ++++
>>> ?3 files changed, 388 insertions(+), 0 deletions(-)
>>> ?create mode 100644 arch/arm/mach-mxs/gpio.c
>>> ?create mode 100644 arch/arm/mach-mxs/gpio.h
>>> ?create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>>>
>>> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
>>> new file mode 100644
>>> index 0000000..d88acf3
>>> --- /dev/null
>>> +++ b/arch/arm/mach-mxs/gpio.c
>>> @@ -0,0 +1,321 @@
>>> +/*
>>> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
>>> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>>> + *
>>> + * Based on code from Freescale,
>>> + * Copyright (C) 2004-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA ?02110-1301, USA.
>>> + */
>>> +
>>> +#include <linux/init.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/io.h>
>>> +#include <linux/irq.h>
>>> +#include <linux/gpio.h>
>>> +#include <mach/mx23.h>
>>> +#include <mach/mx28.h>
>>> +#include <asm-generic/bug.h>
>>> +
>>> +#include "gpio.h"
>>> +
>>> +static struct mxs_gpio_port *mxs_gpio_ports;
>>> +static int gpio_table_size;
>>> +
>>> +#define PINCTRL_DOUT(n) ? ? ? ? ? ? ?((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
>>> +#define PINCTRL_DIN(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
>>> +#define PINCTRL_DOE(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
>>> +#define PINCTRL_PIN2IRQ(n) ? ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
>>> +#define PINCTRL_IRQEN(n) ? ? ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
>>> +#define PINCTRL_IRQLEV(n) ? ?((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
>>> +#define PINCTRL_IRQPOL(n) ? ?((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
>>> +#define PINCTRL_IRQSTAT(n) ? ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
>>> +
>>> +#define GPIO_INT_FALL_EDGE ? 0x0
>>> +#define GPIO_INT_LOW_LEV ? ? 0x1
>>> +#define GPIO_INT_RISE_EDGE ? 0x2
>>> +#define GPIO_INT_HIGH_LEV ? ?0x3
>>> +#define GPIO_INT_LEV_MASK ? ?(1 << 0)
>>> +#define GPIO_INT_POL_MASK ? ?(1 << 1)
>>> +
>>> +/* Note: This driver assumes 32 GPIOs are handled in one register */
>>> +
>>> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
>>> +{
>>> + ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
>>> +}
>>> +
>>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>>> +{
>>> + ? ? if (enable == 0) {
>>> + ? ? ? ? ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>>> + ? ? ? ? ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> This will loose interrupt pulses that happen while IRQs are disabled.
>> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
>> is disabled.
>>
> What about leaving PIN2IRQ always be 1 and only using IRQEN to
> enable/disable IRQ? ?I consulted the designer it's no problem no
> matter what the pin function is.
>
The code will be like:

static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
                                int enable)
{
        if (enable) {
                __raw_writel(1 << index,
                        port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
                __raw_writel(1 << index,
                        port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
        } else {
                __raw_writel(1 << index,
                        port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
        }
}


-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-12-10  7:23       ` Shawn Guo
@ 2010-12-10  8:11         ` Uwe Kleine-König
  2010-12-10 15:32           ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-10  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Fri, Dec 10, 2010 at 03:23:13PM +0800, Shawn Guo wrote:
> On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> > On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> >> Shawn Guo writes:
> >>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
> >>> +{
> >>> + ? ? if (enable == 0) {
> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> >> This will loose interrupt pulses that happen while IRQs are disabled.
> >> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
> >> is disabled.
> >>
> > What about leaving PIN2IRQ always be 1 and only using IRQEN to
> > enable/disable IRQ? ?I consulted the designer it's no problem no
> > matter what the pin function is.
> >
> The code will be like:
> 
> static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>                                 int enable)
> {
>         if (enable) {
>                 __raw_writel(1 << index,
>                         port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
>                 __raw_writel(1 << index,
>                         port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
>         } else {
>                 __raw_writel(1 << index,
>                         port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>         }
> }
If I understood Lothar correctly the best way is to set and clear
PINCTRL_PIN2IRQ in the irqchips irq_startup and irq_shutdown routine.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
  2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-10 14:51   ` Uwe Kleine-König
  2010-12-10 15:05     ` Shawn Guo
  0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-10 14:51 UTC (permalink / raw)
  To: linux-arm-kernel

Hallo Shawn,

On Wed, Dec 08, 2010 at 12:32:03AM +0800, Shawn Guo wrote:
>  - Remove cpu.o from arch/arm/mach-mxs/Makefile
> [...]
>
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> new file mode 100644
> index 0000000..40b808c
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -0,0 +1,10 @@
> +# Common support
> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
                    ^^^^^

Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
  2010-12-10 14:51   ` Uwe Kleine-König
@ 2010-12-10 15:05     ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/10 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hallo Shawn,
>
> On Wed, Dec 08, 2010 at 12:32:03AM +0800, Shawn Guo wrote:
>> ?- Remove cpu.o from arch/arm/mach-mxs/Makefile
>> [...]
>>
>> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
>> new file mode 100644
>> index 0000000..40b808c
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/Makefile
>> @@ -0,0 +1,10 @@
>> +# Common support
>> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> ? ? ? ? ? ? ? ? ? ?^^^^^
>
There was something wrong with my patch management.  The commit of
removing cpu.o was squashed into another local patch.  Thanks for
catching.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v3 07/15] ARM: mxs: Add gpio support
  2010-12-10  8:11         ` Uwe Kleine-König
@ 2010-12-10 15:32           ` Shawn Guo
  0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/12/10 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Dec 10, 2010 at 03:23:13PM +0800, Shawn Guo wrote:
>> On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
>> > On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> >> Shawn Guo writes:
>> >>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> >>> +{
>> >>> + ? ? if (enable == 0) {
>> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> >> This will loose interrupt pulses that happen while IRQs are disabled.
>> >> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
>> >> is disabled.
>> >>
>> > What about leaving PIN2IRQ always be 1 and only using IRQEN to
>> > enable/disable IRQ? ?I consulted the designer it's no problem no
>> > matter what the pin function is.
>> >
>> The code will be like:
>>
>> static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> {
>> ? ? ? ? if (enable) {
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
>> ? ? ? ? } else {
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> ? ? ? ? }
>> }
> If I understood Lothar correctly the best way is to set and clear
> PINCTRL_PIN2IRQ in the irqchips irq_startup and irq_shutdown routine.
>
Is there any problem with the current code to address Lothar's
concern?  If no, I would not introduce two more irq_chip routines into
the file.

-- 
Regards,
Shawn

^ permalink raw reply	[flat|nested] 146+ messages in thread

end of thread, other threads:[~2010-12-10 15:32 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-26  6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-11-26  6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-11-26 11:30   ` Uwe Kleine-König
2010-11-29  7:21     ` Shawn Guo
2010-11-26  6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-11-26  6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-11-26  9:31   ` Lothar Waßmann
2010-11-26  9:57     ` Uwe Kleine-König
2010-11-26 10:38       ` Lothar Waßmann
2010-11-26 11:32         ` Uwe Kleine-König
2010-11-26 12:53           ` Lothar Waßmann
2010-11-29  9:25           ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
2010-11-29  9:58             ` Uwe Kleine-König
2010-12-06 16:13               ` Uwe Kleine-König
2010-11-26 14:16         ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
2010-11-26 14:38           ` Lothar Waßmann
2010-11-26  6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-11-30 13:56   ` Uwe Kleine-König
2010-11-30 17:02     ` Russell King - ARM Linux
2010-12-01 11:23     ` Shawn Guo
2010-11-26  6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-11-30 15:48   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
2010-11-30 16:13   ` Uwe Kleine-König
2010-12-02 14:44     ` Shawn Guo
2010-12-02 15:20       ` Thomas Gleixner
2010-12-02 16:48       ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-11-30 16:21   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-11-30 16:32   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
2010-11-30 16:39   ` Uwe Kleine-König
2010-12-07 13:09     ` Shawn Guo
2010-12-07 13:33       ` Uwe Kleine-König
2010-12-07 13:53         ` Shawn Guo
2010-12-02 15:07   ` Uwe Kleine-König
2010-12-03  5:07     ` Shawn Guo
2010-11-26  6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-11-26  6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
2010-11-26  6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-11-30 20:01   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-11-30 20:02   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
2010-11-30 20:06   ` Uwe Kleine-König
2010-11-26  6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-11-30 20:08   ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-11-30  9:21   ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-11-30 10:25   ` Uwe Kleine-König
2010-12-01 10:45     ` Shawn Guo
2010-12-01 10:59       ` Uwe Kleine-König
2010-12-01 11:34         ` Shawn Guo
2010-12-02  6:02     ` Shawn Guo
2010-12-02  7:27       ` Uwe Kleine-König
2010-12-02  9:40   ` Uwe Kleine-König
2010-12-02 10:16     ` Shawn Guo
2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-07 20:18   ` Uwe Kleine-König
2010-12-08  4:50     ` Shawn Guo
2010-12-08  9:17       ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-07 20:27   ` Uwe Kleine-König
2010-12-08  7:33   ` Lothar Waßmann
2010-12-08 20:31     ` Uwe Kleine-König
2010-12-09  8:51       ` Shawn Guo
2010-12-09  8:55         ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-12-07 21:03   ` Uwe Kleine-König
2010-12-08  8:27     ` Shawn Guo
2010-12-08  9:39       ` Uwe Kleine-König
2010-12-08 10:46         ` Shawn Guo
2010-12-08 12:09           ` Uwe Kleine-König
2010-12-08 12:31             ` Shawn Guo
2010-12-08  8:56     ` Shawn Guo
2010-12-08  9:14       ` Uwe Kleine-König
2010-12-08  8:24   ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-12-08 20:27   ` Uwe Kleine-König
2010-12-09  2:02     ` Shawn Guo
2010-12-09  8:42       ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-07 21:18   ` Uwe Kleine-König
2010-12-08  5:58     ` Shawn Guo
2010-12-08  9:25       ` Uwe Kleine-König
2010-12-08  8:30   ` Lothar Waßmann
2010-12-08  9:31     ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-08  7:21   ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-08  7:25   ` Lothar Waßmann
2010-12-08 10:52     ` Shawn Guo
2010-12-08 10:56       ` Uwe Kleine-König
2010-12-08 11:29         ` Shawn Guo
2010-12-08 11:32           ` Lothar Waßmann
2010-12-09  6:15             ` Shawn Guo
2010-12-09  8:43               ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
2010-12-08 20:57   ` Uwe Kleine-König
2010-12-09  1:44     ` Shawn Guo
2010-12-09  8:41   ` Uwe Kleine-König
2010-12-09 10:04     ` Shawn Guo
2010-12-09 10:30     ` Shawn Guo
2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
2010-12-08 20:28   ` Uwe Kleine-König
2010-12-09  7:04     ` Shawn Guo
2010-12-09  8:32       ` Uwe Kleine-König
2010-12-09  9:03         ` Shawn Guo
2010-12-09  9:37           ` Uwe Kleine-König
2010-12-09 10:17             ` Shawn Guo
2010-12-09 12:27               ` Lothar Waßmann
2010-12-09 13:38                 ` Shawn Guo
2010-12-09 13:54                   ` Shawn Guo
2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-12-10 14:51   ` Uwe Kleine-König
2010-12-10 15:05     ` Shawn Guo
2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-09 17:37   ` Russell King - ARM Linux
2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-09 16:47   ` Lothar Waßmann
2010-12-10  7:06     ` Shawn Guo
2010-12-10  7:23       ` Shawn Guo
2010-12-10  8:11         ` Uwe Kleine-König
2010-12-10 15:32           ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-09 16:12   ` Lothar Waßmann
2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
2010-12-09 21:11   ` Uwe Kleine-König
2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.