linux/arch/arm/mach-omap2/omap-iommu.c
<<
>>
Prefs
   1/*
   2 * omap iommu: omap device registration
   3 *
   4 * Copyright (C) 2008-2009 Nokia Corporation
   5 *
   6 * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/platform_device.h>
  14
  15#include <plat/iommu.h>
  16#include <plat/irqs.h>
  17
  18struct iommu_device {
  19        resource_size_t base;
  20        int irq;
  21        struct iommu_platform_data pdata;
  22        struct resource res[2];
  23};
  24static struct iommu_device *devices;
  25static int num_iommu_devices;
  26
  27#ifdef CONFIG_ARCH_OMAP3
  28static struct iommu_device omap3_devices[] = {
  29        {
  30                .base = 0x480bd400,
  31                .irq = 24,
  32                .pdata = {
  33                        .name = "isp",
  34                        .nr_tlb_entries = 8,
  35                        .clk_name = "cam_ick",
  36                        .da_start = 0x0,
  37                        .da_end = 0xFFFFF000,
  38                },
  39        },
  40#if defined(CONFIG_OMAP_IOMMU_IVA2)
  41        {
  42                .base = 0x5d000000,
  43                .irq = 28,
  44                .pdata = {
  45                        .name = "iva2",
  46                        .nr_tlb_entries = 32,
  47                        .clk_name = "iva2_ck",
  48                        .da_start = 0x11000000,
  49                        .da_end = 0xFFFFF000,
  50                },
  51        },
  52#endif
  53};
  54#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
  55static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
  56#else
  57#define omap3_devices           NULL
  58#define NR_OMAP3_IOMMU_DEVICES  0
  59#define omap3_iommu_pdev        NULL
  60#endif
  61
  62#ifdef CONFIG_ARCH_OMAP4
  63static struct iommu_device omap4_devices[] = {
  64        {
  65                .base = OMAP4_MMU1_BASE,
  66                .irq = OMAP44XX_IRQ_DUCATI_MMU,
  67                .pdata = {
  68                        .name = "ducati",
  69                        .nr_tlb_entries = 32,
  70                        .clk_name = "ducati_ick",
  71                        .da_start = 0x0,
  72                        .da_end = 0xFFFFF000,
  73                },
  74        },
  75#if defined(CONFIG_MPU_TESLA_IOMMU)
  76        {
  77                .base = OMAP4_MMU2_BASE,
  78                .irq = INT_44XX_DSP_MMU,
  79                .pdata = {
  80                        .name = "tesla",
  81                        .nr_tlb_entries = 32,
  82                        .clk_name = "tesla_ick",
  83                        .da_start = 0x0,
  84                        .da_end = 0xFFFFF000,
  85                },
  86        },
  87#endif
  88};
  89#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
  90static struct platform_device *omap4_iommu_pdev[NR_OMAP4_IOMMU_DEVICES];
  91#else
  92#define omap4_devices           NULL
  93#define NR_OMAP4_IOMMU_DEVICES  0
  94#define omap4_iommu_pdev        NULL
  95#endif
  96
  97static struct platform_device **omap_iommu_pdev;
  98
  99static int __init omap_iommu_init(void)
 100{
 101        int i, err;
 102        struct resource res[] = {
 103                { .flags = IORESOURCE_MEM },
 104                { .flags = IORESOURCE_IRQ },
 105        };
 106
 107        if (cpu_is_omap34xx()) {
 108                devices = omap3_devices;
 109                omap_iommu_pdev = omap3_iommu_pdev;
 110                num_iommu_devices = NR_OMAP3_IOMMU_DEVICES;
 111        } else if (cpu_is_omap44xx()) {
 112                devices = omap4_devices;
 113                omap_iommu_pdev = omap4_iommu_pdev;
 114                num_iommu_devices = NR_OMAP4_IOMMU_DEVICES;
 115        } else
 116                return -ENODEV;
 117
 118        for (i = 0; i < num_iommu_devices; i++) {
 119                struct platform_device *pdev;
 120                const struct iommu_device *d = &devices[i];
 121
 122                pdev = platform_device_alloc("omap-iommu", i);
 123                if (!pdev) {
 124                        err = -ENOMEM;
 125                        goto err_out;
 126                }
 127
 128                res[0].start = d->base;
 129                res[0].end = d->base + MMU_REG_SIZE - 1;
 130                res[1].start = res[1].end = d->irq;
 131
 132                err = platform_device_add_resources(pdev, res,
 133                                                    ARRAY_SIZE(res));
 134                if (err)
 135                        goto err_out;
 136                err = platform_device_add_data(pdev, &d->pdata,
 137                                               sizeof(d->pdata));
 138                if (err)
 139                        goto err_out;
 140                err = platform_device_add(pdev);
 141                if (err)
 142                        goto err_out;
 143                omap_iommu_pdev[i] = pdev;
 144        }
 145        return 0;
 146
 147err_out:
 148        while (i--)
 149                platform_device_put(omap_iommu_pdev[i]);
 150        return err;
 151}
 152module_init(omap_iommu_init);
 153
 154static void __exit omap_iommu_exit(void)
 155{
 156        int i;
 157
 158        for (i = 0; i < num_iommu_devices; i++)
 159                platform_device_unregister(omap_iommu_pdev[i]);
 160}
 161module_exit(omap_iommu_exit);
 162
 163MODULE_AUTHOR("Hiroshi DOYU");
 164MODULE_DESCRIPTION("omap iommu: omap device registration");
 165MODULE_LICENSE("GPL v2");
 166