diff options
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 95 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 1 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/omap-serial.h | 4 |
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 | } |
235 | EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific); | 244 | EXPORT_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 | */ | ||
255 | struct 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 | } | ||
296 | EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap); | ||
297 | |||
237 | int omap_dm_timer_free(struct omap_dm_timer *timer) | 298 | int 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 | ||
857 | static const struct of_device_id omap_timer_match[] = { | ||
858 | { .compatible = "ti,omap2-timer", }, | ||
859 | {}, | ||
860 | }; | ||
861 | MODULE_DEVICE_TABLE(of, omap_timer_match); | ||
862 | |||
783 | static struct platform_driver omap_dm_timer_driver = { | 863 | static 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 { | |||
100 | int omap_dm_timer_reserve_systimer(int id); | 100 | int omap_dm_timer_reserve_systimer(int id); |
101 | struct omap_dm_timer *omap_dm_timer_request(void); | 101 | struct omap_dm_timer *omap_dm_timer_request(void); |
102 | struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); | 102 | struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); |
103 | struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap); | ||
103 | int omap_dm_timer_free(struct omap_dm_timer *timer); | 104 | int omap_dm_timer_free(struct omap_dm_timer *timer); |
104 | void omap_dm_timer_enable(struct omap_dm_timer *timer); | 105 | void omap_dm_timer_enable(struct omap_dm_timer *timer); |
105 | void omap_dm_timer_disable(struct omap_dm_timer *timer); | 106 | void 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 |