aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig1
-rw-r--r--arch/arm/plat-omap/dmtimer.c95
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h1
-rw-r--r--arch/arm/plat-omap/include/plat/omap-serial.h4
4 files changed, 92 insertions, 9 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 7cd56ed5cd94..82fcb206b5b2 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -26,6 +26,7 @@ config ARCH_OMAP2PLUS
26 select CLKDEV_LOOKUP 26 select CLKDEV_LOOKUP
27 select GENERIC_IRQ_CHIP 27 select GENERIC_IRQ_CHIP
28 select OMAP_DM_TIMER 28 select OMAP_DM_TIMER
29 select PINCTRL
29 select PROC_DEVICETREE if PROC_FS 30 select PROC_DEVICETREE if PROC_FS
30 select SPARSE_IRQ 31 select SPARSE_IRQ
31 select USE_OF 32 select USE_OF
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 82231a75abd6..9dca23e4d6b0 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -40,6 +40,8 @@
40#include <linux/device.h> 40#include <linux/device.h>
41#include <linux/err.h> 41#include <linux/err.h>
42#include <linux/pm_runtime.h> 42#include <linux/pm_runtime.h>
43#include <linux/of.h>
44#include <linux/of_device.h>
43 45
44#include <plat/dmtimer.h> 46#include <plat/dmtimer.h>
45 47
@@ -209,6 +211,13 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
209 unsigned long flags; 211 unsigned long flags;
210 int ret = 0; 212 int ret = 0;
211 213
214 /* Requesting timer by ID is not supported when device tree is used */
215 if (of_have_populated_dt()) {
216 pr_warn("%s: Please use omap_dm_timer_request_by_cap()\n",
217 __func__);
218 return NULL;
219 }
220
212 spin_lock_irqsave(&dm_timer_lock, flags); 221 spin_lock_irqsave(&dm_timer_lock, flags);
213 list_for_each_entry(t, &omap_timer_list, node) { 222 list_for_each_entry(t, &omap_timer_list, node) {
214 if (t->pdev->id == id && !t->reserved) { 223 if (t->pdev->id == id && !t->reserved) {
@@ -234,6 +243,58 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id)
234} 243}
235EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific); 244EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
236 245
246/**
247 * omap_dm_timer_request_by_cap - Request a timer by capability
248 * @cap: Bit mask of capabilities to match
249 *
250 * Find a timer based upon capabilities bit mask. Callers of this function
251 * should use the definitions found in the plat/dmtimer.h file under the
252 * comment "timer capabilities used in hwmod database". Returns pointer to
253 * timer handle on success and a NULL pointer on failure.
254 */
255struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
256{
257 struct omap_dm_timer *timer = NULL, *t;
258 unsigned long flags;
259
260 if (!cap)
261 return NULL;
262
263 spin_lock_irqsave(&dm_timer_lock, flags);
264 list_for_each_entry(t, &omap_timer_list, node) {
265 if ((!t->reserved) && ((t->capability & cap) == cap)) {
266 /*
267 * If timer is not NULL, we have already found one timer
268 * but it was not an exact match because it had more
269 * capabilites that what was required. Therefore,
270 * unreserve the last timer found and see if this one
271 * is a better match.
272 */
273 if (timer)
274 timer->reserved = 0;
275
276 timer = t;
277 timer->reserved = 1;
278
279 /* Exit loop early if we find an exact match */
280 if (t->capability == cap)
281 break;
282 }
283 }
284 spin_unlock_irqrestore(&dm_timer_lock, flags);
285
286 if (timer && omap_dm_timer_prepare(timer)) {
287 timer->reserved = 0;
288 timer = NULL;
289 }
290
291 if (!timer)
292 pr_debug("%s: timer request failed!\n", __func__);
293
294 return timer;
295}
296EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
297
237int omap_dm_timer_free(struct omap_dm_timer *timer) 298int omap_dm_timer_free(struct omap_dm_timer *timer)
238{ 299{
239 if (unlikely(!timer)) 300 if (unlikely(!timer))
@@ -414,7 +475,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
414 * use the clock framework to set the parent clock. To be removed 475 * use the clock framework to set the parent clock. To be removed
415 * once OMAP1 migrated to using clock framework for dmtimers 476 * once OMAP1 migrated to using clock framework for dmtimers
416 */ 477 */
417 if (pdata->set_timer_src) 478 if (pdata && pdata->set_timer_src)
418 return pdata->set_timer_src(timer->pdev, source); 479 return pdata->set_timer_src(timer->pdev, source);
419 480
420 fclk = clk_get(&timer->pdev->dev, "fck"); 481 fclk = clk_get(&timer->pdev->dev, "fck");
@@ -696,7 +757,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
696 struct device *dev = &pdev->dev; 757 struct device *dev = &pdev->dev;
697 struct dmtimer_platform_data *pdata = pdev->dev.platform_data; 758 struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
698 759
699 if (!pdata) { 760 if (!pdata && !dev->of_node) {
700 dev_err(dev, "%s: no platform data.\n", __func__); 761 dev_err(dev, "%s: no platform data.\n", __func__);
701 return -ENODEV; 762 return -ENODEV;
702 } 763 }
@@ -725,12 +786,24 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
725 return -ENOMEM; 786 return -ENOMEM;
726 } 787 }
727 788
728 timer->id = pdev->id; 789 if (dev->of_node) {
790 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
791 timer->capability |= OMAP_TIMER_ALWON;
792 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
793 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
794 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
795 timer->capability |= OMAP_TIMER_HAS_PWM;
796 if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
797 timer->capability |= OMAP_TIMER_SECURE;
798 } else {
799 timer->id = pdev->id;
800 timer->capability = pdata->timer_capability;
801 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
802 timer->get_context_loss_count = pdata->get_context_loss_count;
803 }
804
729 timer->irq = irq->start; 805 timer->irq = irq->start;
730 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
731 timer->pdev = pdev; 806 timer->pdev = pdev;
732 timer->capability = pdata->timer_capability;
733 timer->get_context_loss_count = pdata->get_context_loss_count;
734 807
735 /* Skip pm_runtime_enable for OMAP1 */ 808 /* Skip pm_runtime_enable for OMAP1 */
736 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) { 809 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
@@ -770,7 +843,8 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
770 843
771 spin_lock_irqsave(&dm_timer_lock, flags); 844 spin_lock_irqsave(&dm_timer_lock, flags);
772 list_for_each_entry(timer, &omap_timer_list, node) 845 list_for_each_entry(timer, &omap_timer_list, node)
773 if (timer->pdev->id == pdev->id) { 846 if (!strcmp(dev_name(&timer->pdev->dev),
847 dev_name(&pdev->dev))) {
774 list_del(&timer->node); 848 list_del(&timer->node);
775 ret = 0; 849 ret = 0;
776 break; 850 break;
@@ -780,11 +854,18 @@ static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
780 return ret; 854 return ret;
781} 855}
782 856
857static const struct of_device_id omap_timer_match[] = {
858 { .compatible = "ti,omap2-timer", },
859 {},
860};
861MODULE_DEVICE_TABLE(of, omap_timer_match);
862
783static struct platform_driver omap_dm_timer_driver = { 863static struct platform_driver omap_dm_timer_driver = {
784 .probe = omap_dm_timer_probe, 864 .probe = omap_dm_timer_probe,
785 .remove = __devexit_p(omap_dm_timer_remove), 865 .remove = __devexit_p(omap_dm_timer_remove),
786 .driver = { 866 .driver = {
787 .name = "omap_timer", 867 .name = "omap_timer",
868 .of_match_table = of_match_ptr(omap_timer_match),
788 }, 869 },
789}; 870};
790 871
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index 3f5b9cfd9c0b..f8943c8f9dbf 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -100,6 +100,7 @@ struct dmtimer_platform_data {
100int omap_dm_timer_reserve_systimer(int id); 100int omap_dm_timer_reserve_systimer(int id);
101struct omap_dm_timer *omap_dm_timer_request(void); 101struct omap_dm_timer *omap_dm_timer_request(void);
102struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); 102struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
103struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
103int omap_dm_timer_free(struct omap_dm_timer *timer); 104int omap_dm_timer_free(struct omap_dm_timer *timer);
104void omap_dm_timer_enable(struct omap_dm_timer *timer); 105void omap_dm_timer_enable(struct omap_dm_timer *timer);
105void omap_dm_timer_disable(struct omap_dm_timer *timer); 106void omap_dm_timer_disable(struct omap_dm_timer *timer);
diff --git a/arch/arm/plat-omap/include/plat/omap-serial.h b/arch/arm/plat-omap/include/plat/omap-serial.h
index f4a4cd014795..1957a8516e93 100644
--- a/arch/arm/plat-omap/include/plat/omap-serial.h
+++ b/arch/arm/plat-omap/include/plat/omap-serial.h
@@ -40,10 +40,10 @@
40#define OMAP_UART_WER_MOD_WKUP 0X7F 40#define OMAP_UART_WER_MOD_WKUP 0X7F
41 41
42/* Enable XON/XOFF flow control on output */ 42/* Enable XON/XOFF flow control on output */
43#define OMAP_UART_SW_TX 0x8 43#define OMAP_UART_SW_TX 0x04
44 44
45/* Enable XON/XOFF flow control on input */ 45/* Enable XON/XOFF flow control on input */
46#define OMAP_UART_SW_RX 0x2 46#define OMAP_UART_SW_RX 0x04
47 47
48#define OMAP_UART_SYSC_RESET 0X07 48#define OMAP_UART_SYSC_RESET 0X07
49#define OMAP_UART_TCR_TRIG 0X0F 49#define OMAP_UART_TCR_TRIG 0X0F