summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/imx-dma.c137
-rw-r--r--drivers/dma/imx-sdma.c1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c3
-rw-r--r--drivers/dma/ipu/ipu_irq.c3
-rw-r--r--drivers/i2c/busses/i2c-imx.c40
-rw-r--r--drivers/irqchip/Kconfig9
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-versatile-fpga.c204
-rw-r--r--drivers/media/platform/soc_camera/mx2_camera.c134
-rw-r--r--drivers/media/platform/soc_camera/mx3_camera.c2
-rw-r--r--drivers/mmc/host/mxcmmc.c31
-rw-r--r--drivers/mtd/nand/mxc_nand.c96
-rw-r--r--drivers/rtc/rtc-mxc.c34
-rw-r--r--drivers/sh/clk/cpg.c86
-rw-r--r--drivers/uio/Kconfig1
-rw-r--r--drivers/uio/uio_pruss.c24
-rw-r--r--drivers/usb/host/ehci-mxc.c1
-rw-r--r--drivers/video/imxfb.c38
-rw-r--r--drivers/video/mx3fb.c3
-rw-r--r--drivers/watchdog/imx2_wdt.c1
20 files changed, 688 insertions, 161 deletions
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 7d9554cc4976..dbf0e6f8de8a 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
#include "dmaengine.h"
#define IMXDMA_MAX_CHAN_DESCRIPTORS 16
@@ -167,6 +166,12 @@ struct imxdma_channel {
int slot_2d;
};
+enum imx_dma_type {
+ IMX1_DMA,
+ IMX21_DMA,
+ IMX27_DMA,
+};
+
struct imxdma_engine {
struct device *dev;
struct device_dma_parameters dma_parms;
@@ -177,7 +182,39 @@ struct imxdma_engine {
spinlock_t lock;
struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS];
struct imxdma_channel channel[IMX_DMA_CHANNELS];
+ enum imx_dma_type devtype;
+};
+
+static struct platform_device_id imx_dma_devtype[] = {
+ {
+ .name = "imx1-dma",
+ .driver_data = IMX1_DMA,
+ }, {
+ .name = "imx21-dma",
+ .driver_data = IMX21_DMA,
+ }, {
+ .name = "imx27-dma",
+ .driver_data = IMX27_DMA,
+ }, {
+ /* sentinel */
+ }
};
+MODULE_DEVICE_TABLE(platform, imx_dma_devtype);
+
+static inline int is_imx1_dma(struct imxdma_engine *imxdma)
+{
+ return imxdma->devtype == IMX1_DMA;
+}
+
+static inline int is_imx21_dma(struct imxdma_engine *imxdma)
+{
+ return imxdma->devtype == IMX21_DMA;
+}
+
+static inline int is_imx27_dma(struct imxdma_engine *imxdma)
+{
+ return imxdma->devtype == IMX27_DMA;
+}
static struct imxdma_channel *to_imxdma_chan(struct dma_chan *chan)
{
@@ -212,7 +249,9 @@ static unsigned imx_dmav1_readl(struct imxdma_engine *imxdma, unsigned offset)
static int imxdma_hw_chain(struct imxdma_channel *imxdmac)
{
- if (cpu_is_mx27())
+ struct imxdma_engine *imxdma = imxdmac->imxdma;
+
+ if (is_imx27_dma(imxdma))
return imxdmac->hw_chaining;
else
return 0;
@@ -267,7 +306,7 @@ static void imxdma_enable_hw(struct imxdma_desc *d)
imx_dmav1_writel(imxdma, imx_dmav1_readl(imxdma, DMA_CCR(channel)) |
CCR_CEN | CCR_ACRPT, DMA_CCR(channel));
- if ((cpu_is_mx21() || cpu_is_mx27()) &&
+ if (!is_imx1_dma(imxdma) &&
d->sg && imxdma_hw_chain(imxdmac)) {
d->sg = sg_next(d->sg);
if (d->sg) {
@@ -436,7 +475,7 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id)
struct imxdma_engine *imxdma = dev_id;
int i, disr;
- if (cpu_is_mx21() || cpu_is_mx27())
+ if (!is_imx1_dma(imxdma))
imxdma_err_handler(irq, dev_id);
disr = imx_dmav1_readl(imxdma, DMA_DISR);
@@ -961,35 +1000,32 @@ static void imxdma_issue_pending(struct dma_chan *chan)
static int __init imxdma_probe(struct platform_device *pdev)
{
struct imxdma_engine *imxdma;
+ struct resource *res;
int ret, i;
+ int irq, irq_err;
-
- imxdma = kzalloc(sizeof(*imxdma), GFP_KERNEL);
+ imxdma = devm_kzalloc(&pdev->dev, sizeof(*imxdma), GFP_KERNEL);
if (!imxdma)
return -ENOMEM;
- if (cpu_is_mx1()) {
- imxdma->base = MX1_IO_ADDRESS(MX1_DMA_BASE_ADDR);
- } else if (cpu_is_mx21()) {
- imxdma->base = MX21_IO_ADDRESS(MX21_DMA_BASE_ADDR);
- } else if (cpu_is_mx27()) {
- imxdma->base = MX27_IO_ADDRESS(MX27_DMA_BASE_ADDR);
- } else {
- kfree(imxdma);
- return 0;
- }
+ imxdma->devtype = pdev->id_entry->driver_data;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ imxdma->base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!imxdma->base)
+ return -EADDRNOTAVAIL;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(imxdma->dma_ipg)) {
- ret = PTR_ERR(imxdma->dma_ipg);
- goto err_clk;
- }
+ if (IS_ERR(imxdma->dma_ipg))
+ return PTR_ERR(imxdma->dma_ipg);
imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb");
- if (IS_ERR(imxdma->dma_ahb)) {
- ret = PTR_ERR(imxdma->dma_ahb);
- goto err_clk;
- }
+ if (IS_ERR(imxdma->dma_ahb))
+ return PTR_ERR(imxdma->dma_ahb);
clk_prepare_enable(imxdma->dma_ipg);
clk_prepare_enable(imxdma->dma_ahb);
@@ -997,18 +1033,25 @@ static int __init imxdma_probe(struct platform_device *pdev)
/* reset DMA module */
imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR);
- if (cpu_is_mx1()) {
- ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma);
+ if (is_imx1_dma(imxdma)) {
+ ret = devm_request_irq(&pdev->dev, irq,
+ dma_irq_handler, 0, "DMA", imxdma);
if (ret) {
dev_warn(imxdma->dev, "Can't register IRQ for DMA\n");
- goto err_enable;
+ goto err;
+ }
+
+ irq_err = platform_get_irq(pdev, 1);
+ if (irq_err < 0) {
+ ret = irq_err;
+ goto err;
}
- ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma);
+ ret = devm_request_irq(&pdev->dev, irq_err,
+ imxdma_err_handler, 0, "DMA", imxdma);
if (ret) {
dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n");
- free_irq(MX1_DMA_INT, NULL);
- goto err_enable;
+ goto err;
}
}
@@ -1038,14 +1081,14 @@ static int __init imxdma_probe(struct platform_device *pdev)
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
struct imxdma_channel *imxdmac = &imxdma->channel[i];
- if (cpu_is_mx21() || cpu_is_mx27()) {
- ret = request_irq(MX2x_INT_DMACH0 + i,
+ if (!is_imx1_dma(imxdma)) {
+ ret = devm_request_irq(&pdev->dev, irq + i,
dma_irq_handler, 0, "DMA", imxdma);
if (ret) {
dev_warn(imxdma->dev, "Can't register IRQ %d "
"for DMA channel %d\n",
- MX2x_INT_DMACH0 + i, i);
- goto err_init;
+ irq + i, i);
+ goto err;
}
init_timer(&imxdmac->watchdog);
imxdmac->watchdog.function = &imxdma_watchdog;
@@ -1091,46 +1134,25 @@ static int __init imxdma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&imxdma->dma_device);
if (ret) {
dev_err(&pdev->dev, "unable to register\n");
- goto err_init;
+ goto err;
}
return 0;
-err_init:
-
- if (cpu_is_mx21() || cpu_is_mx27()) {
- while (--i >= 0)
- free_irq(MX2x_INT_DMACH0 + i, NULL);
- } else if cpu_is_mx1() {
- free_irq(MX1_DMA_INT, NULL);
- free_irq(MX1_DMA_ERR, NULL);
- }
-err_enable:
+err:
clk_disable_unprepare(imxdma->dma_ipg);
clk_disable_unprepare(imxdma->dma_ahb);
-err_clk:
- kfree(imxdma);
return ret;
}
static int __exit imxdma_remove(struct platform_device *pdev)
{
struct imxdma_engine *imxdma = platform_get_drvdata(pdev);
- int i;
dma_async_device_unregister(&imxdma->dma_device);
- if (cpu_is_mx21() || cpu_is_mx27()) {
- for (i = 0; i < IMX_DMA_CHANNELS; i++)
- free_irq(MX2x_INT_DMACH0 + i, NULL);
- } else if cpu_is_mx1() {
- free_irq(MX1_DMA_INT, NULL);
- free_irq(MX1_DMA_ERR, NULL);
- }
-
clk_disable_unprepare(imxdma->dma_ipg);
clk_disable_unprepare(imxdma->dma_ahb);
- kfree(imxdma);
return 0;
}
@@ -1139,6 +1161,7 @@ static struct platform_driver imxdma_driver = {
.driver = {
.name = "imx-dma",
},
+ .id_table = imx_dma_devtype,
.remove = __exit_p(imxdma_remove),
};
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index c099ca0846f4..f082aa3a918c 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -40,7 +40,6 @@
#include <asm/irq.h>
#include <linux/platform_data/dma-imx-sdma.h>
#include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
#include "dmaengine.h"
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index c7573e50aa14..65855373cee6 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -22,8 +22,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
-
-#include <mach/ipu.h>
+#include <linux/dma/ipu-dma.h>
#include "../dmaengine.h"
#include "ipu_intern.h"
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index fa95bcc3de1f..a5ee37d5320f 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -15,8 +15,7 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/module.h>
-
-#include <mach/ipu.h>
+#include <linux/dma/ipu-dma.h>
#include "ipu_intern.h"
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 2ef162d148cb..b9734747d610 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -52,8 +52,6 @@
#include <linux/of_device.h>
#include <linux/of_i2c.h>
#include <linux/pinctrl/consumer.h>
-
-#include <mach/hardware.h>
#include <linux/platform_data/i2c-imx.h>
/** Defines ********************************************************************
@@ -115,6 +113,11 @@ static u16 __initdata i2c_clk_div[50][2] = {
{ 3072, 0x1E }, { 3840, 0x1F }
};
+enum imx_i2c_type {
+ IMX1_I2C,
+ IMX21_I2C,
+};
+
struct imx_i2c_struct {
struct i2c_adapter adapter;
struct clk *clk;
@@ -124,13 +127,33 @@ struct imx_i2c_struct {
unsigned int disable_delay;
int stopped;
unsigned int ifdr; /* IMX_I2C_IFDR */
+ enum imx_i2c_type devtype;
+};
+
+static struct platform_device_id imx_i2c_devtype[] = {
+ {
+ .name = "imx1-i2c",
+ .driver_data = IMX1_I2C,
+ }, {
+ .name = "imx21-i2c",
+ .driver_data = IMX21_I2C,
+ }, {
+ /* sentinel */
+ }
};
+MODULE_DEVICE_TABLE(platform, imx_i2c_devtype);
static const struct of_device_id i2c_imx_dt_ids[] = {
- { .compatible = "fsl,imx1-i2c", },
+ { .compatible = "fsl,imx1-i2c", .data = &imx_i2c_devtype[IMX1_I2C], },
+ { .compatible = "fsl,imx21-i2c", .data = &imx_i2c_devtype[IMX21_I2C], },
{ /* sentinel */ }
};
+static inline int is_imx1_i2c(struct imx_i2c_struct *i2c_imx)
+{
+ return i2c_imx->devtype == IMX1_I2C;
+}
+
/** Functions for IMX I2C adapter driver ***************************************
*******************************************************************************/
@@ -223,7 +246,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
temp &= ~(I2CR_MSTA | I2CR_MTX);
writeb(temp, i2c_imx->base + IMX_I2C_I2CR);
}
- if (cpu_is_mx1()) {
+ if (is_imx1_i2c(i2c_imx)) {
/*
* This delay caused by an i.MXL hardware bug.
* If no (or too short) delay, no "STOP" bit will be generated.
@@ -465,6 +488,8 @@ static struct i2c_algorithm i2c_imx_algo = {
static int __init i2c_imx_probe(struct platform_device *pdev)
{
+ const struct of_device_id *of_id = of_match_device(i2c_imx_dt_ids,
+ &pdev->dev);
struct imx_i2c_struct *i2c_imx;
struct resource *res;
struct imxi2c_platform_data *pdata = pdev->dev.platform_data;
@@ -497,6 +522,10 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ if (of_id)
+ pdev->id_entry = of_id->data;
+ i2c_imx->devtype = pdev->id_entry->driver_data;
+
/* Setup i2c_imx driver structure */
strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));
i2c_imx->adapter.owner = THIS_MODULE;
@@ -593,7 +622,8 @@ static struct platform_driver i2c_imx_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = i2c_imx_dt_ids,
- }
+ },
+ .id_table = imx_i2c_devtype,
};
static int __init i2c_adap_imx_init(void)
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 1bb8bf6d7fd4..62ca575701d3 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -1 +1,8 @@
-# empty
+config VERSATILE_FPGA_IRQ
+ bool
+ select IRQ_DOMAIN
+
+config VERSATILE_FPGA_IRQ_NR
+ int
+ default 4
+ depends on VERSATILE_FPGA_IRQ
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 2444d07544cd..02bd37a6187f 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi.o
+obj-$(CONFIG_VERSATILE_FPGA_IRQ) += irq-versatile-fpga.o
diff --git a/drivers/irqchip/irq-versatile-fpga.c b/drivers/irqchip/irq-versatile-fpga.c
new file mode 100644
index 000000000000..789b3e526930
--- /dev/null
+++ b/drivers/irqchip/irq-versatile-fpga.c
@@ -0,0 +1,204 @@
+/*
+ * Support for Versatile FPGA-based IRQ controllers
+ */
+#include <linux/bitops.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/irqchip/versatile-fpga.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#define IRQ_STATUS 0x00
+#define IRQ_RAW_STATUS 0x04
+#define IRQ_ENABLE_SET 0x08
+#define IRQ_ENABLE_CLEAR 0x0c
+#define INT_SOFT_SET 0x10
+#define INT_SOFT_CLEAR 0x14
+#define FIQ_STATUS 0x20
+#define FIQ_RAW_STATUS 0x24
+#define FIQ_ENABLE 0x28
+#define FIQ_ENABLE_SET 0x28
+#define FIQ_ENABLE_CLEAR 0x2C
+
+/**
+ * struct fpga_irq_data - irq data container for the FPGA IRQ controller
+ * @base: memory offset in virtual memory
+ * @chip: chip container for this instance
+ * @domain: IRQ domain for this instance
+ * @valid: mask for valid IRQs on this controller
+ * @used_irqs: number of active IRQs on this controller
+ */
+struct fpga_irq_data {
+ void __iomem *base;
+ struct irq_chip chip;
+ u32 valid;
+ struct irq_domain *domain;
+ u8 used_irqs;
+};
+
+/* we cannot allocate memory when the controllers are initially registered */
+static struct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR];
+static int fpga_irq_id;
+
+static void fpga_irq_mask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << d->hwirq;
+
+ writel(mask, f->base + IRQ_ENABLE_CLEAR);
+}
+
+static void fpga_irq_unmask(struct irq_data *d)
+{
+ struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
+ u32 mask = 1 << d->hwirq;
+
+ writel(mask, f->base + IRQ_ENABLE_SET);
+}
+
+static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
+{
+ struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
+ u32 status = readl(f->base + IRQ_STATUS);
+
+ if (status == 0) {
+ do_bad_IRQ(irq, desc);
+ return;
+ }
+
+ do {
+ irq = ffs(status) - 1;
+ status &= ~(1 << irq);
+ generic_handle_irq(irq_find_mapping(f->domain, irq));
+ } while (status);
+}
+
+/*
+ * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero
+ * if we've handled at least one interrupt. This does a single read of the
+ * status register and handles all interrupts in order from LSB first.
+ */
+static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
+{
+ int handled = 0;
+ int irq;
+ u32 status;
+
+ while ((status = readl(f->base + IRQ_STATUS))) {
+ irq = ffs(status) - 1;
+ handle_IRQ(irq_find_mapping(f->domain, irq), regs);
+ handled = 1;
+ }
+
+ return handled;
+}
+
+/*
+ * Keep iterating over all registered FPGA IRQ controllers until there are
+ * no pending interrupts.
+ */
+asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
+{
+ int i, handled;
+
+ do {
+ for (i = 0, handled = 0; i < fpga_irq_id; ++i)
+ handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
+ } while (handled);
+}
+
+static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ struct fpga_irq_data *f = d->host_data;
+
+ /* Skip invalid IRQs, only register handlers for the real ones */
+ if (!(f->valid & BIT(hwirq)))
+ return -ENOTSUPP;
+ irq_set_chip_data(irq, f);
+ irq_set_chip_and_handler(irq, &f->chip,
+ handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ return 0;
+}
+
+static struct irq_domain_ops fpga_irqdomain_ops = {
+ .map = fpga_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start,
+ int parent_irq, u32 valid, struct device_node *node)
+{
+ struct fpga_irq_data *f;
+ int i;
+
+ if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
+ pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__);
+ return;
+ }
+ f = &fpga_irq_devices[fpga_irq_id];
+ f->base = base;
+ f->chip.name = name;
+ f->chip.irq_ack = fpga_irq_mask;
+ f->chip.irq_mask = fpga_irq_mask;
+ f->chip.irq_unmask = fpga_irq_unmask;
+ f->valid = valid;
+
+ if (parent_irq != -1) {
+ irq_set_handler_data(parent_irq, f);
+ irq_set_chained_handler(parent_irq, fpga_irq_handle);
+ }
+
+ /* This will also allocate irq descriptors */
+ f->domain = irq_domain_add_simple(node, fls(valid), irq_start,
+ &fpga_irqdomain_ops, f);
+
+ /* This will allocate all valid descriptors in the linear case */
+ for (i = 0; i < fls(valid); i++)
+ if (valid & BIT(i)) {
+ if (!irq_start)
+ irq_create_mapping(f->domain, i);
+ f->used_irqs++;
+ }
+
+ pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",
+ fpga_irq_id, name, base, f->used_irqs);
+
+ fpga_irq_id++;
+}
+
+#ifdef CONFIG_OF
+int __init fpga_irq_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ struct fpga_irq_data *f;
+ void __iomem *base;
+ u32 clear_mask;
+ u32 valid_mask;
+
+ if (WARN_ON(!node))
+ return -ENODEV;
+
+ base = of_iomap(node, 0);
+ WARN(!base, "unable to map fpga irq registers\n");
+
+ if (of_property_read_u32(node, "clear-mask", &clear_mask))
+ clear_mask = 0;
+
+ if (of_property_read_u32(node, "valid-mask", &valid_mask))
+ valid_mask = 0;
+
+ fpga_irq_init(base, node->name, 0, -1, valid_mask, node);
+
+ writel(clear_mask, base + IRQ_ENABLE_CLEAR);
+ writel(clear_mask, base + FIQ_ENABLE_CLEAR);
+
+ return 0;
+}
+#endif
diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index 9fd9d1c5b218..558f6a3e510d 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -41,7 +41,6 @@
#include <linux/videodev2.h>
#include <linux/platform_data/camera-mx2.h>
-#include <mach/hardware.h>
#include <asm/dma.h>
@@ -121,11 +120,13 @@
#define CSICR1 0x00
#define CSICR2 0x04
-#define CSISR (cpu_is_mx27() ? 0x08 : 0x18)
+#define CSISR_IMX25 0x18
+#define CSISR_IMX27 0x08
#define CSISTATFIFO 0x0c
#define CSIRFIFO 0x10
#define CSIRXCNT 0x14
-#define CSICR3 (cpu_is_mx27() ? 0x1C : 0x08)
+#define CSICR3_IMX25 0x08
+#define CSICR3_IMX27 0x1c
#define CSIDMASA_STATFIFO 0x20
#define CSIDMATA_STATFIFO 0x24
#define CSIDMASA_FB1 0x28
@@ -268,11 +269,17 @@ struct mx2_buffer {
struct mx2_buf_internal internal;
};
+enum mx2_camera_type {
+ IMX25_CAMERA,
+ IMX27_CAMERA,
+};
+
struct mx2_camera_dev {
struct device *dev;
struct soc_camera_host soc_host;
struct soc_camera_device *icd;
- struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+ struct clk *clk_emma_ahb, *clk_emma_ipg;
+ struct clk *clk_csi_ahb, *clk_csi_per;
void __iomem *base_csi, *base_emma;
@@ -291,6 +298,9 @@ struct mx2_camera_dev {
struct mx2_buffer *fb2_active;
u32 csicr1;
+ u32 reg_csisr;
+ u32 reg_csicr3;
+ enum mx2_camera_type devtype;
struct mx2_buf_internal buf_discard[2];
void *discard_buffer;
@@ -303,6 +313,29 @@ struct mx2_camera_dev {
struct vb2_alloc_ctx *alloc_ctx;
};
+static struct platform_device_id mx2_camera_devtype[] = {
+ {
+ .name = "imx25-camera",
+ .driver_data = IMX25_CAMERA,
+ }, {
+ .name = "imx27-camera",
+ .driver_data = IMX27_CAMERA,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, mx2_camera_devtype);
+
+static inline int is_imx25_camera(struct mx2_camera_dev *pcdev)
+{
+ return pcdev->devtype == IMX25_CAMERA;
+}
+
+static inline int is_imx27_camera(struct mx2_camera_dev *pcdev)
+{
+ return pcdev->devtype == IMX27_CAMERA;
+}
+
static struct mx2_buffer *mx2_ibuf_to_buf(struct mx2_buf_internal *int_buf)
{
return container_of(int_buf, struct mx2_buffer, internal);
@@ -432,11 +465,12 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
{
unsigned long flags;
- clk_disable_unprepare(pcdev->clk_csi);
+ clk_disable_unprepare(pcdev->clk_csi_ahb);
+ clk_disable_unprepare(pcdev->clk_csi_per);
writel(0, pcdev->base_csi + CSICR1);
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
writel(0, pcdev->base_emma + PRP_CNTL);
- } else if (cpu_is_mx25()) {
+ } else if (is_imx25_camera(pcdev)) {
spin_lock_irqsave(&pcdev->lock, flags);
pcdev->fb1_active = NULL;
pcdev->fb2_active = NULL;
@@ -460,13 +494,17 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
if (pcdev->icd)
return -EBUSY;
- ret = clk_prepare_enable(pcdev->clk_csi);
+ ret = clk_prepare_enable(pcdev->clk_csi_ahb);
if (ret < 0)
return ret;
+ ret = clk_prepare_enable(pcdev->clk_csi_per);
+ if (ret < 0)
+ goto exit_csi_ahb;
+
csicr1 = CSICR1_MCLKEN;
- if (cpu_is_mx27())
+ if (is_imx27_camera(pcdev))
csicr1 |= CSICR1_PRP_IF_EN | CSICR1_FCC |
CSICR1_RXFF_LEVEL(0);
@@ -480,6 +518,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
icd->devnum);
return 0;
+
+exit_csi_ahb:
+ clk_disable_unprepare(pcdev->clk_csi_ahb);
+
+ return ret;
}
static void mx2_camera_remove_device(struct soc_camera_device *icd)
@@ -542,7 +585,7 @@ out:
static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
{
struct mx2_camera_dev *pcdev = data;
- u32 status = readl(pcdev->base_csi + CSISR);
+ u32 status = readl(pcdev->base_csi + pcdev->reg_csisr);
if (status & CSISR_DMA_TSF_FB1_INT)
mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
@@ -551,7 +594,7 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
/* FIXME: handle CSISR_RFF_OR_INT */
- writel(status, pcdev->base_csi + CSISR);
+ writel(status, pcdev->base_csi + pcdev->reg_csisr);
return IRQ_HANDLED;
}
@@ -636,7 +679,7 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
buf->state = MX2_STATE_QUEUED;
list_add_tail(&buf->internal.queue, &pcdev->capture);
- if (cpu_is_mx25()) {
+ if (is_imx25_camera(pcdev)) {
u32 csicr3, dma_inten = 0;
if (pcdev->fb1_active == NULL) {
@@ -655,20 +698,20 @@ static void mx2_videobuf_queue(struct vb2_buffer *vb)
list_del(&buf->internal.queue);
buf->state = MX2_STATE_ACTIVE;
- csicr3 = readl(pcdev->base_csi + CSICR3);
+ csicr3 = readl(pcdev->base_csi + pcdev->reg_csicr3);
/* Reflash DMA */
writel(csicr3 | CSICR3_DMA_REFLASH_RFF,
- pcdev->base_csi + CSICR3);
+ pcdev->base_csi + pcdev->reg_csicr3);
/* clear & enable interrupts */
- writel(dma_inten, pcdev->base_csi + CSISR);
+ writel(dma_inten, pcdev->base_csi + pcdev->reg_csisr);
pcdev->csicr1 |= dma_inten;
writel(pcdev->csicr1, pcdev->base_csi + CSICR1);
/* enable DMA */
csicr3 |= CSICR3_DMA_REQ_EN_RFF | CSICR3_RXFF_LEVEL(1);
- writel(csicr3, pcdev->base_csi + CSICR3);
+ writel(csicr3, pcdev->base_csi + pcdev->reg_csicr3);
}
}
@@ -712,7 +755,7 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
*/
spin_lock_irqsave(&pcdev->lock, flags);
- if (cpu_is_mx25() && buf->state == MX2_STATE_ACTIVE) {
+ if (is_imx25_camera(pcdev) && buf->state == MX2_STATE_ACTIVE) {
if (pcdev->fb1_active == buf) {
pcdev->csicr1 &= ~CSICR1_FB1_DMA_INTEN;
writel(0, pcdev->base_csi + CSIDMASA_FB1);
@@ -835,7 +878,7 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
unsigned long phys;
int bytesperline;
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
unsigned long flags;
if (count < 2)
return -EINVAL;
@@ -930,7 +973,7 @@ static int mx2_stop_streaming(struct vb2_queue *q)
void *b;
u32 cntl;
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
spin_lock_irqsave(&pcdev->lock, flags);
cntl = readl(pcdev->base_emma + PRP_CNTL);
@@ -1082,11 +1125,11 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
if (bytesperline < 0)
return bytesperline;
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
ret = mx27_camera_emma_prp_reset(pcdev);
if (ret)
return ret;
- } else if (cpu_is_mx25()) {
+ } else if (is_imx25_camera(pcdev)) {
writel((bytesperline * icd->user_height) >> 2,
pcdev->base_csi + CSIRXCNT);
writel((bytesperline << 16) | icd->user_height,
@@ -1392,7 +1435,7 @@ static int mx2_camera_try_fmt(struct soc_camera_device *icd,
/* FIXME: implement MX27 limits */
/* limit to MX25 hardware capabilities */
- if (cpu_is_mx25()) {
+ if (is_imx25_camera(pcdev)) {
if (xlate->host_fmt->bits_per_sample <= 8)
width_limit = 0xffff * 4;
else
@@ -1726,10 +1769,31 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
goto exit;
}
- pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
- if (IS_ERR(pcdev->clk_csi)) {
- dev_err(&pdev->dev, "Could not get csi clock\n");
- err = PTR_ERR(pcdev->clk_csi);
+ pcdev->devtype = pdev->id_entry->driver_data;
+ switch (pcdev->devtype) {
+ case IMX25_CAMERA:
+ pcdev->reg_csisr = CSISR_IMX25;
+ pcdev->reg_csicr3 = CSICR3_IMX25;
+ break;
+ case IMX27_CAMERA:
+ pcdev->reg_csisr = CSISR_IMX27;
+ pcdev->reg_csicr3 = CSICR3_IMX27;
+ break;
+ default:
+ break;
+ }
+
+ pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(pcdev->clk_csi_ahb)) {
+ dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+ err = PTR_ERR(pcdev->clk_csi_ahb);
+ goto exit;
+ }
+
+ pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+ if (IS_ERR(pcdev->clk_csi_per)) {
+ dev_err(&pdev->dev, "Could not get csi per clock\n");
+ err = PTR_ERR(pcdev->clk_csi_per);
goto exit;
}
@@ -1739,12 +1803,13 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
pcdev->platform_flags = pcdev->pdata->flags;
- rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+ rate = clk_round_rate(pcdev->clk_csi_per,
+ pcdev->pdata->clk * 2);
if (rate <= 0) {
err = -ENODEV;
goto exit;
}
- err = clk_set_rate(pcdev->clk_csi, rate);
+ err = clk_set_rate(pcdev->clk_csi_per, rate);
if (err < 0)
goto exit;
}
@@ -1763,7 +1828,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
pcdev->dev = &pdev->dev;
platform_set_drvdata(pdev, pcdev);
- if (cpu_is_mx25()) {
+ if (is_imx25_camera(pcdev)) {
err = devm_request_irq(&pdev->dev, irq_csi, mx25_camera_irq, 0,
MX2_CAM_DRV_NAME, pcdev);
if (err) {
@@ -1772,7 +1837,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
}
}
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
err = mx27_camera_emma_init(pdev);
if (err)
goto exit;
@@ -1789,7 +1854,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
pcdev->soc_host.priv = pcdev;
pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
pcdev->soc_host.nr = pdev->id;
- if (cpu_is_mx25())
+ if (is_imx25_camera(pcdev))
pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
@@ -1802,14 +1867,14 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
goto exit_free_emma;
dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
- clk_get_rate(pcdev->clk_csi));
+ clk_get_rate(pcdev->clk_csi_per));
return 0;
exit_free_emma:
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
eallocctx:
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
clk_disable_unprepare(pcdev->clk_emma_ipg);
clk_disable_unprepare(pcdev->clk_emma_ahb);
}
@@ -1827,7 +1892,7 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev)
vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
- if (cpu_is_mx27()) {
+ if (is_imx27_camera(pcdev)) {
clk_disable_unprepare(pcdev->clk_emma_ipg);
clk_disable_unprepare(pcdev->clk_emma_ahb);
}
@@ -1841,6 +1906,7 @@ static struct platform_driver mx2_camera_driver = {
.driver = {
.name = MX2_CAM_DRV_NAME,
},
+ .id_table = mx2_camera_devtype,
.remove = __devexit_p(mx2_camera_remove),
};
diff --git a/drivers/media/platform/soc_camera/mx3_camera.c b/drivers/media/platform/soc_camera/mx3_camera.c
index 3557ac97e430..64d39b1b5582 100644
--- a/drivers/media/platform/soc_camera/mx3_camera.c
+++ b/drivers/media/platform/soc_camera/mx3_camera.c
@@ -17,6 +17,7 @@
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
+#include <linux/dma/ipu-dma.h>
#include <media/v4l2-common.h>
#include <media/v4l2-dev.h>
@@ -24,7 +25,6 @@
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
-#include <mach/ipu.h>
#include <linux/platform_data/camera-mx3.h>
#include <linux/platform_data/dma-imx.h>
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 6290b7f1ccfe..477f63bad521 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -41,7 +41,6 @@
#include <linux/platform_data/mmc-mxcmmc.h>
#include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
#define DRIVER_NAME "mxc-mmc"
#define MXCMCI_TIMEOUT_MS 10000
@@ -113,6 +112,11 @@
#define INT_WRITE_OP_DONE_EN (1 << 1)
#define INT_READ_OP_EN (1 << 0)
+enum mxcmci_type {
+ IMX21_MMC,
+ IMX31_MMC,
+};
+
struct mxcmci_host {
struct mmc_host *mmc;
struct resource *res;
@@ -153,7 +157,26 @@ struct mxcmci_host {
struct imx_dma_data dma_data;
struct timer_list watchdog;
+ enum mxcmci_type devtype;
+};
+
+static struct platform_device_id mxcmci_devtype[] = {
+ {
+ .name = "imx21-mmc",
+ .driver_data = IMX21_MMC,
+ }, {
+ .name = "imx31-mmc",
+ .driver_data = IMX31_MMC,
+ }, {
+ /* sentinel */
+ }
};
+MODULE_DEVICE_TABLE(platform, mxcmci_devtype);
+
+static inline int is_imx31_mmc(struct mxcmci_host *host)
+{
+ return host->devtype == IMX31_MMC;
+}
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -843,6 +866,8 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
{
+ struct mxcmci_host *mxcmci = mmc_priv(host);
+
/*
* MX3 SoCs have a silicon bug which corrupts CRC calculation of
* multi-block transfers when connected SDIO peripheral doesn't
@@ -850,7 +875,7 @@ static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
* One way to prevent this is to only allow 1-bit transfers.
*/
- if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO)
+ if (is_imx31_mmc(mxcmci) && card->type == MMC_TYPE_SDIO)
host->caps &= ~MMC_CAP_4_BIT_DATA;
else
host->caps |= MMC_CAP_4_BIT_DATA;
@@ -948,6 +973,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host->mmc = mmc;
host->pdata = pdev->dev.platform_data;
+ host->devtype = pdev->id_entry->driver_data;
spin_lock_init(&host->lock);
mxcmci_init_ocr(host);
@@ -1120,6 +1146,7 @@ static const struct dev_pm_ops mxcmci_pm_ops = {
static struct platform_driver mxcmci_driver = {
.probe = mxcmci_probe,
.remove = mxcmci_remove,
+ .id_table = mxcmci_devtype,
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 72e31d86030d..022dcdc256fb 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -37,15 +37,9 @@
#include <asm/mach/flash.h>
#include <linux/platform_data/mtd-mxc_nand.h>
-#include <mach/hardware.h>
#define DRIVER_NAME "mxc_nand"
-#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
-#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2a() cpu_is_mx51()
-#define nfc_is_v3_2b() cpu_is_mx53()
-
/* Addresses for NFC registers */
#define NFC_V1_V2_BUF_SIZE (host->regs + 0x00)
#define NFC_V1_V2_BUF_ADDR (host->regs + 0x04)
@@ -1283,6 +1277,53 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
.ppb_shift = 8,
};
+static inline int is_imx21_nfc(struct mxc_nand_host *host)
+{
+ return host->devtype_data == &imx21_nand_devtype_data;
+}
+
+static inline int is_imx27_nfc(struct mxc_nand_host *host)
+{
+ return host->devtype_data == &imx27_nand_devtype_data;
+}
+
+static inline int is_imx25_nfc(struct mxc_nand_host *host)
+{
+ return host->devtype_data == &imx25_nand_devtype_data;
+}
+
+static inline int is_imx51_nfc(struct mxc_nand_host *host)
+{
+ return host->devtype_data == &imx51_nand_devtype_data;
+}
+
+static inline int is_imx53_nfc(struct mxc_nand_host *host)
+{
+ return host->devtype_data == &imx53_nand_devtype_data;
+}
+
+static struct platform_device_id mxcnd_devtype[] = {
+ {
+ .name = "imx21-nand",
+ .driver_data = (kernel_ulong_t) &imx21_nand_devtype_data,
+ }, {
+ .name = "imx27-nand",
+ .driver_data = (kernel_ulong_t) &imx27_nand_devtype_data,
+ }, {
+ .name = "imx25-nand",
+ .driver_data = (kernel_ulong_t) &imx25_nand_devtype_data,
+ }, {
+ .name = "imx51-nand",
+ .driver_data = (kernel_ulong_t) &imx51_nand_devtype_data,
+ }, {
+ .name = "imx53-nand",
+ .driver_data = (kernel_ulong_t) &imx53_nand_devtype_data,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, mxcnd_devtype);
+
#ifdef CONFIG_OF_MTD
static const struct of_device_id mxcnd_dt_ids[] = {
{
@@ -1337,32 +1378,6 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host)
}
#endif
-static int __init mxcnd_probe_pdata(struct mxc_nand_host *host)
-{
- struct mxc_nand_platform_data *pdata = host->dev->platform_data;
-
- if (!pdata)
- return -ENODEV;
-
- host->pdata = *pdata;
-
- if (nfc_is_v1()) {
- if (cpu_is_mx21())
- host->devtype_data = &imx21_nand_devtype_data;
- else
- host->devtype_data = &imx27_nand_devtype_data;
- } else if (nfc_is_v21()) {
- host->devtype_data = &imx25_nand_devtype_data;
- } else if (nfc_is_v3_2a()) {
- host->devtype_data = &imx51_nand_devtype_data;
- } else if (nfc_is_v3_2b()) {
- host->devtype_data = &imx53_nand_devtype_data;
- } else
- BUG();
-
- return 0;
-}
-
static int __devinit mxcnd_probe(struct platform_device *pdev)
{
struct nand_chip *this;
@@ -1404,8 +1419,16 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)
return PTR_ERR(host->clk);
err = mxcnd_probe_dt(host);
- if (err > 0)
- err = mxcnd_probe_pdata(host);
+ if (err > 0) {
+ struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
+ if (pdata) {
+ host->pdata = *pdata;
+ host->devtype_data = (struct mxc_nand_devtype_data *)
+ pdev->id_entry->driver_data;
+ } else {
+ err = -ENODEV;
+ }
+ }
if (err < 0)
return err;
@@ -1494,7 +1517,7 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)
}
/* first scan to find the device and get the page size */
- if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) {
+ if (nand_scan_ident(mtd, is_imx25_nfc(host) ? 4 : 1, NULL)) {
err = -ENXIO;
goto escan;
}
@@ -1508,7 +1531,7 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)
this->ecc.layout = host->devtype_data->ecclayout_4k;
if (this->ecc.mode == NAND_ECC_HW) {
- if (nfc_is_v1())
+ if (is_imx21_nfc(host) || is_imx27_nfc(host))
this->ecc.strength = 1;
else
this->ecc.strength = (host->eccsize == 4) ? 4 : 8;
@@ -1555,6 +1578,7 @@ static struct platform_driver mxcnd_driver = {
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(mxcnd_dt_ids),
},
+ .id_table = mxcnd_devtype,
.probe = mxcnd_probe,
.remove = __devexit_p(mxcnd_remove),
};
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c
index cd0106293a49..7304139934aa 100644
--- a/drivers/rtc/rtc-mxc.c
+++ b/drivers/rtc/rtc-mxc.c
@@ -17,8 +17,6 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
-#include <mach/hardware.h>
-
#define RTC_INPUT_CLK_32768HZ (0x00 << 5)
#define RTC_INPUT_CLK_32000HZ (0x01 << 5)
#define RTC_INPUT_CLK_38400HZ (0x02 << 5)
@@ -72,14 +70,38 @@ static const u32 PIE_BIT_DEF[MAX_PIE_NUM][2] = {
#define RTC_TEST2 0x2C /* 32bit rtc test reg 2 */
#define RTC_TEST3 0x30 /* 32bit rtc test reg 3 */
+enum imx_rtc_type {
+ IMX1_RTC,
+ IMX21_RTC,
+};
+
struct rtc_plat_data {
struct rtc_device *rtc;
void __iomem *ioaddr;
int irq;
struct clk *clk;
struct rtc_time g_rtc_alarm;
+ enum imx_rtc_type devtype;
};
+static struct platform_device_id imx_rtc_devtype[] = {
+ {
+ .name = "imx1-rtc",
+ .driver_data = IMX1_RTC,
+ }, {
+ .name = "imx21-rtc",
+ .driver_data = IMX21_RTC,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imx_rtc_devtype);
+
+static inline int is_imx1_rtc(struct rtc_plat_data *data)
+{
+ return data->devtype == IMX1_RTC;
+}
+
/*
* This function is used to obtain the RTC time or the alarm value in
* second.
@@ -278,10 +300,13 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
*/
static int mxc_rtc_set_mmss(struct device *dev, unsigned long time)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
+
/*
* TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only
*/
- if (cpu_is_mx1()) {
+ if (is_imx1_rtc(pdata)) {
struct rtc_time tm;
rtc_time_to_tm(time, &tm);
@@ -360,6 +385,8 @@ static int __devinit mxc_rtc_probe(struct platform_device *pdev)
if (!pdata)
return -ENOMEM;
+ pdata->devtype = pdev->id_entry->driver_data;
+
if (!devm_request_mem_region(&pdev->dev, res->start,
resource_size(res), pdev->name))
return -EBUSY;
@@ -480,6 +507,7 @@ static struct platform_driver mxc_rtc_driver = {
#endif
.owner = THIS_MODULE,
},
+ .id_table = imx_rtc_devtype,
.probe = mxc_rtc_probe,
.remove = __devexit_p(mxc_rtc_remove),
};
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 07e9fb4f8041..b3dc44146ca0 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -361,3 +361,89 @@ int __init sh_clk_div4_reparent_register(struct clk *clks, int nr,
return sh_clk_div_register_ops(clks, nr, table,
&sh_clk_div4_reparent_clk_ops);
}
+
+/* FSI-DIV */
+static unsigned long fsidiv_recalc(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+
+ value >>= 16;
+ if (value < 2)
+ return clk->parent->rate;
+
+ return clk->parent->rate / value;
+}
+
+static long fsidiv_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_div_range_round(clk, 1, 0xffff, rate);
+}
+
+static void fsidiv_disable(struct clk *clk)
+{
+ __raw_writel(0, clk->mapping->base);
+}
+
+static int fsidiv_enable(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base) >> 16;
+ if (value < 2)
+ return 0;
+
+ __raw_writel((value << 16) | 0x3, clk->mapping->base);
+
+ return 0;
+}
+
+static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val;
+ int idx;
+
+ idx = (clk->parent->rate / rate) & 0xffff;
+ if (idx < 2)
+ __raw_writel(0, clk->mapping->base);
+ else
+ __raw_writel(idx << 16, clk->mapping->base);
+
+ return 0;
+}
+
+static struct sh_clk_ops fsidiv_clk_ops = {
+ .recalc = fsidiv_recalc,
+ .round_rate = fsidiv_round_rate,
+ .set_rate = fsidiv_set_rate,
+ .enable = fsidiv_enable,
+ .disable = fsidiv_disable,
+};
+
+int __init sh_clk_fsidiv_register(struct clk *clks, int nr)
+{
+ struct clk_mapping *map;
+ int i;
+
+ for (i = 0; i < nr; i++) {
+
+ map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL);
+ if (!map) {
+ pr_err("%s: unable to alloc memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* clks[i].enable_reg came from SH_CLK_FSIDIV() */
+ map->phys = (phys_addr_t)clks[i].enable_reg;
+ map->len = 8;
+
+ clks[i].enable_reg = 0; /* remove .enable_reg */
+ clks[i].ops = &fsidiv_clk_ops;
+ clks[i].mapping = map;
+
+ clk_register(&clks[i]);
+ }
+
+ return 0;
+}
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 6f3ea9bbc818..c48b93813fc1 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -97,6 +97,7 @@ config UIO_NETX
config UIO_PRUSS
tristate "Texas Instruments PRUSS driver"
depends on ARCH_DAVINCI_DA850
+ select GENERIC_ALLOCATOR
help
PRUSS driver for OMAPL138/DA850/AM18XX devices
PRUSS driver requires user space components, examples and user space
diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
index 33a7a273b453..f8738de342be 100644
--- a/drivers/uio/uio_pruss.c
+++ b/drivers/uio/uio_pruss.c
@@ -25,7 +25,7 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
-#include <mach/sram.h>
+#include <linux/genalloc.h>
#define DRV_NAME "pruss_uio"
#define DRV_VERSION "1.0"
@@ -65,10 +65,11 @@ struct uio_pruss_dev {
dma_addr_t sram_paddr;
dma_addr_t ddr_paddr;
void __iomem *prussio_vaddr;
- void *sram_vaddr;
+ unsigned long sram_vaddr;
void *ddr_vaddr;
unsigned int hostirq_start;
unsigned int pintc_base;
+ struct gen_pool *sram_pool;
};
static irqreturn_t pruss_handler(int irq, struct uio_info *info)
@@ -106,7 +107,9 @@ static void pruss_cleanup(struct platform_device *dev,
gdev->ddr_paddr);
}
if (gdev->sram_vaddr)
- sram_free(gdev->sram_vaddr, sram_pool_sz);
+ gen_pool_free(gdev->sram_pool,
+ gdev->sram_vaddr,
+ sram_pool_sz);
kfree(gdev->info);
clk_put(gdev->pruss_clk);
kfree(gdev);
@@ -152,10 +155,17 @@ static int __devinit pruss_probe(struct platform_device *dev)
goto out_free;
}
- gdev->sram_vaddr = sram_alloc(sram_pool_sz, &(gdev->sram_paddr));
- if (!gdev->sram_vaddr) {
- dev_err(&dev->dev, "Could not allocate SRAM pool\n");
- goto out_free;
+ if (pdata->sram_pool) {
+ gdev->sram_pool = pdata->sram_pool;
+ gdev->sram_vaddr =
+ gen_pool_alloc(gdev->sram_pool, sram_pool_sz);
+ if (!gdev->sram_vaddr) {
+ dev_err(&dev->dev, "Could not allocate SRAM pool\n");
+ goto out_free;
+ }
+ gdev->sram_paddr =
+ gen_pool_virt_to_phys(gdev->sram_pool,
+ gdev->sram_vaddr);
}
gdev->ddr_vaddr = dma_alloc_coherent(&dev->dev, extram_pool_sz,
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index 4a08fc0b27c9..8e58a5fa1994 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -24,7 +24,6 @@
#include <linux/usb/ulpi.h>
#include <linux/slab.h>
-#include <mach/hardware.h>
#include <linux/platform_data/usb-ehci-mxc.h>
#include <asm/mach-types.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index cf2688de0832..e501dbc966b3 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -33,7 +33,6 @@
#include <linux/math64.h>
#include <linux/platform_data/video-imxfb.h>
-#include <mach/hardware.h>
/*
* Complain if VAR is out of range.
@@ -53,8 +52,8 @@
#define LCDC_SIZE 0x04
#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
-#define YMAX_MASK (cpu_is_mx1() ? 0x1ff : 0x3ff)
-#define SIZE_YMAX(y) ((y) & YMAX_MASK)
+#define YMAX_MASK_IMX1 0x1ff
+#define YMAX_MASK_IMX21 0x3ff
#define LCDC_VPW 0x08
#define VPW_VPW(x) ((x) & 0x3ff)
@@ -128,12 +127,18 @@ struct imxfb_rgb {
struct fb_bitfield transp;
};
+enum imxfb_type {
+ IMX1_FB,
+ IMX21_FB,
+};
+
struct imxfb_info {
struct platform_device *pdev;
void __iomem *regs;
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
+ enum imxfb_type devtype;
/*
* These are the addresses we mapped
@@ -168,6 +173,24 @@ struct imxfb_info {
void (*backlight_power)(int);
};
+static struct platform_device_id imxfb_devtype[] = {
+ {
+ .name = "imx1-fb",
+ .driver_data = IMX1_FB,
+ }, {
+ .name = "imx21-fb",
+ .driver_data = IMX21_FB,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(platform, imxfb_devtype);
+
+static inline int is_imx1_fb(struct imxfb_info *fbi)
+{
+ return fbi->devtype == IMX1_FB;
+}
+
#define IMX_NAME "IMX"
/*
@@ -366,7 +389,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
break;
case 16:
default:
- if (cpu_is_mx1())
+ if (is_imx1_fb(fbi))
pcr |= PCR_BPIX_12;
else
pcr |= PCR_BPIX_16;
@@ -596,6 +619,7 @@ static struct fb_ops imxfb_ops = {
static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct imxfb_info *fbi = info->par;
+ u32 ymax_mask = is_imx1_fb(fbi) ? YMAX_MASK_IMX1 : YMAX_MASK_IMX21;
pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",
var->xres, var->hsync_len,
@@ -617,7 +641,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
if (var->right_margin > 255)
printk(KERN_ERR "%s: invalid right_margin %d\n",
info->fix.id, var->right_margin);
- if (var->yres < 1 || var->yres > YMAX_MASK)
+ if (var->yres < 1 || var->yres > ymax_mask)
printk(KERN_ERR "%s: invalid yres %d\n",
info->fix.id, var->yres);
if (var->vsync_len > 100)
@@ -645,7 +669,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf
VCR_V_WAIT_2(var->upper_margin),
fbi->regs + LCDC_VCR);
- writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),
+ writel(SIZE_XMAX(var->xres) | (var->yres & ymax_mask),
fbi->regs + LCDC_SIZE);
writel(fbi->pcr, fbi->regs + LCDC_PCR);
@@ -765,6 +789,7 @@ static int __init imxfb_probe(struct platform_device *pdev)
return -ENOMEM;
fbi = info->par;
+ fbi->devtype = pdev->id_entry->driver_data;
if (!fb_mode)
fb_mode = pdata->mode[0].mode.name;
@@ -939,6 +964,7 @@ static struct platform_driver imxfb_driver = {
.driver = {
.name = DRIVER_NAME,
},
+ .id_table = imxfb_devtype,
};
static int imxfb_setup(void)
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index ce1d452464ed..736887208574 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -26,10 +26,9 @@
#include <linux/console.h>
#include <linux/clk.h>
#include <linux/mutex.h>
+#include <linux/dma/ipu-dma.h>
#include <linux/platform_data/dma-imx.h>
-#include <mach/hardware.h>
-#include <mach/ipu.h>
#include <linux/platform_data/video-mx3fb.h>
#include <asm/io.h>
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index bcfab2b00ad2..9a45d0294cf4 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -33,7 +33,6 @@
#include <linux/uaccess.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
-#include <mach/hardware.h>
#define DRIVER_NAME "imx2-wdt"