config ARM
bool
default y
+ select ARCH_HAVE_CUSTOM_GPIO_H
select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE if PCI || ISA || PCMCIA
+ select HAVE_DMA_ATTRS
+ select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
+ select CMA if (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
+ select HAVE_ARCH_TRACEHOOK
select HAVE_KPROBES if !XIP_KERNEL
select HAVE_KRETPROBES if (HAVE_KPROBES)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
select HAVE_C_RECORDMCOUNT
select HAVE_GENERIC_HARDIRQS
+ select HARDIRQS_SW_RESEND
+ select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
+ select GENERIC_IRQ_PROBE
+ select HARDIRQS_SW_RESEND
select CPU_PM if (SUSPEND || CPU_IDLE)
select GENERIC_PCI_IOMAP
- select HAVE_BPF_JIT if NET
+ select HAVE_BPF_JIT
+ select GENERIC_SMP_IDLE_THREAD
+ select KTIME_SCALAR
+ select GENERIC_CLOCKEVENTS_BROADCAST if SMP
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
config ARM_HAS_SG_CHAIN
bool
-config HAVE_PWM
- bool
-
-config MIGHT_HAVE_PCI
- bool
-
-config SYS_SUPPORTS_APM_EMULATION
+config NEED_SG_DMA_LENGTH
bool
-config GENERIC_GPIO
+config ARM_DMA_USE_IOMMU
+ select NEED_SG_DMA_LENGTH
+ select ARM_HAS_SG_CHAIN
bool
-config ARCH_USES_GETTIMEOFFSET
+config HAVE_PWM
bool
- default n
-config GENERIC_CLOCKEVENTS
+config MIGHT_HAVE_PCI
bool
-config GENERIC_CLOCKEVENTS_BROADCAST
+config SYS_SUPPORTS_APM_EMULATION
bool
- depends on GENERIC_CLOCKEVENTS
- default y if SMP
-config KTIME_SCALAR
+config GENERIC_GPIO
bool
- default y
config HAVE_TCM
bool
config SBUS
bool
-config MCA
- bool
- help
- MicroChannel Architecture is found in some IBM PS/2 machines and
- laptops. It is a bus system similar to PCI or ISA. See
- <file:Documentation/mca.txt> (and especially the web page given
- there) before attempting to build an MCA bus kernel.
-
config STACKTRACE_SUPPORT
bool
default y
bool
default y
-config HARDIRQS_SW_RESEND
- bool
- default y
-
-config GENERIC_IRQ_PROBE
- bool
- default y
-
config GENERIC_LOCKBREAK
bool
default y
and that the relevant menu configurations are displayed for
it.
-config ARCH_HAS_CPU_IDLE_WAIT
- def_bool y
-
config GENERIC_HWEIGHT
bool
default y
select NEED_MACH_IO_H
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
+ select MULTI_IRQ_HANDLER
help
Support for ARM's Integrator platform.
select IRQ_DOMAIN
select NEED_MACH_IO_H if PCCARD
help
- This enables support for systems based on the Atmel AT91RM9200,
- AT91SAM9 processors.
+ This enables support for systems based on Atmel
+ AT91RM9200 and AT91SAM9* processors.
config ARCH_BCMRING
bool "Broadcom BCMRING"
Support for the Calxeda Highbank SoC based boards.
config ARCH_CLPS711X
- bool "Cirrus Logic CLPS711x/EP721x-based"
+ bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
select CPU_ARM720T
select ARCH_USES_GETTIMEOFFSET
select NEED_MACH_MEMORY_H
help
- Support for Cirrus Logic 711x/721x based boards.
+ Support for Cirrus Logic 711x/721x/731x based boards.
config ARCH_CNS3XXX
bool "Cavium Networks CNS3XXX family"
select CLKDEV_LOOKUP
select GENERIC_IRQ_CHIP
select MIGHT_HAVE_CACHE_L2X0
+ select PINCTRL
+ select PINCTRL_SIRF
select USE_OF
select ZONE_DMA
help
select COMMON_CLK
select HAVE_CLK_PREPARE
select PINCTRL
+ select USE_OF
help
Support for Freescale MXS-based family of processors
help
Support for Intel's IOP33X (XScale) family of processors.
-config ARCH_IXP23XX
- bool "IXP23XX-based"
- depends on MMU
- select CPU_XSC3
- select PCI
- select ARCH_USES_GETTIMEOFFSET
- select NEED_MACH_IO_H
- select NEED_MACH_MEMORY_H
- help
- Support for Intel's IXP23xx (XScale) family of processors.
-
-config ARCH_IXP2000
- bool "IXP2400/2800-based"
- depends on MMU
- select CPU_XSCALE
- select PCI
- select ARCH_USES_GETTIMEOFFSET
- select NEED_MACH_IO_H
- select NEED_MACH_MEMORY_H
- help
- Support for Intel's IXP2400/2800 (XScale) family of processors.
-
config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
select USB_ARCH_HAS_OHCI
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
+ select USE_OF
help
Support for the NXP LPC32XX family of processors
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
select GPIO_PXA
- select TICK_ONESHOT
+ select IRQ_DOMAIN
select PLAT_PXA
select SPARSE_IRQ
select GENERIC_ALLOCATOR
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select GPIO_PXA
- select TICK_ONESHOT
select PLAT_PXA
select SPARSE_IRQ
select AUTO_ZRELADDR
select CPU_FREQ
select GENERIC_CLOCKEVENTS
select CLKDEV_LOOKUP
- select TICK_ONESHOT
select ARCH_REQUIRE_GPIOLIB
select HAVE_IDE
select NEED_MACH_MEMORY_H
select CPU_ARM926T
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
+ select PINCTRL
select MIGHT_HAVE_CACHE_L2X0
select ARCH_REQUIRE_GPIOLIB
help
select ARM_AMBA
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
+ select COMMON_CLK
select CLKSRC_MMIO
select GENERIC_CLOCKEVENTS
select HAVE_CLK
source "arch/arm/mach-ixp4xx/Kconfig"
-source "arch/arm/mach-ixp2000/Kconfig"
-
-source "arch/arm/mach-ixp23xx/Kconfig"
-
source "arch/arm/mach-kirkwood/Kconfig"
source "arch/arm/mach-ks8695/Kconfig"
source "arch/arm/plat-samsung/Kconfig"
source "arch/arm/plat-s3c24xx/Kconfig"
-source "arch/arm/plat-s5p/Kconfig"
source "arch/arm/plat-spear/Kconfig"
bool
select CLKSRC_MMIO
select GENERIC_IRQ_CHIP
+ select COMMON_CLK
config PLAT_PXA
bool
menu "Kernel Features"
-source "kernel/time/Kconfig"
-
config HAVE_SMP
bool
help
help
This option enables support for the ARM system coherency unit
+config ARM_ARCH_TIMER
+ bool "Architected timer support"
+ depends on CPU_V7
+ help
+ This option enables support for the ARM architected timer
+
config HAVE_ARM_TWD
bool
depends on SMP
- select TICK_ONESHOT
help
This options enables support for the ARM timer and watchdog unit
default ZBOOT_ROM_NONE
help
Include experimental SD/MMC loading code in the ROM-able zImage.
- With this enabled it is possible to write the the ROM-able zImage
+ With this enabled it is possible to write the ROM-able zImage
kernel image to an MMC or SD card and boot the kernel straight
from the reset vector. At reset the processor Mask ROM will load
- the first part of the the ROM-able zImage which in turn loads the
+ the first part of the ROM-able zImage which in turn loads the
rest the kernel image to RAM.
config ZBOOT_ROM_NONE
source "kernel/power/Kconfig"
config ARCH_SUSPEND_POSSIBLE
- depends on !ARCH_S5PC100
+ depends on !ARCH_S5PC100 && !ARCH_TEGRA
depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
- CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
+ CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
def_bool y
config ARM_CPU_SUSPEND
Say Y here if you want the debug print routines to direct
their output to the second serial port on these devices.
+ config DEBUG_DAVINCI_DA8XX_UART1
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART1"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DA8XX_UART2
+ bool "Kernel low-level debugging on DaVinci DA8XX using UART2"
+ depends on ARCH_DAVINCI_DA8XX
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART2 serial port on DaVinci DA8XX devices.
+
+ config DEBUG_DAVINCI_DMx_UART0
+ bool "Kernel low-level debugging on DaVinci DMx using UART0"
+ depends on ARCH_DAVINCI_DMx
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART0 serial port on DaVinci DMx devices.
+
+ config DEBUG_DAVINCI_TNETV107X_UART1
+ bool "Kernel low-level debugging on DaVinci TNETV107x using UART1"
+ depends on ARCH_DAVINCI_TNETV107X
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to UART1 serial port on DaVinci TNETV107X
+ devices.
+
config DEBUG_DC21285_PORT
bool "Kernel low-level debugging messages via footbridge serial port"
depends on FOOTBRIDGE
Say Y here if you want kernel low-level debugging support
on i.MX50 or i.MX53.
+ config DEBUG_IMX6Q_UART2
+ bool "i.MX6Q Debug UART2"
+ depends on SOC_IMX6Q
+ help
+ Say Y here if you want kernel low-level debugging support
+ on i.MX6Q UART2. This is correct for e.g. the SabreLite
+ board.
+
config DEBUG_IMX6Q_UART4
bool "i.MX6Q Debug UART4"
depends on SOC_IMX6Q
name, id, res, num_resources, data, size_data, 0);
}
-int __init mxs_add_amba_device(const struct amba_device *dev);
-
-/* duart */
-int __init mxs_add_duart(const struct amba_device *dev);
-
/* auart */
struct mxs_auart_data {
int id;
const struct mxs_mxs_i2c_data *data);
/* mmc */
- #include <mach/mmc.h>
+ #include <linux/mmc/mxs-mmc.h>
struct mxs_mxs_mmc_data {
+ const char *devid;
int id;
resource_size_t iobase;
resource_size_t dma;
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
+ #include <linux/module.h>
#include <linux/fsl/mxs-dma.h>
+ #include <linux/stmp_device.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
#include <asm/irq.h>
#include <mach/mxs.h>
- #include <mach/common.h>
#include "dmaengine.h"
* dma can program the controller registers of peripheral devices.
*/
- #define MXS_DMA_APBH 0
- #define MXS_DMA_APBX 1
- #define dma_is_apbh() (mxs_dma->dev_id == MXS_DMA_APBH)
-
- #define APBH_VERSION_LATEST 3
- #define apbh_is_old() (mxs_dma->version < APBH_VERSION_LATEST)
+ #define dma_is_apbh(mxs_dma) ((mxs_dma)->type == MXS_DMA_APBH)
+ #define apbh_is_old(mxs_dma) ((mxs_dma)->dev_id == IMX23_DMA)
#define HW_APBHX_CTRL0 0x000
#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
#define HW_APBHX_CTRL2 0x020
#define HW_APBHX_CHANNEL_CTRL 0x030
#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
- #define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800)
- #define HW_APBX_VERSION 0x800
- #define BP_APBHX_VERSION_MAJOR 24
- #define HW_APBHX_CHn_NXTCMDAR(n) \
- (((dma_is_apbh() && apbh_is_old()) ? 0x050 : 0x110) + (n) * 0x70)
- #define HW_APBHX_CHn_SEMA(n) \
- (((dma_is_apbh() && apbh_is_old()) ? 0x080 : 0x140) + (n) * 0x70)
+ /*
+ * The offset of NXTCMDAR register is different per both dma type and version,
+ * while stride for each channel is all the same 0x70.
+ */
+ #define HW_APBHX_CHn_NXTCMDAR(d, n) \
+ (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x050 : 0x110) + (n) * 0x70)
+ #define HW_APBHX_CHn_SEMA(d, n) \
+ (((dma_is_apbh(d) && apbh_is_old(d)) ? 0x080 : 0x140) + (n) * 0x70)
/*
* ccw bits definitions
#define MXS_DMA_CHANNELS 16
#define MXS_DMA_CHANNELS_MASK 0xffff
+ enum mxs_dma_devtype {
+ MXS_DMA_APBH,
+ MXS_DMA_APBX,
+ };
+
+ enum mxs_dma_id {
+ IMX23_DMA,
+ IMX28_DMA,
+ };
+
struct mxs_dma_engine {
- int dev_id;
- unsigned int version;
+ enum mxs_dma_id dev_id;
+ enum mxs_dma_devtype type;
void __iomem *base;
struct clk *clk;
struct dma_device dma_device;
struct mxs_dma_chan mxs_chans[MXS_DMA_CHANNELS];
};
+ struct mxs_dma_type {
+ enum mxs_dma_id id;
+ enum mxs_dma_devtype type;
+ };
+
+ static struct mxs_dma_type mxs_dma_types[] = {
+ {
+ .id = IMX23_DMA,
+ .type = MXS_DMA_APBH,
+ }, {
+ .id = IMX23_DMA,
+ .type = MXS_DMA_APBX,
+ }, {
+ .id = IMX28_DMA,
+ .type = MXS_DMA_APBH,
+ }, {
+ .id = IMX28_DMA,
+ .type = MXS_DMA_APBX,
+ }
+ };
+
+ static struct platform_device_id mxs_dma_ids[] = {
+ {
+ .name = "imx23-dma-apbh",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[0],
+ }, {
+ .name = "imx23-dma-apbx",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[1],
+ }, {
+ .name = "imx28-dma-apbh",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[2],
+ }, {
+ .name = "imx28-dma-apbx",
+ .driver_data = (kernel_ulong_t) &mxs_dma_types[3],
+ }, {
+ /* end of list */
+ }
+ };
+
+ static const struct of_device_id mxs_dma_dt_ids[] = {
+ { .compatible = "fsl,imx23-dma-apbh", .data = &mxs_dma_ids[0], },
+ { .compatible = "fsl,imx23-dma-apbx", .data = &mxs_dma_ids[1], },
+ { .compatible = "fsl,imx28-dma-apbh", .data = &mxs_dma_ids[2], },
+ { .compatible = "fsl,imx28-dma-apbx", .data = &mxs_dma_ids[3], },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mxs_dma_dt_ids);
+
+ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
+ {
+ return container_of(chan, struct mxs_dma_chan, chan);
+ }
+
+ int mxs_dma_is_apbh(struct dma_chan *chan)
+ {
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
+ struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+
+ return dma_is_apbh(mxs_dma);
+ }
+
+ int mxs_dma_is_apbx(struct dma_chan *chan)
+ {
+ struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
+ struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+
+ return !dma_is_apbh(mxs_dma);
+ }
+
static void mxs_dma_reset_chan(struct mxs_dma_chan *mxs_chan)
{
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
int chan_id = mxs_chan->chan.chan_id;
- if (dma_is_apbh() && apbh_is_old())
+ if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
writel(1 << (chan_id + BP_APBH_CTRL0_RESET_CHANNEL),
- mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
else
writel(1 << (chan_id + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL),
- mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
}
static void mxs_dma_enable_chan(struct mxs_dma_chan *mxs_chan)
/* set cmd_addr up */
writel(mxs_chan->ccw_phys,
- mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(chan_id));
+ mxs_dma->base + HW_APBHX_CHn_NXTCMDAR(mxs_dma, chan_id));
/* write 1 to SEMA to kick off the channel */
- writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(chan_id));
+ writel(1, mxs_dma->base + HW_APBHX_CHn_SEMA(mxs_dma, chan_id));
}
static void mxs_dma_disable_chan(struct mxs_dma_chan *mxs_chan)
int chan_id = mxs_chan->chan.chan_id;
/* freeze the channel */
- if (dma_is_apbh() && apbh_is_old())
+ if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
writel(1 << chan_id,
- mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
else
writel(1 << chan_id,
- mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_SET);
mxs_chan->status = DMA_PAUSED;
}
int chan_id = mxs_chan->chan.chan_id;
/* unfreeze the channel */
- if (dma_is_apbh() && apbh_is_old())
+ if (dma_is_apbh(mxs_dma) && apbh_is_old(mxs_dma))
writel(1 << chan_id,
- mxs_dma->base + HW_APBHX_CTRL0 + MXS_CLR_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_CLR);
else
writel(1 << chan_id,
- mxs_dma->base + HW_APBHX_CHANNEL_CTRL + MXS_CLR_ADDR);
+ mxs_dma->base + HW_APBHX_CHANNEL_CTRL + STMP_OFFSET_REG_CLR);
mxs_chan->status = DMA_IN_PROGRESS;
}
- static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
- {
- return container_of(chan, struct mxs_dma_chan, chan);
- }
-
static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx)
{
return dma_cookie_assign(tx);
/* completion status */
stat1 = readl(mxs_dma->base + HW_APBHX_CTRL1);
stat1 &= MXS_DMA_CHANNELS_MASK;
- writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + MXS_CLR_ADDR);
+ writel(stat1, mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_CLR);
/* error status */
stat2 = readl(mxs_dma->base + HW_APBHX_CTRL2);
- writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + MXS_CLR_ADDR);
+ writel(stat2, mxs_dma->base + HW_APBHX_CTRL2 + STMP_OFFSET_REG_CLR);
/*
* When both completion and error of termination bits set at the
ccw->bits |= BF_CCW(MXS_DMA_CMD_NO_XFER, COMMAND);
} else {
for_each_sg(sgl, sg, sg_len, i) {
- if (sg->length > MAX_XFER_BYTES) {
+ if (sg_dma_len(sg) > MAX_XFER_BYTES) {
dev_err(mxs_dma->dma_device.dev, "maximum bytes for sg entry exceeded: %d > %d\n",
- sg->length, MAX_XFER_BYTES);
+ sg_dma_len(sg), MAX_XFER_BYTES);
goto err_out;
}
ccw->next = mxs_chan->ccw_phys + sizeof(*ccw) * idx;
ccw->bufaddr = sg->dma_address;
- ccw->xfer_bytes = sg->length;
+ ccw->xfer_bytes = sg_dma_len(sg);
ccw->bits = 0;
ccw->bits |= CCW_CHAIN;
if (ret)
return ret;
- ret = mxs_reset_block(mxs_dma->base);
+ ret = stmp_reset_block(mxs_dma->base);
if (ret)
goto err_out;
- /* only major version matters */
- mxs_dma->version = readl(mxs_dma->base +
- ((mxs_dma->dev_id == MXS_DMA_APBX) ?
- HW_APBX_VERSION : HW_APBH_VERSION)) >>
- BP_APBHX_VERSION_MAJOR;
-
/* enable apbh burst */
- if (dma_is_apbh()) {
+ if (dma_is_apbh(mxs_dma)) {
writel(BM_APBH_CTRL0_APB_BURST_EN,
- mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
writel(BM_APBH_CTRL0_APB_BURST8_EN,
- mxs_dma->base + HW_APBHX_CTRL0 + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL0 + STMP_OFFSET_REG_SET);
}
/* enable irq for all the channels */
writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
- mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR);
+ mxs_dma->base + HW_APBHX_CTRL1 + STMP_OFFSET_REG_SET);
err_out:
clk_disable_unprepare(mxs_dma->clk);
static int __init mxs_dma_probe(struct platform_device *pdev)
{
- const struct platform_device_id *id_entry =
- platform_get_device_id(pdev);
+ const struct platform_device_id *id_entry;
+ const struct of_device_id *of_id;
+ const struct mxs_dma_type *dma_type;
struct mxs_dma_engine *mxs_dma;
struct resource *iores;
int ret, i;
if (!mxs_dma)
return -ENOMEM;
- mxs_dma->dev_id = id_entry->driver_data;
+ of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
+ if (of_id)
+ id_entry = of_id->data;
+ else
+ id_entry = platform_get_device_id(pdev);
+
+ dma_type = (struct mxs_dma_type *)id_entry->driver_data;
+ mxs_dma->type = dma_type->type;
+ mxs_dma->dev_id = dma_type->id;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
return ret;
}
- static struct platform_device_id mxs_dma_type[] = {
- {
- .name = "mxs-dma-apbh",
- .driver_data = MXS_DMA_APBH,
- }, {
- .name = "mxs-dma-apbx",
- .driver_data = MXS_DMA_APBX,
- }, {
- /* end of list */
- }
- };
-
static struct platform_driver mxs_dma_driver = {
.driver = {
.name = "mxs-dma",
+ .of_match_table = mxs_dma_dt_ids,
},
- .id_table = mxs_dma_type,
+ .id_table = mxs_dma_ids,
};
static int __init mxs_dma_module_init(void)
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/gpio.h>
+ #include <linux/of.h>
+ #include <linux/of_address.h>
+ #include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/module.h>
- #include <mach/mxs.h>
#define MXS_SET 0x4
#define MXS_CLR 0x8
- #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 PINCTRL_DOUT(p) ((is_imx23_gpio(p) ? 0x0500 : 0x0700) + (p->id) * 0x10)
+ #define PINCTRL_DIN(p) ((is_imx23_gpio(p) ? 0x0600 : 0x0900) + (p->id) * 0x10)
+ #define PINCTRL_DOE(p) ((is_imx23_gpio(p) ? 0x0700 : 0x0b00) + (p->id) * 0x10)
+ #define PINCTRL_PIN2IRQ(p) ((is_imx23_gpio(p) ? 0x0800 : 0x1000) + (p->id) * 0x10)
+ #define PINCTRL_IRQEN(p) ((is_imx23_gpio(p) ? 0x0900 : 0x1100) + (p->id) * 0x10)
+ #define PINCTRL_IRQLEV(p) ((is_imx23_gpio(p) ? 0x0a00 : 0x1200) + (p->id) * 0x10)
+ #define PINCTRL_IRQPOL(p) ((is_imx23_gpio(p) ? 0x0b00 : 0x1300) + (p->id) * 0x10)
+ #define PINCTRL_IRQSTAT(p) ((is_imx23_gpio(p) ? 0x0c00 : 0x1400) + (p->id) * 0x10)
#define GPIO_INT_FALL_EDGE 0x0
#define GPIO_INT_LOW_LEV 0x1
#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+ enum mxs_gpio_id {
+ IMX23_GPIO,
+ IMX28_GPIO,
+ };
+
struct mxs_gpio_port {
void __iomem *base;
int id;
int irq;
int virtual_irq_start;
struct bgpio_chip bgc;
+ enum mxs_gpio_id devid;
};
+ static inline int is_imx23_gpio(struct mxs_gpio_port *port)
+ {
+ return port->devid == IMX23_GPIO;
+ }
+
+ static inline int is_imx28_gpio(struct mxs_gpio_port *port)
+ {
+ return port->devid == IMX28_GPIO;
+ }
+
/* Note: This driver assumes 32 GPIOs are handled in one register */
static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
}
/* set level or edge */
- pin_addr = port->base + PINCTRL_IRQLEV(port->id);
+ pin_addr = port->base + PINCTRL_IRQLEV(port);
if (edge & GPIO_INT_LEV_MASK)
writel(pin_mask, pin_addr + MXS_SET);
else
writel(pin_mask, pin_addr + MXS_CLR);
/* set polarity */
- pin_addr = port->base + PINCTRL_IRQPOL(port->id);
+ pin_addr = port->base + PINCTRL_IRQPOL(port);
if (edge & GPIO_INT_POL_MASK)
writel(pin_mask, pin_addr + MXS_SET);
else
writel(pin_mask, pin_addr + MXS_CLR);
writel(1 << (gpio & 0x1f),
- port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
+ port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
return 0;
}
desc->irq_data.chip->irq_ack(&desc->irq_data);
- irq_stat = readl(port->base + PINCTRL_IRQSTAT(port->id)) &
- readl(port->base + PINCTRL_IRQEN(port->id));
+ irq_stat = readl(port->base + PINCTRL_IRQSTAT(port)) &
+ readl(port->base + PINCTRL_IRQEN(port));
while (irq_stat != 0) {
int irqoffset = fls(irq_stat) - 1;
ct->chip.irq_unmask = irq_gc_mask_set_bit;
ct->chip.irq_set_type = mxs_gpio_set_irq_type;
ct->chip.irq_set_wake = mxs_gpio_set_wake_irq;
- ct->regs.ack = PINCTRL_IRQSTAT(port->id) + MXS_CLR;
- ct->regs.mask = PINCTRL_IRQEN(port->id);
+ ct->regs.ack = PINCTRL_IRQSTAT(port) + MXS_CLR;
+ ct->regs.mask = PINCTRL_IRQEN(port);
irq_setup_generic_chip(gc, IRQ_MSK(32), 0, IRQ_NOREQUEST, 0);
}
return port->virtual_irq_start + offset;
}
+ static struct platform_device_id mxs_gpio_ids[] = {
+ {
+ .name = "imx23-gpio",
+ .driver_data = IMX23_GPIO,
+ }, {
+ .name = "imx28-gpio",
+ .driver_data = IMX28_GPIO,
+ }, {
+ /* sentinel */
+ }
+ };
+ MODULE_DEVICE_TABLE(platform, mxs_gpio_ids);
+
+ static const struct of_device_id mxs_gpio_dt_ids[] = {
+ { .compatible = "fsl,imx23-gpio", .data = (void *) IMX23_GPIO, },
+ { .compatible = "fsl,imx28-gpio", .data = (void *) IMX28_GPIO, },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mxs_gpio_dt_ids);
+
static int __devinit mxs_gpio_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id =
+ of_match_device(mxs_gpio_dt_ids, &pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *parent;
static void __iomem *base;
struct mxs_gpio_port *port;
struct resource *iores = NULL;
int err;
- port = kzalloc(sizeof(struct mxs_gpio_port), GFP_KERNEL);
+ port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
- port->id = pdev->id;
+ if (np) {
+ port->id = of_alias_get_id(np, "gpio");
+ if (port->id < 0)
+ return port->id;
+ port->devid = (enum mxs_gpio_id) of_id->data;
+ } else {
+ port->id = pdev->id;
+ port->devid = pdev->id_entry->driver_data;
+ }
port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
+ port->irq = platform_get_irq(pdev, 0);
+ if (port->irq < 0)
+ return port->irq;
+
/*
* map memory region only once, as all the gpio ports
* share the same one
*/
if (!base) {
- iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!iores) {
- err = -ENODEV;
- goto out_kfree;
- }
-
- if (!request_mem_region(iores->start, resource_size(iores),
- pdev->name)) {
- err = -EBUSY;
- goto out_kfree;
- }
-
- base = ioremap(iores->start, resource_size(iores));
- if (!base) {
- err = -ENOMEM;
- goto out_release_mem;
+ if (np) {
+ parent = of_get_parent(np);
+ base = of_iomap(parent, 0);
+ of_node_put(parent);
+ } else {
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_request_and_ioremap(&pdev->dev, iores);
}
+ if (!base)
+ return -EADDRNOTAVAIL;
}
port->base = base;
- port->irq = platform_get_irq(pdev, 0);
- if (port->irq < 0) {
- err = -EINVAL;
- goto out_iounmap;
- }
-
/*
* select the pin interrupt functionality but initially
* disable the interrupts
*/
- writel(~0U, port->base + PINCTRL_PIN2IRQ(port->id));
- writel(0, port->base + PINCTRL_IRQEN(port->id));
+ writel(~0U, port->base + PINCTRL_PIN2IRQ(port));
+ writel(0, port->base + PINCTRL_IRQEN(port));
/* clear address has to be used to clear IRQSTAT bits */
- writel(~0U, port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR);
+ writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
/* gpio-mxs can be a generic irq chip */
mxs_gpio_init_gc(port);
irq_set_handler_data(port->irq, port);
err = bgpio_init(&port->bgc, &pdev->dev, 4,
- port->base + PINCTRL_DIN(port->id),
- port->base + PINCTRL_DOUT(port->id), NULL,
- port->base + PINCTRL_DOE(port->id), NULL, 0);
+ port->base + PINCTRL_DIN(port),
+ port->base + PINCTRL_DOUT(port), NULL,
- port->base + PINCTRL_DOE(port), NULL, false);
++ port->base + PINCTRL_DOE(port), NULL, 0);
if (err)
- goto out_iounmap;
+ return err;
port->bgc.gc.to_irq = mxs_gpio_to_irq;
port->bgc.gc.base = port->id * 32;
err = gpiochip_add(&port->bgc.gc);
- if (err)
- goto out_bgpio_remove;
+ if (err) {
+ bgpio_remove(&port->bgc);
+ return err;
+ }
return 0;
-
- out_bgpio_remove:
- bgpio_remove(&port->bgc);
- out_iounmap:
- if (iores)
- iounmap(port->base);
- out_release_mem:
- if (iores)
- release_mem_region(iores->start, resource_size(iores));
- out_kfree:
- kfree(port);
- dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, err);
- return err;
}
static struct platform_driver mxs_gpio_driver = {
.driver = {
.name = "gpio-mxs",
.owner = THIS_MODULE,
+ .of_match_table = mxs_gpio_dt_ids,
},
.probe = mxs_gpio_probe,
+ .id_table = mxs_gpio_ids,
};
static int __init mxs_gpio_init(void)
#include <linux/jiffies.h>
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/stmp_device.h>
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/of_i2c.h>
-#include <mach/common.h>
-
#define DRIVER_NAME "mxs-i2c"
#define MXS_I2C_CTRL0 (0x00)
struct i2c_adapter adapter;
};
-/*
- * TODO: check if calls to here are really needed. If not, we could get rid of
- * mxs_reset_block and the mach-dependency. Needs an I2C analyzer, probably.
- */
static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
{
- mxs_reset_block(i2c->regs);
+ stmp_reset_block(i2c->regs);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
i2c->regs + MXS_I2C_QUEUECTRL_SET);
adap->algo = &mxs_i2c_algo;
adap->dev.parent = dev;
adap->nr = pdev->id;
+ adap->dev.of_node = pdev->dev.of_node;
i2c_set_adapdata(adap, i2c);
err = i2c_add_numbered_adapter(adap);
if (err) {
return err;
}
+ of_i2c_register_devices(adap);
+
return 0;
}
return 0;
}
+ static const struct of_device_id mxs_i2c_dt_ids[] = {
+ { .compatible = "fsl,imx28-i2c", },
+ { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, mxs_i2c_dt_ids);
+
static struct platform_driver mxs_i2c_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
+ .of_match_table = mxs_i2c_dt_ids,
},
.remove = __devexit_p(mxs_i2c_remove),
};