static int gptimer_start(void) { int err; u32 count = counter_config[0].count; BUG_ON(gptimer != NULL); /* First try to request timers from CORE power domain for OMAP3 */ if (cpu_is_omap34xx()) { gptimer = omap_dm_timer_request_specific(10); if (gptimer == NULL) gptimer = omap_dm_timer_request_specific(11); } /* Just any timer would be fine */ if (gptimer == NULL) gptimer = omap_dm_timer_request(); if (gptimer == NULL) return -ENODEV; omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); err = request_irq(omap_dm_timer_get_irq(gptimer), gptimer_interrupt, IRQF_DISABLED, "oprofile gptimer", NULL); if (err) { omap_dm_timer_free(gptimer); gptimer = NULL; printk(KERN_ERR "oprofile: unable to request gptimer IRQ\n"); return err; } if (count < 1) count = 1; omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - count); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); return 0; }
static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; gptimer = omap_dm_timer_request_specific(1); BUG_ON(gptimer == NULL); #if defined(CONFIG_OMAP_32K_TIMER) omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ); #else omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); #endif tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); omap2_gp_timer_irq.dev_id = (void *)gptimer; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(1, &clockevent_gpt); clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); }
static void gptimer_stop(void) { omap_dm_timer_set_int_enable(gptimer, 0); free_irq(omap_dm_timer_get_irq(gptimer), NULL); omap_dm_timer_free(gptimer); gptimer = NULL; }
static void __init omap2_gp_clockevent_init(int gptimer_id, const char *fck_source) { int res; res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source); BUG_ON(res); omap2_gp_timer_irq.dev_id = (void *)&clkev; setup_irq(clkev.irq, &omap2_gp_timer_irq); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpu_possible_mask; clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); clockevents_register_device(&clockevent_gpt); pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", gptimer_id, clkev.rate); }
static int __devinit cloudsurfer_wakeup_probe(struct platform_device *pdev) { struct cloudsurfer_wakeup_struct *wkup; struct input_dev *wkup_in; u32 tick_rate, cycles; int err; /* Data structure allocation */ wkup = kzalloc(sizeof(struct cloudsurfer_wakeup_struct), GFP_KERNEL); wkup_in = input_allocate_device(); if (!wkup_in) { printk("CLOUDSURFER - Can't allocate wakeup timer input\n"); err = -ENOMEM; goto error_input_dev; } /* Timer allocation and setup */ if ( (wkup->timer=omap_dm_timer_request_specific(1)) == NULL ) { printk("CLOUDSURFER - can't allocate wakeup timer\n"); err = -ENODEV; goto error_timer; } wkup->irq = omap_dm_timer_get_irq(wkup->timer); omap_dm_timer_set_source(wkup->timer,OMAP_TIMER_SRC_32_KHZ); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(wkup->timer)); cycles = tick_rate * wakeup_seconds; omap_dm_timer_stop(wkup->timer); input_set_capability(wkup_in,EV_MSC,1); input_set_capability(wkup_in,EV_MSC,2); wkup_in->name = "cloudsurfer-wakeup"; wkup_in->phys = "cloudsurfer-wakeup/input0"; wkup_in->dev.parent = &pdev->dev; cloudsurfer_irq_data.dev_id = wkup_in; setup_irq(wkup->irq,&cloudsurfer_irq_data); input_set_drvdata(wkup_in, wkup); err = input_register_device(wkup_in); if (err) { printk("CLOUDSURFER -Can't register wakeup timer: %d\n", err); goto error_register; } omap_dm_timer_set_int_enable(wkup->timer,OMAP_TIMER_INT_OVERFLOW); omap_dm_timer_set_load_start(wkup->timer, 1, 0xffffffff - cycles); platform_set_drvdata(pdev, wkup_in); return 0; error_register: free_irq(wkup->irq, NULL); error_timer: input_free_device(wkup_in); error_input_dev: kfree(wkup); return err; }
static irqreturn_t omap_rproc_watchdog_isr(int irq, void *p) { struct rproc *rproc = p; struct omap_rproc_pdata *pdata = rproc->dev->platform_data; struct omap_rproc_timers_info *timers = pdata->timers; struct omap_dm_timer *timer = NULL; struct omap_rproc_priv *rpp = rproc->priv; int i; for (i = 0; i < pdata->timers_cnt; i++) { if (irq == omap_dm_timer_get_irq(timers[i].odt)) { timer = timers[i].odt; break; } } if (!timer) return IRQ_NONE; omap_dm_timer_write_status(timer, OMAP_TIMER_INT_OVERFLOW); if (rpp->wdt_cb) rpp->wdt_cb(rproc); return IRQ_HANDLED; }
static void __init omap2_gp_clockevent_init(int gptimer_id, const char *fck_source, const char *property) { int res; clkev.id = gptimer_id; clkev.errata = omap_dm_timer_get_errata(); /* * For clock-event timers we never read the timer counter and * so we are not impacted by errata i103 and i767. Therefore, * we can safely ignore this errata for clock-event timers. */ __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); res = omap_dm_timer_init_one(&clkev, fck_source, property, &clockevent_gpt.name, OMAP_TIMER_POSTED); BUG_ON(res); omap2_gp_timer_irq.dev_id = &clkev; setup_irq(clkev.irq, &omap2_gp_timer_irq); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.cpumask = cpu_possible_mask; clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); clockevents_config_and_register(&clockevent_gpt, clkev.rate, 3, /* Timer internal resynch latency */ 0xffffffff); pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, clkev.rate); }
static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr) { struct device *dev = rproc->dev; struct platform_device *pdev = to_platform_device(dev); struct omap_rproc_pdata *pdata = dev->platform_data; struct omap_rproc_timers_info *timers = pdata->timers; struct omap_rproc_priv *rpp = rproc->priv; int i; int ret = 0; if (rproc->secure_mode) { rproc->secure_reset = true; ret = rproc_drm_invoke_service(rproc->secure_mode); if (ret) { dev_err(rproc->dev, "rproc_drm_invoke_service failed " "for secure_enable ret = 0x%x\n", ret); return -ENXIO; } } #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND ret = _init_pm_flags(rproc); if (ret) return ret; #endif for (i = 0; i < pdata->timers_cnt; i++) { timers[i].odt = omap_dm_timer_request_specific(timers[i].id); if (!timers[i].odt) { ret = -EBUSY; goto out; } omap_dm_timer_set_source(timers[i].odt, OMAP_TIMER_SRC_SYS_CLK); #ifdef CONFIG_REMOTEPROC_WATCHDOG /* GPT 9 & 11 (ipu); GPT 6 (dsp) are used as watchdog timers */ if ((!strcmp(rproc->name, "dsp") && timers[i].id == 6) || (!strcmp(rproc->name, "ipu") && (timers[i].id == DUCATI_WDT_TIMER_1 || timers[i].id == DUCATI_WDT_TIMER_2))) { ret = request_irq(omap_dm_timer_get_irq(timers[i].odt), omap_rproc_watchdog_isr, IRQF_DISABLED, "rproc-wdt", rproc); /* Clean counter, remoteproc proc will set the value */ omap_dm_timer_set_load(timers[i].odt, 0, 0); } #endif } rpp->bootaddr = bootaddr; ret = omap_device_enable(pdev); out: if (ret) { while (i--) { omap_dm_timer_free(timers[i].odt); timers[i].odt = NULL; } } return ret; }
static int __devexit cloudsurfer_wakeup_remove(struct platform_device *pdev) { struct input_dev *wkup_in = platform_get_drvdata(pdev); struct cloudsurfer_wakeup_struct *wkup = input_get_drvdata(wkup_in); int irq = omap_dm_timer_get_irq(wkup->timer); free_irq(irq, wkup); kfree(wkup); input_unregister_device(wkup_in); return 0; }
static int __init gptimer_request_init(void) { struct clk *gt_fclk; uint32_t gt_rate; /*Requesting for any available timer*/ timer_ptr = omap_dm_timer_request(); if (timer_ptr == NULL) { /*Timers are not available*/ printk(KERN_ERR "GPtimers are not available\n"); return -1; } switch (clock_type) { case 1: /*Set the clock source to 32Khz Clock*/ printk(KERN_INFO "Using OMAP_TIMER_SRC_32_KHZ source\n"); omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_32_KHZ); break; case 2: /*Set the clock source to System Clock*/ printk(KERN_INFO "Using OMAP_TIMER_SRC_SYS_CLK source\n"); omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK); break; case 3: /*Set the clock source to System Clock*/ printk(KERN_INFO "Using OMAP_TIMER_SRC_EXT_CLK source\n"); omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_EXT_CLK); break; default: printk(KERN_ERR "Invalid clock_type value. Use 1, 2 or 3\n"); return -1; } /*Figure out what IRQ our timer triggers*/ timer_irq = omap_dm_timer_get_irq(timer_ptr); /*Get clock rate in Hz*/ gt_fclk = omap_dm_timer_get_fclk(timer_ptr); gt_rate = clk_get_rate(gt_fclk); /*Start the timer!*/ omap_dm_timer_start(timer_ptr); printk(KERN_INFO "GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq); return 0; }
// Initialize the kernel module static int __init gptimer_test_init(void) { int ret = 0; struct clk *gt_fclk; uint32_t gt_rate; printk("gptimer test: starting moudle init\n"); // request a timer (we are asking for ANY open timer, see dmtimer.c for details on how this works) timer_ptr = omap_dm_timer_request(); if(timer_ptr == NULL){ // oops, no timers available printk("gptimer test: No more gp timers available, bailing out\n"); return -1; } // set the clock source to system clock omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK); // set prescalar to 1:1 omap_dm_timer_set_prescaler(timer_ptr, 32); // figure out what IRQ our timer triggers timer_irq = omap_dm_timer_get_irq(timer_ptr); // install our IRQ handler for our timer ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler); if(ret){ printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq); return ret; } // get clock rate in Hz gt_fclk = omap_dm_timer_get_fclk(timer_ptr); gt_rate = clk_get_rate(gt_fclk); // set preload, and autoreload // we set it to the clock rate in order to get 1 overflow every second omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - gt_rate); // setup timer to trigger our IRQ on the overflow event omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW); // start the timer! omap_dm_timer_start(timer_ptr); // done! printk("gptimer test: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq); // return sucsess return 0; }
static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; int src; u32* time_base = ioremap(0x4A318000, SZ_4K); inited = 1; gptimer = omap_dm_timer_request_specific(gptimer_id); BUG_ON(gptimer == NULL); gptimer_wakeup = gptimer; #if defined(CONFIG_OMAP_32K_TIMER) src = OMAP_TIMER_SRC_32_KHZ; #else src = OMAP_TIMER_SRC_SYS_CLK; WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the " "secure 32KiHz clock source\n"); #endif if (gptimer_id != 12) WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)), "timer-gp: omap_dm_timer_set_source() failed\n"); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", gptimer_id, tick_rate); print_timer(time_base); omap2_gp_timer_irq.dev_id = (void *)gptimer; //TODO: slow for safety omap_dm_timer_set_load_start(gptimer, 1, 0); print_timer(time_base); setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); print_timer(time_base); }
static int irblaster_remove(struct platform_device *pdev) { int irqno = omap_dm_timer_get_irq(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); free_irq(irqno, NULL); misc_deregister(&irblast_miscdev); _select_default_config(); omap_dm_timer_free(gpt_pwm_list[IRBLASTER_PWM].timer); omap_dm_timer_free(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); return 0; }
static void __init omap2_gp_timer_init(void) { u32 tick_period; omap_dm_timer_init(); gptimer = omap_dm_timer_request_specific(1); BUG_ON(gptimer == NULL); omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / 100; tick_period -= 1; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap2_gp_timer_start(tick_period); }
static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51) { struct clk *clk_fclk; int retval, pwm_timer = lirc_rx51->pwm_timer_num; lirc_rx51->pwm_timer = omap_dm_timer_request_specific(pwm_timer); if (lirc_rx51->pwm_timer == NULL) { dev_err(lirc_rx51->dev, ": Error requesting GPT%d timer\n", pwm_timer); return -EBUSY; } lirc_rx51->pulse_timer = omap_dm_timer_request(); if (lirc_rx51->pulse_timer == NULL) { dev_err(lirc_rx51->dev, ": Error requesting pulse timer\n"); retval = -EBUSY; goto err1; } omap_dm_timer_set_source(lirc_rx51->pwm_timer, OMAP_TIMER_SRC_SYS_CLK); omap_dm_timer_set_source(lirc_rx51->pulse_timer, OMAP_TIMER_SRC_SYS_CLK); omap_dm_timer_enable(lirc_rx51->pwm_timer); omap_dm_timer_enable(lirc_rx51->pulse_timer); lirc_rx51->irq_num = omap_dm_timer_get_irq(lirc_rx51->pulse_timer); retval = request_irq(lirc_rx51->irq_num, lirc_rx51_interrupt_handler, IRQF_DISABLED | IRQF_SHARED, "lirc_pulse_timer", lirc_rx51); if (retval) { dev_err(lirc_rx51->dev, ": Failed to request interrupt line\n"); goto err2; } clk_fclk = omap_dm_timer_get_fclk(lirc_rx51->pwm_timer); lirc_rx51->fclk_khz = clk_fclk->rate / 1000; return 0; err2: omap_dm_timer_free(lirc_rx51->pulse_timer); err1: omap_dm_timer_free(lirc_rx51->pwm_timer); return retval; }
static void __init omap2_gp_clockevent_init(void) { u32 tick_rate; int src; inited = 1; gptimer = omap_dm_timer_request_specific(gptimer_id); BUG_ON(gptimer == NULL); #if defined(CONFIG_OMAP_32K_TIMER) src = OMAP_TIMER_SRC_32_KHZ; #else src = OMAP_TIMER_SRC_SYS_CLK; WARN(gptimer_id == 12, "WARNING: GPTIMER12 can only use the " "secure 32KiHz clock source\n"); #endif if (gptimer_id != 12) WARN(IS_ERR_VALUE(omap_dm_timer_set_source(gptimer, src)), "timer-gp: omap_dm_timer_set_source() failed\n"); tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer)); if (cpu_is_omap44xx()) /* Assuming 32kHz clk is driving GPT1 */ tick_rate = 32768; /* FIXME: */ pr_info("OMAP clockevent source: GPTIMER%d at %u Hz\n", gptimer_id, tick_rate); omap2_gp_timer_irq.dev_id = (void *)gptimer; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(tick_rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpumask_of(0); clockevents_register_device(&clockevent_gpt); }
static int __init omap4_setup_gpt2(void) { /* Set up GPT2 for the WA */ gptimer2 = omap_dm_timer_request_specific(2); BUG_ON(gptimer2 == NULL); printk(KERN_INFO "Enabling AXI2OCP errata Fix \n"); omap_dm_timer_set_source(gptimer2, OMAP_TIMER_SRC_32_KHZ); gpt2_timer_irq.dev_id = (void *)gptimer2; setup_irq(omap_dm_timer_get_irq(gptimer2), &gpt2_timer_irq); omap_dm_timer_set_int_enable(gptimer2, OMAP_TIMER_INT_OVERFLOW); /* * Timer reload value is used based on mpu @ 600 MHz * And hence bridge is at 300 MHz. 65K cycle = 216 uS * 6 * 1/32 kHz => ~187 us */ omap_dm_timer_set_load_start(gptimer2, 1, 0xffffff06); return 0; }
static void __init omap2_gp_clockevent_init(int gptimer_id, const char *fck_source, const char *property) { int res; clkev.errata = omap_dm_timer_get_errata(); /* * For clock-event timers we never read the timer counter and * so we are not impacted by errata i103 and i767. Therefore, * we can safely ignore this errata for clock-event timers. */ __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767); res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property, OMAP_TIMER_POSTED); BUG_ON(res); omap2_gp_timer_irq.dev_id = &clkev; setup_irq(clkev.irq, &omap2_gp_timer_irq); __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC, clockevent_gpt.shift); clockevent_gpt.max_delta_ns = clockevent_delta2ns(0xffffffff, &clockevent_gpt); clockevent_gpt.min_delta_ns = clockevent_delta2ns(3, &clockevent_gpt); /* Timer internal resynch latency. */ clockevent_gpt.cpumask = cpu_possible_mask; clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); clockevents_register_device(&clockevent_gpt); pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", gptimer_id, clkev.rate); }
static inline int omap_rproc_stop(struct rproc *rproc) { struct device *dev = rproc->dev; struct platform_device *pdev = to_platform_device(dev); struct omap_rproc_pdata *pdata = dev->platform_data; struct omap_rproc_timers_info *timers = pdata->timers; int ret, i; #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND _destroy_pm_flags(rproc); #endif if (rproc->secure_reset) { ret = rproc_drm_invoke_service(false); if (ret) dev_err(rproc->dev, "rproc_drm_invoke_service failed " "for secure disable ret = 0x%x\n", ret); rproc->secure_reset = false; } ret = omap_device_idle(pdev); if (ret) goto err; for (i = 0; i < pdata->timers_cnt; i++) { #ifdef CONFIG_REMOTEPROC_WATCHDOG /* GPT 9 & 11 (ipu); GPT 6 (dsp) are used as watchdog timers */ if ((!strcmp(rproc->name, "dsp") && timers[i].id == 6) || (!strcmp(rproc->name, "ipu") && (timers[i].id == DUCATI_WDT_TIMER_1 || timers[i].id == DUCATI_WDT_TIMER_2))) free_irq(omap_dm_timer_get_irq(timers[i].odt), rproc); #endif omap_dm_timer_free(timers[i].odt); timers[i].odt = NULL; } err: return ret; }
static int _init_gpt(void) { int irqno; int ret = 0; if ((gpt_pwm_list[IRBLASTER_PWM].timer = omap_dm_timer_request_specific(gpt_pwm_list[IRBLASTER_PWM].no)) == NULL) { printk(KERN_ERR "%s: failed to request dm-timer (%d)\n", gpt_pwm_list[IRBLASTER_PWM].name, gpt_pwm_list[IRBLASTER_PWM].no); return -ENODEV; } omap_dm_timer_set_source(gpt_pwm_list[IRBLASTER_PWM].timer, gpt_pwm_list[IRBLASTER_PWM].source); gpt_pwm_list[IRBLASTER_PWM].rate = clk_get_rate(omap_dm_timer_get_fclk(gpt_pwm_list[IRBLASTER_PWM].timer)); printk(KERN_DEBUG "%s (%d) timer rate is: %d\n", gpt_pwm_list[IRBLASTER_PWM].name, gpt_pwm_list[IRBLASTER_PWM].no, gpt_pwm_list[IRBLASTER_PWM].rate); if ((gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer = omap_dm_timer_request_specific(gpt_pwm_list[IRBLASTER_TIMER_CTRL].no)) == NULL) { printk(KERN_ERR "%s: failed to request dm-timer (%d)\n", gpt_pwm_list[IRBLASTER_TIMER_CTRL].name, gpt_pwm_list[IRBLASTER_TIMER_CTRL].no); omap_dm_timer_free(gpt_pwm_list[IRBLASTER_PWM].timer); return -ENODEV; } omap_dm_timer_set_source(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, gpt_pwm_list[IRBLASTER_TIMER_CTRL].source); gpt_pwm_list[IRBLASTER_TIMER_CTRL].rate = clk_get_rate(omap_dm_timer_get_fclk(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer)); printk(KERN_DEBUG "%s (%d) timer rate is: %d\n", gpt_pwm_list[IRBLASTER_TIMER_CTRL].name, gpt_pwm_list[IRBLASTER_TIMER_CTRL].no, gpt_pwm_list[IRBLASTER_TIMER_CTRL].rate); /* select irblaster configuration */ _select_irb_config(); /* enable timer clock */ omap_dm_timer_enable(gpt_pwm_list[IRBLASTER_PWM].timer); omap_dm_timer_enable(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); /* set modulation mod */ /* trigger on overflow and match */ omap_dm_timer_set_pwm(gpt_pwm_list[IRBLASTER_PWM].timer,0,1,2); omap_dm_timer_set_pwm(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, 0, 1, 2); //if ( gpt_pwm_list[IRBLASTER_TIMER_CTRL].mux_config ) // omap_cfg_reg(gpt_pwm_list[IRBLASTER_TIMER_CTRL].mux_config); irqno = omap_dm_timer_get_irq(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); if (request_irq(irqno, omap2_irblaster_timer_interrupt, IRQF_DISABLED, "gp timer", NULL)) { ret = -EBUSY; goto failed_request_irq; } omap_dm_timer_set_int_enable(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, IRBLASTER_TIMER_CTRL_IT_TYPE); /* disable timer clocks after init */ omap_dm_timer_disable(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); omap_dm_timer_disable(gpt_pwm_list[IRBLASTER_PWM].timer); init_waitqueue_head(&irb_wait); _gio_debug_init(); return 0; failed_request_irq: omap_dm_timer_free(gpt_pwm_list[IRBLASTER_PWM].timer); omap_dm_timer_free(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); return ret; }
static int __init pwm_start(void) { int ret = 0; struct clk *timer_fclk; uint32_t gt_rate; printk(KERN_INFO "Loading PWM Module... \n"); // request any timer timer_ptr = omap_dm_timer_request(); if(timer_ptr == NULL){ // no timers available printk("pwm module: No more gp timers available, bailing out\n"); return -1; } // set the clock source to the system clock ret = omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK); if(ret) { printk("pwm module: could not set source\n"); return -1; } // set prescalar to 1:1 omap_dm_timer_set_prescaler(timer_ptr, 0); // figure out what IRQ our timer triggers timer_irq = omap_dm_timer_get_irq(timer_ptr); // install our IRQ handler for our timer ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "pwm", timer_irq_handler); if(ret){ printk("pwm module: request_irq failed (on irq %d), bailing out\n", timer_irq); return ret; } // get clock rate in Hz and add it to struct timer_fclk = omap_dm_timer_get_fclk(timer_ptr); gt_rate = clk_get_rate(timer_fclk); pwm_data_ptr.timer_rate = gt_rate; // set preload, and autoreload // we set it to a default of 1kHz set_pwm_freq(1000); // setup timer to trigger IRQ on the overflow omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW); // start the timer omap_dm_timer_start(timer_ptr); // done! printk("pwm module: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq); // setup a GPIO pwm_setup_pin(38); pwm_data_ptr.pin = 38; set_pwm_dutycycle(1,150); // return success return 0; }