#include #include #include "gsc3280mac_timer.h" static void gsc3280mac_timer_handler(void *data) { struct net_device *dev = (struct net_device *)data; gsc3280mac_schedule(dev); } #define GSC3280MAC_TIMER_MSG(timer, freq) \ printk(KERN_INFO "gsc3280mac_timer: %s Timer ON (freq %dHz)\n", timer, freq); #if defined(CONFIG_GSC3280MAC_RTC_TIMER) #include static struct rtc_device *gsc3280mac_rtc; static rtc_task_t gsc3280mac_task; static void gsc3280mac_rtc_start(unsigned int new_freq) { rtc_irq_set_freq(gsc3280mac_rtc, &gsc3280mac_task, new_freq); rtc_irq_set_state(gsc3280mac_rtc, &gsc3280mac_task, 1); } static void gsc3280mac_rtc_stop(void) { rtc_irq_set_state(gsc3280mac_rtc, &gsc3280mac_task, 0); } int gsc3280mac_open_ext_timer(struct net_device *dev, struct gsc3280mac_timer *tm) { gsc3280mac_task.private_data = dev; gsc3280mac_task.func = gsc3280mac_timer_handler; gsc3280mac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (gsc3280mac_rtc == NULL) { pr_err("open rtc device failed\n"); return -ENODEV; } rtc_irq_register(gsc3280mac_rtc, &gsc3280mac_task); /* Periodic mode is not supported */ if ((rtc_irq_set_freq(gsc3280mac_rtc, &gsc3280mac_task, tm->freq) < 0)) { pr_err("set periodic failed\n"); rtc_irq_unregister(gsc3280mac_rtc, &gsc3280mac_task); rtc_class_close(gsc3280mac_rtc); return -1; } GSC3280MAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq); tm->timer_start = gsc3280mac_rtc_start; tm->timer_stop = gsc3280mac_rtc_stop; return 0; } int gsc3280mac_close_ext_timer(void) { rtc_irq_set_state(gsc3280mac_rtc, &gsc3280mac_task, 0); rtc_irq_unregister(gsc3280mac_rtc, &gsc3280mac_task); rtc_class_close(gsc3280mac_rtc); return 0; } #elif defined(CONFIG_GSC3280MAC_TMU_TIMER) #include #define TMU_CHANNEL "tmu2_clk" static struct clk *timer_clock; static void gsc3280mac_tmu_start(unsigned int new_freq) { clk_set_rate(timer_clock, new_freq); clk_enable(timer_clock); } static void gsc3280mac_tmu_stop(void) { clk_disable(timer_clock); } int gsc3280mac_open_ext_timer(struct net_device *dev, struct gsc3280mac_timer *tm) { timer_clock = clk_get(NULL, TMU_CHANNEL); if (timer_clock == NULL) return -1; if (tmu2_register_user(gsc3280mac_timer_handler, (void *)dev) < 0) { timer_clock = NULL; return -1; } GSC3280MAC_TIMER_MSG("TMU2", tm->freq); tm->timer_start = gsc3280mac_tmu_start; tm->timer_stop = gsc3280mac_tmu_stop; return 0; } int gsc3280mac_close_ext_timer(void) { clk_disable(timer_clock); tmu2_unregister_user(); clk_put(timer_clock); return 0; } #endif