0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/clk.h>
0016 #include <linux/io.h>
0017 #include <linux/err.h>
0018 #include <linux/slab.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/platform_data/dmtimer-omap.h>
0021 #include <linux/soc/ti/omap1-io.h>
0022
0023 #include <clocksource/timer-ti-dm.h>
0024
0025 #include "soc.h"
0026
0027 #define OMAP1610_GPTIMER1_BASE 0xfffb1400
0028 #define OMAP1610_GPTIMER2_BASE 0xfffb1c00
0029 #define OMAP1610_GPTIMER3_BASE 0xfffb2400
0030 #define OMAP1610_GPTIMER4_BASE 0xfffb2c00
0031 #define OMAP1610_GPTIMER5_BASE 0xfffb3400
0032 #define OMAP1610_GPTIMER6_BASE 0xfffb3c00
0033 #define OMAP1610_GPTIMER7_BASE 0xfffb7400
0034 #define OMAP1610_GPTIMER8_BASE 0xfffbd400
0035
0036 #define OMAP1_DM_TIMER_COUNT 8
0037
0038 static int omap1_dm_timer_set_src(struct platform_device *pdev,
0039 int source)
0040 {
0041 int n = (pdev->id - 1) << 1;
0042 u32 l;
0043
0044 l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
0045 l |= source << n;
0046 omap_writel(l, MOD_CONF_CTRL_1);
0047
0048 return 0;
0049 }
0050
0051 static int __init omap1_dm_timer_init(void)
0052 {
0053 int i;
0054 int ret;
0055 struct dmtimer_platform_data *pdata;
0056 struct platform_device *pdev;
0057
0058 if (!cpu_is_omap16xx())
0059 return 0;
0060
0061 for (i = 1; i <= OMAP1_DM_TIMER_COUNT; i++) {
0062 struct resource res[2];
0063 u32 base, irq;
0064
0065 switch (i) {
0066 case 1:
0067 base = OMAP1610_GPTIMER1_BASE;
0068 irq = INT_1610_GPTIMER1;
0069 break;
0070 case 2:
0071 base = OMAP1610_GPTIMER2_BASE;
0072 irq = INT_1610_GPTIMER2;
0073 break;
0074 case 3:
0075 base = OMAP1610_GPTIMER3_BASE;
0076 irq = INT_1610_GPTIMER3;
0077 break;
0078 case 4:
0079 base = OMAP1610_GPTIMER4_BASE;
0080 irq = INT_1610_GPTIMER4;
0081 break;
0082 case 5:
0083 base = OMAP1610_GPTIMER5_BASE;
0084 irq = INT_1610_GPTIMER5;
0085 break;
0086 case 6:
0087 base = OMAP1610_GPTIMER6_BASE;
0088 irq = INT_1610_GPTIMER6;
0089 break;
0090 case 7:
0091 base = OMAP1610_GPTIMER7_BASE;
0092 irq = INT_1610_GPTIMER7;
0093 break;
0094 case 8:
0095 base = OMAP1610_GPTIMER8_BASE;
0096 irq = INT_1610_GPTIMER8;
0097 break;
0098 default:
0099
0100
0101
0102
0103 return -EINVAL;
0104 }
0105
0106 pdev = platform_device_alloc("omap_timer", i);
0107 if (!pdev) {
0108 pr_err("%s: Failed to device alloc for dmtimer%d\n",
0109 __func__, i);
0110 return -ENOMEM;
0111 }
0112
0113 memset(res, 0, 2 * sizeof(struct resource));
0114 res[0].start = base;
0115 res[0].end = base + 0x46;
0116 res[0].flags = IORESOURCE_MEM;
0117 res[1].start = irq;
0118 res[1].end = irq;
0119 res[1].flags = IORESOURCE_IRQ;
0120 ret = platform_device_add_resources(pdev, res,
0121 ARRAY_SIZE(res));
0122 if (ret) {
0123 dev_err(&pdev->dev, "%s: Failed to add resources.\n",
0124 __func__);
0125 goto err_free_pdev;
0126 }
0127
0128 pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
0129 if (!pdata) {
0130 ret = -ENOMEM;
0131 goto err_free_pdata;
0132 }
0133
0134 pdata->set_timer_src = omap1_dm_timer_set_src;
0135 pdata->timer_capability = OMAP_TIMER_ALWON |
0136 OMAP_TIMER_NEEDS_RESET | OMAP_TIMER_HAS_DSP_IRQ;
0137
0138 ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
0139 if (ret) {
0140 dev_err(&pdev->dev, "%s: Failed to add platform data.\n",
0141 __func__);
0142 goto err_free_pdata;
0143 }
0144
0145 ret = platform_device_add(pdev);
0146 if (ret) {
0147 dev_err(&pdev->dev, "%s: Failed to add platform device.\n",
0148 __func__);
0149 goto err_free_pdata;
0150 }
0151
0152 dev_dbg(&pdev->dev, " Registered.\n");
0153 }
0154
0155 return 0;
0156
0157 err_free_pdata:
0158 kfree(pdata);
0159
0160 err_free_pdev:
0161 platform_device_unregister(pdev);
0162
0163 return ret;
0164 }
0165 arch_initcall(omap1_dm_timer_init);