From 0acce82b3dd792c85079ca1f4f7ffd8c82427e0a Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi <peter.ujfalusi@nokia.com> Date: Thu, 3 Jun 2010 07:39:32 +0300 Subject: OMAP: McBSP: Function to query the FIFO size Users of McBSP can use the omap_mcbsp_get_fifo_size function to query the size of the McBSP FIFO. The function will return the FIFO size in words (the HW maximum). Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolsfonmicro.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk> --- arch/arm/plat-omap/include/plat/mcbsp.h | 2 ++ arch/arm/plat-omap/mcbsp.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h index 975744f10a58..b4ff6a11a8f2 100644 --- a/arch/arm/plat-omap/include/plat/mcbsp.h +++ b/arch/arm/plat-omap/include/plat/mcbsp.h @@ -473,6 +473,7 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold); u16 omap_mcbsp_get_max_tx_threshold(unsigned int id); u16 omap_mcbsp_get_max_rx_threshold(unsigned int id); +u16 omap_mcbsp_get_fifo_size(unsigned int id); u16 omap_mcbsp_get_tx_delay(unsigned int id); u16 omap_mcbsp_get_rx_delay(unsigned int id); int omap_mcbsp_get_dma_op_mode(unsigned int id); @@ -483,6 +484,7 @@ static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { } static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; } +static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; } static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; } static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; } diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 7e669c9744d8..8bab0b28b7a3 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -560,6 +560,20 @@ u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold); +u16 omap_mcbsp_get_fifo_size(unsigned int id) +{ + struct omap_mcbsp *mcbsp; + + if (!omap_mcbsp_check_valid_id(id)) { + printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); + return -ENODEV; + } + mcbsp = id_to_mcbsp_ptr(id); + + return mcbsp->pdata->buffer_size; +} +EXPORT_SYMBOL(omap_mcbsp_get_fifo_size); + #define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ #define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ /* -- cgit v1.2.2 From 451fd82dc148bd5ac9ed5b19b6915a1afe32b9cb Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi <peter.ujfalusi@nokia.com> Date: Thu, 3 Jun 2010 07:39:33 +0300 Subject: OMAP3: McBSP: Change the way how the FIFO is handled Use the actual FIFO size in words as buffer_size on OMAP3. Change the threshold configuration to use 1 based numbering, when specifying the allowed threshold maximum or the McBSP threshold value. Set the default maximum threshold to (buffer_size - 0x10) intialy. >From users of McBSP, now it is expected to use this method. Asking for threshold 1 means that the value written to threshold registers are going to be 0, which means 1 word threshold. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolsfonmicro.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk> --- arch/arm/plat-omap/mcbsp.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 8bab0b28b7a3..4ef46047b787 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -481,9 +481,9 @@ int omap_st_is_enabled(unsigned int id) EXPORT_SYMBOL(omap_st_is_enabled); /* - * omap_mcbsp_set_tx_threshold configures how to deal - * with transmit threshold. the threshold value and handler can be - * configure in here. + * omap_mcbsp_set_rx_threshold configures the transmit threshold in words. + * The threshold parameter is 1 based, and it is converted (threshold - 1) + * for the THRSH2 register. */ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) { @@ -498,14 +498,15 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - MCBSP_WRITE(mcbsp, THRSH2, threshold); + if (threshold && threshold <= mcbsp->max_tx_thres) + MCBSP_WRITE(mcbsp, THRSH2, threshold - 1); } EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold); /* - * omap_mcbsp_set_rx_threshold configures how to deal - * with receive threshold. the threshold value and handler can be - * configure in here. + * omap_mcbsp_set_rx_threshold configures the receive threshold in words. + * The threshold parameter is 1 based, and it is converted (threshold - 1) + * for the THRSH1 register. */ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) { @@ -520,7 +521,8 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold) } mcbsp = id_to_mcbsp_ptr(id); - MCBSP_WRITE(mcbsp, THRSH1, threshold); + if (threshold && threshold <= mcbsp->max_rx_thres) + MCBSP_WRITE(mcbsp, THRSH1, threshold - 1); } EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold); @@ -1697,8 +1699,16 @@ static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) { mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; if (cpu_is_omap34xx()) { - mcbsp->max_tx_thres = max_thres(mcbsp); - mcbsp->max_rx_thres = max_thres(mcbsp); + /* + * Initially configure the maximum thresholds to a safe value. + * The McBSP FIFO usage with these values should not go under + * 16 locations. + * If the whole FIFO without safety buffer is used, than there + * is a possibility that the DMA will be not able to push the + * new data on time, causing channel shifts in runtime. + */ + mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10; + mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10; /* * REVISIT: Set dmap_op_mode to THRESHOLD as default * for mcbsp2 instances. -- cgit v1.2.2 From f10b8ad15f9531b6d58edabccf05e9eb738c4409 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi <peter.ujfalusi@nokia.com> Date: Thu, 3 Jun 2010 07:39:34 +0300 Subject: OMAP3: McBSP: Use the port's buffer_size when calculating tx delay Sicne the platform data's buffer_size now holds the full size of the FIFO, there is no longer need to handle the ports differently. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolsfonmicro.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk> --- arch/arm/plat-omap/mcbsp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index 4ef46047b787..e31496e35b0f 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -576,8 +576,6 @@ u16 omap_mcbsp_get_fifo_size(unsigned int id) } EXPORT_SYMBOL(omap_mcbsp_get_fifo_size); -#define MCBSP2_FIFO_SIZE 0x500 /* 1024 + 256 locations */ -#define MCBSP1345_FIFO_SIZE 0x80 /* 128 locations */ /* * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO */ @@ -596,10 +594,7 @@ u16 omap_mcbsp_get_tx_delay(unsigned int id) buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); /* Number of slots are different in McBSP ports */ - if (mcbsp->id == 2) - return MCBSP2_FIFO_SIZE - buffstat; - else - return MCBSP1345_FIFO_SIZE - buffstat; + return mcbsp->pdata->buffer_size - buffstat; } EXPORT_SYMBOL(omap_mcbsp_get_tx_delay); -- cgit v1.2.2 From a1a54456d08ff8d406b550b60f97088ac7401b8c Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> Date: Thu, 13 May 2010 09:45:35 +0300 Subject: omap iommu: Introduce iopgd_is_table MACRO A bit more strict comparison. Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/iommu.c | 8 ++++---- arch/arm/plat-omap/iopgtable.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index bc094dbacee6..341c48179ee0 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -653,7 +653,7 @@ void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte) if (!*iopgd) goto out; - if (*iopgd & IOPGD_TABLE) + if (iopgd_is_table(*iopgd)) iopte = iopte_offset(iopgd, da); out: *ppgd = iopgd; @@ -670,7 +670,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da) if (!*iopgd) return 0; - if (*iopgd & IOPGD_TABLE) { + if (iopgd_is_table(*iopgd)) { int i; u32 *iopte = iopte_offset(iopgd, da); @@ -745,7 +745,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj) if (!*iopgd) continue; - if (*iopgd & IOPGD_TABLE) + if (iopgd_is_table(*iopgd)) iopte_free(iopte_offset(iopgd, 0)); *iopgd = 0; @@ -785,7 +785,7 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) iopgd = iopgd_offset(obj, da); - if (!(*iopgd & IOPGD_TABLE)) { + if (!iopgd_is_table(*iopgd)) { dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, da, iopgd, *iopgd); return IRQ_NONE; diff --git a/arch/arm/plat-omap/iopgtable.h b/arch/arm/plat-omap/iopgtable.h index ab23b6a140fd..f2e6b64cca64 100644 --- a/arch/arm/plat-omap/iopgtable.h +++ b/arch/arm/plat-omap/iopgtable.h @@ -63,6 +63,8 @@ #define IOPGD_SECTION (2 << 0) #define IOPGD_SUPER (1 << 18 | 2 << 0) +#define iopgd_is_table(x) (((x) & 3) == IOPGD_TABLE) + #define IOPTE_SMALL (2 << 0) #define IOPTE_LARGE (1 << 0) -- cgit v1.2.2 From 124933599a11cab4b77a6d79d49312754e8ff88e Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> Date: Thu, 13 May 2010 09:46:44 +0300 Subject: omap iommu: Rename iopte_[p,v]addr -> iopte_page_[p,v]addr Follow Linux pagetable accessor name convention. Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/iopgtable.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/iopgtable.h b/arch/arm/plat-omap/iopgtable.h index f2e6b64cca64..c3e93bb0911f 100644 --- a/arch/arm/plat-omap/iopgtable.h +++ b/arch/arm/plat-omap/iopgtable.h @@ -72,12 +72,12 @@ #define iopgd_index(da) (((da) >> IOPGD_SHIFT) & (PTRS_PER_IOPGD - 1)) #define iopgd_offset(obj, da) ((obj)->iopgd + iopgd_index(da)) -#define iopte_paddr(iopgd) (*iopgd & ~((1 << 10) - 1)) -#define iopte_vaddr(iopgd) ((u32 *)phys_to_virt(iopte_paddr(iopgd))) +#define iopgd_page_paddr(iopgd) (*iopgd & ~((1 << 10) - 1)) +#define iopgd_page_vaddr(iopgd) ((u32 *)phys_to_virt(iopgd_page_paddr(iopgd))) /* to find an entry in the second-level page table. */ #define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1)) -#define iopte_offset(iopgd, da) (iopte_vaddr(iopgd) + iopte_index(da)) +#define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da)) static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa, u32 flags) -- cgit v1.2.2 From ddfa975a8cf66753a7d829bada753c3617628486 Mon Sep 17 00:00:00 2001 From: "Kanigeri, Hari" <h-kanigeri2@ti.com> Date: Mon, 24 May 2010 02:01:51 +0000 Subject: omap iommu: add functionality to get TLB miss interrupt In order to enable TLB miss interrupt, the TWL should be disabled. This patch provides the functionality to get the MMU fault interrupt for a TLB miss in the cases where the users are working with the locked TLB entries and with TWL disabled. New interface is added to select twl and to enable TLB miss interrupt. Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com> Signed-off-by: Ramesh Gupta <grgupta@ti.com> Signed-off-by: Hiroshi Doyu <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/include/plat/iommu.h | 2 ++ arch/arm/plat-omap/iommu.c | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h index 0752af9d099e..33c7d41cb6a5 100644 --- a/arch/arm/plat-omap/include/plat/iommu.h +++ b/arch/arm/plat-omap/include/plat/iommu.h @@ -80,6 +80,7 @@ struct iommu_functions { int (*enable)(struct iommu *obj); void (*disable)(struct iommu *obj); + void (*set_twl)(struct iommu *obj, bool on); u32 (*fault_isr)(struct iommu *obj, u32 *ra); void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr); @@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e); extern u32 iotlb_cr_to_virt(struct cr_regs *cr); extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e); +extern void iommu_set_twl(struct iommu *obj, bool on); extern void flush_iotlb_page(struct iommu *obj, u32 da); extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end); extern void flush_iotlb_all(struct iommu *obj); diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 341c48179ee0..688ae66bb8fc 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj) } EXPORT_SYMBOL_GPL(flush_iotlb_all); +/** + * iommu_set_twl - enable/disable table walking logic + * @obj: target iommu + * @on: enable/disable + * + * Function used to enable/disable TWL. If one wants to work + * exclusively with locked TLB entries and receive notifications + * for TLB miss then call this function to disable TWL. + */ +void iommu_set_twl(struct iommu *obj, bool on) +{ + clk_enable(obj->clk); + arch_iommu->set_twl(obj, on); + clk_disable(obj->clk); +} +EXPORT_SYMBOL_GPL(iommu_set_twl); + #if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE) ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes) -- cgit v1.2.2 From 37b298100f0ff8b954217635504c860cdb040ccf Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> Date: Mon, 24 May 2010 02:01:52 +0000 Subject: omap iommu: move iommu_disable at fault to the above layer The function prefix "omap2_iommu_" indicates that the prefixed function belongs to "omap2_iommu_ops" to provide iommu basic functionalities for the above layers. It's better to avoid the prefixed function called in the same prefixed ones internally, like nested here. Now "iommu_disable" is called just after fault_isr() in the above layer. This is a little bit more sensible to keep the consistency of module layers. Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/iommu.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c index 688ae66bb8fc..a202a2ce6e3d 100644 --- a/arch/arm/plat-omap/iommu.c +++ b/arch/arm/plat-omap/iommu.c @@ -800,6 +800,8 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) if (!stat) return IRQ_HANDLED; + iommu_disable(obj); + iopgd = iopgd_offset(obj, da); if (!iopgd_is_table(*iopgd)) { -- cgit v1.2.2 From dba638d22d5af5486a861e08ab46e57abef7049a Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:28 +0300 Subject: omap: Separate out omap2 FS USB platform init functions We want to split old FS USB platform init code and stop doing pin multiplexing under plat-omap. First move 24xx specific init code into omap2_usb[012]_init functions. Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/usb.c | 252 +++++++++++++++++++++++++++++------------------ 1 file changed, 157 insertions(+), 95 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index d3bf17cd36f3..9c4929a33e52 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -115,15 +115,56 @@ static void omap2_usb2_enable_5pinunitll(void) omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); } +static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device) +{ + u32 syscon1 = 0; + + omap2_usb_devconf_clear(0, USB_BIDIR_TLL); + + if (nwires == 0) + return 0; + + if (is_device) + omap_cfg_reg(J20_24XX_USB0_PUEN); + + omap_cfg_reg(K18_24XX_USB0_DAT); + omap_cfg_reg(K19_24XX_USB0_TXEN); + omap_cfg_reg(J14_24XX_USB0_SE0); + if (nwires != 3) + omap_cfg_reg(J18_24XX_USB0_RCV); + + switch (nwires) { + case 3: + syscon1 = 2; + omap2_usb_devconf_set(0, USB_BIDIR); + break; + case 4: + syscon1 = 1; + omap2_usb_devconf_set(0, USB_BIDIR); + break; + case 6: + syscon1 = 3; + omap_cfg_reg(J19_24XX_USB0_VP); + omap_cfg_reg(K20_24XX_USB0_VM); + omap2_usb_devconf_set(0, USB_UNIDIR); + break; + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 0, nwires); + } + + return syscon1 << 16; +} + static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) { u32 syscon1 = 0; if (cpu_is_omap24xx()) - omap2_usb_devconf_clear(0, USB_BIDIR_TLL); + return omap2_usb0_init(nwires, is_device); if (nwires == 0) { - if (cpu_class_is_omap1() && !cpu_is_omap15xx()) { + if (!cpu_is_omap15xx()) { u32 l; /* pulldown D+/D- */ @@ -135,9 +176,7 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) } if (is_device) { - if (cpu_is_omap24xx()) - omap_cfg_reg(J20_24XX_USB0_PUEN); - else if (cpu_is_omap7xx()) { + if (cpu_is_omap7xx()) { omap_cfg_reg(AA17_7XX_USB_DM); omap_cfg_reg(W16_7XX_USB_PU_EN); omap_cfg_reg(W17_7XX_USB_VBUSI); @@ -147,8 +186,7 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) omap_cfg_reg(W4_USB_PUEN); } - /* internal transceiver (unavailable on 17xx, 24xx) */ - if (!cpu_class_is_omap2() && nwires == 2) { + if (nwires == 2) { u32 l; // omap_cfg_reg(P9_USB_DP); @@ -183,26 +221,18 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) return 0; } - if (cpu_is_omap24xx()) { - omap_cfg_reg(K18_24XX_USB0_DAT); - omap_cfg_reg(K19_24XX_USB0_TXEN); - omap_cfg_reg(J14_24XX_USB0_SE0); - if (nwires != 3) - omap_cfg_reg(J18_24XX_USB0_RCV); - } else { - omap_cfg_reg(V6_USB0_TXD); - omap_cfg_reg(W9_USB0_TXEN); - omap_cfg_reg(W5_USB0_SE0); - if (nwires != 3) - omap_cfg_reg(Y5_USB0_RCV); - } + omap_cfg_reg(V6_USB0_TXD); + omap_cfg_reg(W9_USB0_TXEN); + omap_cfg_reg(W5_USB0_SE0); + if (nwires != 3) + omap_cfg_reg(Y5_USB0_RCV); /* NOTE: SPEED and SUSP aren't configured here. OTG hosts * may be able to use I2C requests to set those bits along * with VBUS switching and overcurrent detection. */ - if (cpu_class_is_omap1() && nwires != 6) { + if (nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); @@ -213,21 +243,13 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) switch (nwires) { case 3: syscon1 = 2; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(0, USB_BIDIR); break; case 4: syscon1 = 1; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(0, USB_BIDIR); break; case 6: syscon1 = 3; - if (cpu_is_omap24xx()) { - omap_cfg_reg(J19_24XX_USB0_VP); - omap_cfg_reg(K20_24XX_USB0_VM); - omap2_usb_devconf_set(0, USB_UNIDIR); - } else { + { u32 l; omap_cfg_reg(AA9_USB0_VP); @@ -244,30 +266,66 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) return syscon1 << 16; } +static u32 __init omap2_usb1_init(unsigned nwires) +{ + u32 syscon1 = 0; + + omap2_usb_devconf_clear(1, USB_BIDIR_TLL); + + if (nwires == 0) + return 0; + + /* NOTE: board-specific code must set up pin muxing for usb1, + * since each signal could come out on either of two balls. + */ + + switch (nwires) { + case 2: + /* NOTE: board-specific code must override this setting if + * this TLL link is not using DP/DM + */ + syscon1 = 1; + omap2_usb_devconf_set(1, USB_BIDIR_TLL); + break; + case 3: + syscon1 = 2; + omap2_usb_devconf_set(1, USB_BIDIR); + break; + case 4: + syscon1 = 1; + omap2_usb_devconf_set(1, USB_BIDIR); + break; + case 6: + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 1, nwires); + } + + return syscon1 << 20; +} + static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { + if (cpu_is_omap24xx()) + return omap2_usb1_init(nwires); + + if (!cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); l &= ~CONF_USB1_UNI_R; omap_writel(l, USB_TRANSCEIVER_CTRL); } - if (cpu_is_omap24xx()) - omap2_usb_devconf_clear(1, USB_BIDIR_TLL); - if (nwires == 0) return 0; /* external transceiver */ - if (cpu_class_is_omap1()) { - omap_cfg_reg(USB1_TXD); - omap_cfg_reg(USB1_TXEN); - if (nwires != 3) - omap_cfg_reg(USB1_RCV); - } + omap_cfg_reg(USB1_TXD); + omap_cfg_reg(USB1_TXEN); + if (nwires != 3) + omap_cfg_reg(USB1_RCV); if (cpu_is_omap15xx()) { omap_cfg_reg(USB1_SEO); @@ -280,10 +338,6 @@ static u32 __init omap_usb1_init(unsigned nwires) } else if (cpu_is_omap1710()) { omap_cfg_reg(R13_1710_USB1_SE0); // SUSP - } else if (cpu_is_omap24xx()) { - /* NOTE: board-specific code must set up pin muxing for usb1, - * since each signal could come out on either of two balls. - */ } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; @@ -291,27 +345,14 @@ static u32 __init omap_usb1_init(unsigned nwires) switch (nwires) { case 2: - if (!cpu_is_omap24xx()) - goto bad; - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(1, USB_BIDIR_TLL); - break; + goto bad; case 3: syscon1 = 2; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(1, USB_BIDIR); break; case 4: syscon1 = 1; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(1, USB_BIDIR); break; case 6: - if (cpu_is_omap24xx()) - goto bad; syscon1 = 3; omap_cfg_reg(USB1_VP); omap_cfg_reg(USB1_VM); @@ -331,20 +372,70 @@ bad: return syscon1 << 20; } -static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) +static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup) { u32 syscon1 = 0; - if (cpu_is_omap24xx()) { - omap2_usb2_disable_5pinbitll(); - alt_pingroup = 0; + omap2_usb2_disable_5pinbitll(); + alt_pingroup = 0; + + /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ + if (alt_pingroup || nwires == 0) + return 0; + + omap_cfg_reg(Y11_24XX_USB2_DAT); + omap_cfg_reg(AA10_24XX_USB2_SE0); + if (nwires > 2) + omap_cfg_reg(AA12_24XX_USB2_TXEN); + if (nwires > 3) + omap_cfg_reg(AA6_24XX_USB2_RCV); + + switch (nwires) { + case 2: + /* NOTE: board-specific code must override this setting if + * this TLL link is not using DP/DM + */ + syscon1 = 1; + omap2_usb_devconf_set(2, USB_BIDIR_TLL); + break; + case 3: + syscon1 = 2; + omap2_usb_devconf_set(2, USB_BIDIR); + break; + case 4: + syscon1 = 1; + omap2_usb_devconf_set(2, USB_BIDIR); + break; + case 5: + omap_cfg_reg(AA4_24XX_USB2_TLLSE0); + /* NOTE: board-specific code must override this setting if + * this TLL link is not using DP/DM. Something must also + * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} + */ + syscon1 = 3; + omap2_usb2_enable_5pinunitll(); + break; + case 6: + default: + printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", + 2, nwires); } + return syscon1 << 24; +} + +static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) +{ + u32 syscon1 = 0; + + if (cpu_is_omap24xx()) + return omap2_usb2_init(nwires, alt_pingroup); + /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ if (alt_pingroup || nwires == 0) return 0; - if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) { + if (!cpu_is_omap15xx() && nwires != 6) { u32 l; l = omap_readl(USB_TRANSCEIVER_CTRL); @@ -367,53 +458,24 @@ static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) if (nwires != 3) omap_cfg_reg(Y5_USB2_RCV); // FIXME omap_cfg_reg(USB2_SPEED); - } else if (cpu_is_omap24xx()) { - omap_cfg_reg(Y11_24XX_USB2_DAT); - omap_cfg_reg(AA10_24XX_USB2_SE0); - if (nwires > 2) - omap_cfg_reg(AA12_24XX_USB2_TXEN); - if (nwires > 3) - omap_cfg_reg(AA6_24XX_USB2_RCV); } else { pr_debug("usb%d cpu unrecognized\n", 1); return 0; } - // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP); + // omap_cfg_reg(USB2_SUSP); switch (nwires) { case 2: - if (!cpu_is_omap24xx()) - goto bad; - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(2, USB_BIDIR_TLL); - break; + goto bad; case 3: syscon1 = 2; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(2, USB_BIDIR); break; case 4: syscon1 = 1; - if (cpu_is_omap24xx()) - omap2_usb_devconf_set(2, USB_BIDIR); break; case 5: - if (!cpu_is_omap24xx()) - goto bad; - omap_cfg_reg(AA4_24XX_USB2_TLLSE0); - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM. Something must also - * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} - */ - syscon1 = 3; - omap2_usb2_enable_5pinunitll(); - break; + goto bad; case 6: - if (cpu_is_omap24xx()) - goto bad; syscon1 = 3; if (cpu_is_omap15xx()) { omap_cfg_reg(USB2_VP); -- cgit v1.2.2 From b5e8905bcd7a794b667f6d5eabcb036f25358fdb Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:29 +0300 Subject: omap: Move omap2 FS USB platform init code into mach-omap2/usb-fs.c Move omap2 FS USB platform init code into mach-omap2/usb-fs.c. This will allow further work later on to use omap hwmod for initializing the device. Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/board.h | 8 + arch/arm/plat-omap/include/plat/usb.h | 7 + arch/arm/plat-omap/usb.c | 267 ++++++++------------------------ 3 files changed, 79 insertions(+), 203 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h index 5cd622039da0..3cf4fa25ab3d 100644 --- a/arch/arm/plat-omap/include/plat/board.h +++ b/arch/arm/plat-omap/include/plat/board.h @@ -85,6 +85,14 @@ struct omap_usb_config { * 6 == 6 wire unidirectional (or TLL) */ u8 pins[3]; + + struct platform_device *udc_device; + struct platform_device *ohci_device; + struct platform_device *otg_device; + + u32 (*usb0_init)(unsigned nwires, unsigned is_device); + u32 (*usb1_init)(unsigned nwires); + u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup); }; struct omap_lcd_config { diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 98eef5360e6d..9f792244e77c 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -81,7 +81,14 @@ extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata); #endif +void omap_otg_init(struct omap_usb_config *config); void omap_usb_init(struct omap_usb_config *pdata); +void omap2_usbfs_init(struct omap_usb_config *pdata); +#else +static inline omap2_usbfs_init(struct omap_usb_config *pdata) +{ +} +#endif /*-------------------------------------------------------------------------*/ diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index 9c4929a33e52..27b471ce11a0 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -38,25 +38,12 @@ #include <plat/usb.h> #include <plat/board.h> -#ifdef CONFIG_ARCH_OMAP1 - #define INT_USB_IRQ_GEN IH2_BASE + 20 #define INT_USB_IRQ_NISO IH2_BASE + 30 #define INT_USB_IRQ_ISO IH2_BASE + 29 #define INT_USB_IRQ_HGEN INT_USB_HHC_1 #define INT_USB_IRQ_OTG IH2_BASE + 8 -#else - -#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN -#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO -#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO -#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN -#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG - -#endif - - /* These routines should handle the standard chip-specific modes * for usb0/1/2 ports, covering basic mux and transceiver setup. * @@ -79,90 +66,10 @@ #if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) -static void omap2_usb_devconf_clear(u8 port, u32 mask) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r &= ~USBTXWRMODEI(port, mask); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb_devconf_set(u8 port, u32 mask) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r |= USBTXWRMODEI(port, mask); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_disable_5pinbitll(void) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI); - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static void omap2_usb2_enable_5pinunitll(void) -{ - u32 r; - - r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); - r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI; - omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0); -} - -static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device) -{ - u32 syscon1 = 0; - - omap2_usb_devconf_clear(0, USB_BIDIR_TLL); - - if (nwires == 0) - return 0; - - if (is_device) - omap_cfg_reg(J20_24XX_USB0_PUEN); - - omap_cfg_reg(K18_24XX_USB0_DAT); - omap_cfg_reg(K19_24XX_USB0_TXEN); - omap_cfg_reg(J14_24XX_USB0_SE0); - if (nwires != 3) - omap_cfg_reg(J18_24XX_USB0_RCV); - - switch (nwires) { - case 3: - syscon1 = 2; - omap2_usb_devconf_set(0, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(0, USB_BIDIR); - break; - case 6: - syscon1 = 3; - omap_cfg_reg(J19_24XX_USB0_VP); - omap_cfg_reg(K20_24XX_USB0_VM); - omap2_usb_devconf_set(0, USB_UNIDIR); - break; - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 0, nwires); - } - - return syscon1 << 16; -} - static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) { u32 syscon1 = 0; - if (cpu_is_omap24xx()) - return omap2_usb0_init(nwires, is_device); - if (nwires == 0) { if (!cpu_is_omap15xx()) { u32 l; @@ -266,51 +173,10 @@ static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) return syscon1 << 16; } -static u32 __init omap2_usb1_init(unsigned nwires) -{ - u32 syscon1 = 0; - - omap2_usb_devconf_clear(1, USB_BIDIR_TLL); - - if (nwires == 0) - return 0; - - /* NOTE: board-specific code must set up pin muxing for usb1, - * since each signal could come out on either of two balls. - */ - - switch (nwires) { - case 2: - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(1, USB_BIDIR_TLL); - break; - case 3: - syscon1 = 2; - omap2_usb_devconf_set(1, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(1, USB_BIDIR); - break; - case 6: - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 1, nwires); - } - - return syscon1 << 20; -} - static u32 __init omap_usb1_init(unsigned nwires) { u32 syscon1 = 0; - if (cpu_is_omap24xx()) - return omap2_usb1_init(nwires); - if (!cpu_is_omap15xx() && nwires != 6) { u32 l; @@ -372,65 +238,10 @@ bad: return syscon1 << 20; } -static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup) -{ - u32 syscon1 = 0; - - omap2_usb2_disable_5pinbitll(); - alt_pingroup = 0; - - /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ - if (alt_pingroup || nwires == 0) - return 0; - - omap_cfg_reg(Y11_24XX_USB2_DAT); - omap_cfg_reg(AA10_24XX_USB2_SE0); - if (nwires > 2) - omap_cfg_reg(AA12_24XX_USB2_TXEN); - if (nwires > 3) - omap_cfg_reg(AA6_24XX_USB2_RCV); - - switch (nwires) { - case 2: - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM - */ - syscon1 = 1; - omap2_usb_devconf_set(2, USB_BIDIR_TLL); - break; - case 3: - syscon1 = 2; - omap2_usb_devconf_set(2, USB_BIDIR); - break; - case 4: - syscon1 = 1; - omap2_usb_devconf_set(2, USB_BIDIR); - break; - case 5: - omap_cfg_reg(AA4_24XX_USB2_TLLSE0); - /* NOTE: board-specific code must override this setting if - * this TLL link is not using DP/DM. Something must also - * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED} - */ - syscon1 = 3; - omap2_usb2_enable_5pinunitll(); - break; - case 6: - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 2, nwires); - } - - return syscon1 << 24; -} - static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) { u32 syscon1 = 0; - if (cpu_is_omap24xx()) - return omap2_usb2_init(nwires, alt_pingroup); - /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ if (alt_pingroup || nwires == 0) return 0; @@ -498,6 +309,10 @@ bad: return syscon1 << 24; } +#else +#define omap_usb0_init NULL +#define omap_usb1_init NULL +#define omap_usb2_init NULL #endif /*-------------------------------------------------------------------------*/ @@ -535,6 +350,17 @@ static struct platform_device udc_device = { .resource = udc_resources, }; +static inline void udc_device_init(struct omap_usb_config *pdata) +{ + pdata->udc_device = &udc_device; +} + +#else + +static inline void udc_device_init(struct omap_usb_config *pdata) +{ +} + #endif #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) @@ -565,6 +391,17 @@ static struct platform_device ohci_device = { .resource = ohci_resources, }; +static inline void ohci_device_init(struct omap_usb_config *pdata) +{ + pdata->ohci_device = &ohci_device; +} + +#else + +static inline void ohci_device_init(struct omap_usb_config *pdata) +{ +} + #endif #if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) @@ -588,6 +425,17 @@ static struct platform_device otg_device = { .resource = otg_resources, }; +static inline void otg_device_init(struct omap_usb_config *pdata) +{ + pdata->otg_device = &otg_device; +} + +#else + +static inline void otg_device_init(struct omap_usb_config *pdata) +{ +} + #endif /*-------------------------------------------------------------------------*/ @@ -622,9 +470,9 @@ omap_otg_init(struct omap_usb_config *config) /* pin muxing and transceiver pinouts */ if (config->pins[0] > 2) /* alt pingroup 2 */ alt_pingroup = 1; - syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config)); - syscon |= omap_usb1_init(config->pins[1]); - syscon |= omap_usb2_init(config->pins[2], alt_pingroup); + syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); + syscon |= config->usb1_init(config->pins[1]); + syscon |= config->usb2_init(config->pins[2], alt_pingroup); pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); omap_writel(syscon, OTG_SYSCON_1); @@ -672,15 +520,17 @@ omap_otg_init(struct omap_usb_config *config) #ifdef CONFIG_USB_GADGET_OMAP if (config->otg || config->register_dev) { + struct platform_device *udc_device = config->udc_device; + syscon &= ~DEV_IDLE_EN; - udc_device.dev.platform_data = config; + udc_device->dev.platform_data = config; /* IRQ numbers for omap7xx */ if(cpu_is_omap7xx()) { udc_resources[1].start = INT_7XX_USB_GENI; udc_resources[2].start = INT_7XX_USB_NON_ISO; udc_resources[3].start = INT_7XX_USB_ISO; } - status = platform_device_register(&udc_device); + status = platform_device_register(udc_device); if (status) pr_debug("can't register UDC device, %d\n", status); } @@ -688,11 +538,13 @@ omap_otg_init(struct omap_usb_config *config) #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) if (config->otg || config->register_host) { + struct platform_device *ohci_device = config->ohci_device; + syscon &= ~HST_IDLE_EN; - ohci_device.dev.platform_data = config; + ohci_device->dev.platform_data = config; if (cpu_is_omap7xx()) ohci_resources[1].start = INT_7XX_USB_HHC_1; - status = platform_device_register(&ohci_device); + status = platform_device_register(ohci_device); if (status) pr_debug("can't register OHCI device, %d\n", status); } @@ -700,11 +552,13 @@ omap_otg_init(struct omap_usb_config *config) #ifdef CONFIG_USB_OTG if (config->otg) { + struct platform_device *otg_device = config->otg_device; + syscon &= ~OTG_IDLE_EN; - otg_device.dev.platform_data = config; + otg_device->dev.platform_data = config; if (cpu_is_omap7xx()) otg_resources[1].start = INT_7XX_USB_OTG; - status = platform_device_register(&otg_device); + status = platform_device_register(otg_device); if (status) pr_debug("can't register OTG device, %d\n", status); } @@ -716,7 +570,7 @@ omap_otg_init(struct omap_usb_config *config) } #else -static inline void omap_otg_init(struct omap_usb_config *config) {} +void omap_otg_init(struct omap_usb_config *config) {} #endif /*-------------------------------------------------------------------------*/ @@ -737,9 +591,9 @@ static void __init omap_1510_usb_init(struct omap_usb_config *config) unsigned int val; u16 w; - omap_usb0_init(config->pins[0], is_usb0_device(config)); - omap_usb1_init(config->pins[1]); - omap_usb2_init(config->pins[2], 0); + config->usb0_init(config->pins[0], is_usb0_device(config)); + config->usb1_init(config->pins[1]); + config->usb2_init(config->pins[2], 0); val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); val |= (config->hmc_mode << 1); @@ -807,7 +661,14 @@ static inline void omap_1510_usb_init(struct omap_usb_config *config) {} void __init omap_usb_init(struct omap_usb_config *pdata) { - if (cpu_is_omap7xx() || cpu_is_omap16xx() || cpu_is_omap24xx()) + pdata->usb0_init = omap_usb0_init; + pdata->usb1_init = omap_usb1_init; + pdata->usb2_init = omap_usb2_init; + udc_device_init(pdata); + ohci_device_init(pdata); + otg_device_init(pdata); + + if (cpu_is_omap7xx() || cpu_is_omap16xx()) omap_otg_init(pdata); else if (cpu_is_omap15xx()) omap_1510_usb_init(pdata); -- cgit v1.2.2 From dd0cdd888251d0d62df417d6859e74e57146c13f Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:30 +0300 Subject: omap: Move omap1 USB platform init code into mach-omap1/usb.c Move omap1 FS USB platform init code into mach-omap1/usb.c Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/usb.h | 42 ++- arch/arm/plat-omap/usb.c | 535 ---------------------------------- 2 files changed, 41 insertions(+), 536 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 9f792244e77c..2a9427c8cc48 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -81,8 +81,28 @@ extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata); #endif + +/* + * FIXME correct answer depends on hmc_mode, + * as does (on omap1) any nonzero value for config->otg port number + */ +#ifdef CONFIG_USB_GADGET_OMAP +#define is_usb0_device(config) 1 +#else +#define is_usb0_device(config) 0 +#endif + void omap_otg_init(struct omap_usb_config *config); -void omap_usb_init(struct omap_usb_config *pdata); + +#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE) +void omap1_usb_init(struct omap_usb_config *pdata); +#else +static inline void omap1_usb_init(struct omap_usb_config *pdata) +{ +} +#endif + +#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE) void omap2_usbfs_init(struct omap_usb_config *pdata); #else static inline omap2_usbfs_init(struct omap_usb_config *pdata) @@ -199,4 +219,24 @@ static inline omap2_usbfs_init(struct omap_usb_config *pdata) # define USB0PUENACTLOI (1 << 16) # define USBSTANDBYCTRL (1 << 15) +#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB) +u32 omap1_usb0_init(unsigned nwires, unsigned is_device); +u32 omap1_usb1_init(unsigned nwires); +u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup); +#else +static inline u32 omap1_usb0_init(unsigned nwires, unsigned is_device) +{ + return 0; +} +static inline u32 omap1_usb1_init(unsigned nwires) +{ + return 0; + +} +static inline u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup) +{ + return 0; +} +#endif + #endif /* __ASM_ARCH_OMAP_USB_H */ diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c index 27b471ce11a0..f3570884883e 100644 --- a/arch/arm/plat-omap/usb.c +++ b/arch/arm/plat-omap/usb.c @@ -22,434 +22,13 @@ #include <linux/module.h> #include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/usb/otg.h> #include <linux/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <mach/hardware.h> - -#include <plat/control.h> -#include <plat/mux.h> #include <plat/usb.h> #include <plat/board.h> -#define INT_USB_IRQ_GEN IH2_BASE + 20 -#define INT_USB_IRQ_NISO IH2_BASE + 30 -#define INT_USB_IRQ_ISO IH2_BASE + 29 -#define INT_USB_IRQ_HGEN INT_USB_HHC_1 -#define INT_USB_IRQ_OTG IH2_BASE + 8 - -/* These routines should handle the standard chip-specific modes - * for usb0/1/2 ports, covering basic mux and transceiver setup. - * - * Some board-*.c files will need to set up additional mux options, - * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. - */ - -/* TESTED ON: - * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables - * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables - * - 5912 OSK UDC, with *nonstandard* A-to-A cable - * - 1510 Innovator UDC with bundled usb0 cable - * - 1510 Innovator OHCI with bundled usb1/usb2 cable - * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS - * - 1710 custom development board using alternate pin group - * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables - */ - -/*-------------------------------------------------------------------------*/ - -#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX) - -static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device) -{ - u32 syscon1 = 0; - - if (nwires == 0) { - if (!cpu_is_omap15xx()) { - u32 l; - - /* pulldown D+/D- */ - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~(3 << 1); - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - return 0; - } - - if (is_device) { - if (cpu_is_omap7xx()) { - omap_cfg_reg(AA17_7XX_USB_DM); - omap_cfg_reg(W16_7XX_USB_PU_EN); - omap_cfg_reg(W17_7XX_USB_VBUSI); - omap_cfg_reg(W18_7XX_USB_DMCK_OUT); - omap_cfg_reg(W19_7XX_USB_DCRST); - } else - omap_cfg_reg(W4_USB_PUEN); - } - - if (nwires == 2) { - u32 l; - - // omap_cfg_reg(P9_USB_DP); - // omap_cfg_reg(R8_USB_DM); - - if (cpu_is_omap15xx()) { - /* This works on 1510-Innovator */ - return 0; - } - - /* NOTES: - * - peripheral should configure VBUS detection! - * - only peripherals may use the internal D+/D- pulldowns - * - OTG support on this port not yet written - */ - - /* Don't do this for omap7xx -- it causes USB to not work correctly */ - if (!cpu_is_omap7xx()) { - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~(7 << 4); - if (!is_device) - l |= (3 << 1); - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - - return 3 << 16; - } - - /* alternate pin config, external transceiver */ - if (cpu_is_omap15xx()) { - printk(KERN_ERR "no usb0 alt pin config on 15xx\n"); - return 0; - } - - omap_cfg_reg(V6_USB0_TXD); - omap_cfg_reg(W9_USB0_TXEN); - omap_cfg_reg(W5_USB0_SE0); - if (nwires != 3) - omap_cfg_reg(Y5_USB0_RCV); - - /* NOTE: SPEED and SUSP aren't configured here. OTG hosts - * may be able to use I2C requests to set those bits along - * with VBUS switching and overcurrent detection. - */ - - if (nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - - switch (nwires) { - case 3: - syscon1 = 2; - break; - case 4: - syscon1 = 1; - break; - case 6: - syscon1 = 3; - { - u32 l; - - omap_cfg_reg(AA9_USB0_VP); - omap_cfg_reg(R9_USB0_VM); - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - break; - default: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 0, nwires); - } - return syscon1 << 16; -} - -static u32 __init omap_usb1_init(unsigned nwires) -{ - u32 syscon1 = 0; - - if (!cpu_is_omap15xx() && nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB1_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - if (nwires == 0) - return 0; - - /* external transceiver */ - omap_cfg_reg(USB1_TXD); - omap_cfg_reg(USB1_TXEN); - if (nwires != 3) - omap_cfg_reg(USB1_RCV); - - if (cpu_is_omap15xx()) { - omap_cfg_reg(USB1_SEO); - omap_cfg_reg(USB1_SPEED); - // SUSP - } else if (cpu_is_omap1610() || cpu_is_omap5912()) { - omap_cfg_reg(W13_1610_USB1_SE0); - omap_cfg_reg(R13_1610_USB1_SPEED); - // SUSP - } else if (cpu_is_omap1710()) { - omap_cfg_reg(R13_1710_USB1_SE0); - // SUSP - } else { - pr_debug("usb%d cpu unrecognized\n", 1); - return 0; - } - - switch (nwires) { - case 2: - goto bad; - case 3: - syscon1 = 2; - break; - case 4: - syscon1 = 1; - break; - case 6: - syscon1 = 3; - omap_cfg_reg(USB1_VP); - omap_cfg_reg(USB1_VM); - if (!cpu_is_omap15xx()) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB1_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - break; - default: -bad: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 1, nwires); - } - return syscon1 << 20; -} - -static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup) -{ - u32 syscon1 = 0; - - /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */ - if (alt_pingroup || nwires == 0) - return 0; - - if (!cpu_is_omap15xx() && nwires != 6) { - u32 l; - - l = omap_readl(USB_TRANSCEIVER_CTRL); - l &= ~CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - - /* external transceiver */ - if (cpu_is_omap15xx()) { - omap_cfg_reg(USB2_TXD); - omap_cfg_reg(USB2_TXEN); - omap_cfg_reg(USB2_SEO); - if (nwires != 3) - omap_cfg_reg(USB2_RCV); - /* there is no USB2_SPEED */ - } else if (cpu_is_omap16xx()) { - omap_cfg_reg(V6_USB2_TXD); - omap_cfg_reg(W9_USB2_TXEN); - omap_cfg_reg(W5_USB2_SE0); - if (nwires != 3) - omap_cfg_reg(Y5_USB2_RCV); - // FIXME omap_cfg_reg(USB2_SPEED); - } else { - pr_debug("usb%d cpu unrecognized\n", 1); - return 0; - } - // omap_cfg_reg(USB2_SUSP); - - switch (nwires) { - case 2: - goto bad; - case 3: - syscon1 = 2; - break; - case 4: - syscon1 = 1; - break; - case 5: - goto bad; - case 6: - syscon1 = 3; - if (cpu_is_omap15xx()) { - omap_cfg_reg(USB2_VP); - omap_cfg_reg(USB2_VM); - } else { - u32 l; - - omap_cfg_reg(AA9_USB2_VP); - omap_cfg_reg(R9_USB2_VM); - l = omap_readl(USB_TRANSCEIVER_CTRL); - l |= CONF_USB2_UNI_R; - omap_writel(l, USB_TRANSCEIVER_CTRL); - } - break; - default: -bad: - printk(KERN_ERR "illegal usb%d %d-wire transceiver\n", - 2, nwires); - } - return syscon1 << 24; -} - -#else -#define omap_usb0_init NULL -#define omap_usb1_init NULL -#define omap_usb2_init NULL -#endif - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_USB_GADGET_OMAP - -static struct resource udc_resources[] = { - /* order is significant! */ - { /* registers */ - .start = UDC_BASE, - .end = UDC_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { /* general IRQ */ - .start = INT_USB_IRQ_GEN, - .flags = IORESOURCE_IRQ, - }, { /* PIO IRQ */ - .start = INT_USB_IRQ_NISO, - .flags = IORESOURCE_IRQ, - }, { /* SOF IRQ */ - .start = INT_USB_IRQ_ISO, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 udc_dmamask = ~(u32)0; - -static struct platform_device udc_device = { - .name = "omap_udc", - .id = -1, - .dev = { - .dma_mask = &udc_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(udc_resources), - .resource = udc_resources, -}; - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ - pdata->udc_device = &udc_device; -} - -#else - -static inline void udc_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - -/* The dmamask must be set for OHCI to work */ -static u64 ohci_dmamask = ~(u32)0; - -static struct resource ohci_resources[] = { - { - .start = OMAP_OHCI_BASE, - .end = OMAP_OHCI_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_USB_IRQ_HGEN, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device ohci_device = { - .name = "ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(ohci_resources), - .resource = ohci_resources, -}; - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ - pdata->ohci_device = &ohci_device; -} - -#else - -static inline void ohci_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG) - -static struct resource otg_resources[] = { - /* order is significant! */ - { - .start = OTG_BASE, - .end = OTG_BASE + 0xff, - .flags = IORESOURCE_MEM, - }, { - .start = INT_USB_IRQ_OTG, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device otg_device = { - .name = "omap_otg", - .id = -1, - .num_resources = ARRAY_SIZE(otg_resources), - .resource = otg_resources, -}; - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ - pdata->otg_device = &otg_device; -} - -#else - -static inline void otg_device_init(struct omap_usb_config *pdata) -{ -} - -#endif - -/*-------------------------------------------------------------------------*/ - -// FIXME correct answer depends on hmc_mode, -// as does (on omap1) any nonzero value for config->otg port number -#ifdef CONFIG_USB_GADGET_OMAP -#define is_usb0_device(config) 1 -#else -#define is_usb0_device(config) 0 -#endif - -/*-------------------------------------------------------------------------*/ - #ifdef CONFIG_ARCH_OMAP_OTG void __init @@ -524,12 +103,6 @@ omap_otg_init(struct omap_usb_config *config) syscon &= ~DEV_IDLE_EN; udc_device->dev.platform_data = config; - /* IRQ numbers for omap7xx */ - if(cpu_is_omap7xx()) { - udc_resources[1].start = INT_7XX_USB_GENI; - udc_resources[2].start = INT_7XX_USB_NON_ISO; - udc_resources[3].start = INT_7XX_USB_ISO; - } status = platform_device_register(udc_device); if (status) pr_debug("can't register UDC device, %d\n", status); @@ -542,8 +115,6 @@ omap_otg_init(struct omap_usb_config *config) syscon &= ~HST_IDLE_EN; ohci_device->dev.platform_data = config; - if (cpu_is_omap7xx()) - ohci_resources[1].start = INT_7XX_USB_HHC_1; status = platform_device_register(ohci_device); if (status) pr_debug("can't register OHCI device, %d\n", status); @@ -556,8 +127,6 @@ omap_otg_init(struct omap_usb_config *config) syscon &= ~OTG_IDLE_EN; otg_device->dev.platform_data = config; - if (cpu_is_omap7xx()) - otg_resources[1].start = INT_7XX_USB_OTG; status = platform_device_register(otg_device); if (status) pr_debug("can't register OTG device, %d\n", status); @@ -572,107 +141,3 @@ omap_otg_init(struct omap_usb_config *config) #else void omap_otg_init(struct omap_usb_config *config) {} #endif - -/*-------------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_OMAP15XX - -/* ULPD_DPLL_CTRL */ -#define DPLL_IOB (1 << 13) -#define DPLL_PLL_ENABLE (1 << 4) -#define DPLL_LOCK (1 << 0) - -/* ULPD_APLL_CTRL */ -#define APLL_NDPLL_SWITCH (1 << 0) - - -static void __init omap_1510_usb_init(struct omap_usb_config *config) -{ - unsigned int val; - u16 w; - - config->usb0_init(config->pins[0], is_usb0_device(config)); - config->usb1_init(config->pins[1]); - config->usb2_init(config->pins[2], 0); - - val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1); - val |= (config->hmc_mode << 1); - omap_writel(val, MOD_CONF_CTRL_0); - - printk("USB: hmc %d", config->hmc_mode); - if (config->pins[0]) - printk(", usb0 %d wires%s", config->pins[0], - is_usb0_device(config) ? " (dev)" : ""); - if (config->pins[1]) - printk(", usb1 %d wires", config->pins[1]); - if (config->pins[2]) - printk(", usb2 %d wires", config->pins[2]); - printk("\n"); - - /* use DPLL for 48 MHz function clock */ - pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL), - omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ)); - - w = omap_readw(ULPD_APLL_CTRL); - w &= ~APLL_NDPLL_SWITCH; - omap_writew(w, ULPD_APLL_CTRL); - - w = omap_readw(ULPD_DPLL_CTRL); - w |= DPLL_IOB | DPLL_PLL_ENABLE; - omap_writew(w, ULPD_DPLL_CTRL); - - w = omap_readw(ULPD_SOFT_REQ); - w |= SOFT_UDC_REQ | SOFT_DPLL_REQ; - omap_writew(w, ULPD_SOFT_REQ); - - while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK)) - cpu_relax(); - -#ifdef CONFIG_USB_GADGET_OMAP - if (config->register_dev) { - int status; - - udc_device.dev.platform_data = config; - status = platform_device_register(&udc_device); - if (status) - pr_debug("can't register UDC device, %d\n", status); - /* udc driver gates 48MHz by D+ pullup */ - } -#endif - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) - if (config->register_host) { - int status; - - ohci_device.dev.platform_data = config; - status = platform_device_register(&ohci_device); - if (status) - pr_debug("can't register OHCI device, %d\n", status); - /* hcd explicitly gates 48MHz */ - } -#endif -} - -#else -static inline void omap_1510_usb_init(struct omap_usb_config *config) {} -#endif - -/*-------------------------------------------------------------------------*/ - -void __init omap_usb_init(struct omap_usb_config *pdata) -{ - pdata->usb0_init = omap_usb0_init; - pdata->usb1_init = omap_usb1_init; - pdata->usb2_init = omap_usb2_init; - udc_device_init(pdata); - ohci_device_init(pdata); - otg_device_init(pdata); - - if (cpu_is_omap7xx() || cpu_is_omap16xx()) - omap_otg_init(pdata); - else if (cpu_is_omap15xx()) - omap_1510_usb_init(pdata); - else - printk(KERN_ERR "USB: No init for your chip yet\n"); -} - -- cgit v1.2.2 From 93c43f2561f18b50e3376be968d0688315afc44c Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:39 +0300 Subject: omap: mux: Do keypad muxing in board-*.c files This way we get pin muxing out of plat-omap and can convert H4 to use the new mux functions. Note that it should be safe to assume we can mux all the keypad pins except on H4 which may have Menelaus connected. Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/devices.c | 61 -------------------------------------------- 1 file changed, 61 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 95677d17cd1c..ca5b2290f5a3 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -24,7 +24,6 @@ #include <plat/control.h> #include <plat/board.h> #include <plat/mmc.h> -#include <plat/mux.h> #include <mach/gpio.h> #include <plat/menelaus.h> #include <plat/mcbsp.h> @@ -93,66 +92,7 @@ static inline void omap_init_dsp(void) { } #endif /* CONFIG_OMAP_DSP */ /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE) -static void omap_init_kp(void) -{ - /* 2430 and 34xx keypad is on TWL4030 */ - if (cpu_is_omap2430() || cpu_is_omap34xx()) - return; - - if (machine_is_omap_h2() || machine_is_omap_h3()) { - omap_cfg_reg(F18_1610_KBC0); - omap_cfg_reg(D20_1610_KBC1); - omap_cfg_reg(D19_1610_KBC2); - omap_cfg_reg(E18_1610_KBC3); - omap_cfg_reg(C21_1610_KBC4); - - omap_cfg_reg(G18_1610_KBR0); - omap_cfg_reg(F19_1610_KBR1); - omap_cfg_reg(H14_1610_KBR2); - omap_cfg_reg(E20_1610_KBR3); - omap_cfg_reg(E19_1610_KBR4); - omap_cfg_reg(N19_1610_KBR5); - } else if (machine_is_omap_perseus2() || machine_is_omap_fsample()) { - omap_cfg_reg(E2_7XX_KBR0); - omap_cfg_reg(J7_7XX_KBR1); - omap_cfg_reg(E1_7XX_KBR2); - omap_cfg_reg(F3_7XX_KBR3); - omap_cfg_reg(D2_7XX_KBR4); - - omap_cfg_reg(C2_7XX_KBC0); - omap_cfg_reg(D3_7XX_KBC1); - omap_cfg_reg(E4_7XX_KBC2); - omap_cfg_reg(F4_7XX_KBC3); - omap_cfg_reg(E3_7XX_KBC4); - } else if (machine_is_omap_h4()) { - omap_cfg_reg(T19_24XX_KBR0); - omap_cfg_reg(R19_24XX_KBR1); - omap_cfg_reg(V18_24XX_KBR2); - omap_cfg_reg(M21_24XX_KBR3); - omap_cfg_reg(E5__24XX_KBR4); - if (omap_has_menelaus()) { - omap_cfg_reg(B3__24XX_KBR5); - omap_cfg_reg(AA4_24XX_KBC2); - omap_cfg_reg(B13_24XX_KBC6); - } else { - omap_cfg_reg(M18_24XX_KBR5); - omap_cfg_reg(H19_24XX_KBC2); - omap_cfg_reg(N19_24XX_KBC6); - } - omap_cfg_reg(R20_24XX_KBC0); - omap_cfg_reg(M14_24XX_KBC1); - omap_cfg_reg(V17_24XX_KBC3); - omap_cfg_reg(P21_24XX_KBC4); - omap_cfg_reg(L14_24XX_KBC5); - } -} -#else -static inline void omap_init_kp(void) {} -#endif - -/*-------------------------------------------------------------------------*/ #if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE) static struct platform_device **omap_mcbsp_devices; @@ -420,7 +360,6 @@ static int __init omap_init_devices(void) * in alphabetical order so they're easier to sort through. */ omap_init_dsp(); - omap_init_kp(); omap_init_rng(); omap_init_mcpdm(); omap_init_uwire(); -- cgit v1.2.2 From c9d8230e316abb6a480f6bda85edf859896e9ab6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:40 +0300 Subject: omap: mux: Remove old mux code All mach-omap2 omaps should now use the new mux code. Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/mux.h | 220 ---------------------------------- arch/arm/plat-omap/mux.c | 2 +- 2 files changed, 1 insertion(+), 221 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h index c7472a28ce24..e1da7b17d25b 100644 --- a/arch/arm/plat-omap/include/plat/mux.h +++ b/arch/arm/plat-omap/include/plat/mux.h @@ -114,28 +114,11 @@ PU_PD_REG(NA, 0) \ }, -#define MUX_CFG_24XX(desc, reg_offset, mode, \ - pull_en, pull_mode, dbg) \ -{ \ - .name = desc, \ - .debug = dbg, \ - .mux_reg = reg_offset, \ - .mask = mode, \ - .pull_val = pull_en, \ - .pu_pd_val = pull_mode, \ -}, - -/* 24xx/34xx mux bit defines */ -#define OMAP2_PULL_ENA (1 << 3) -#define OMAP2_PULL_UP (1 << 4) -#define OMAP2_ALTELECTRICALSEL (1 << 5) - struct pin_config { char *name; const unsigned int mux_reg; unsigned char debug; -#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2) const unsigned char mask_offset; const unsigned char mask; @@ -147,7 +130,6 @@ struct pin_config { const char *pu_pd_name; const unsigned int pu_pd_reg; const unsigned char pu_pd_val; -#endif #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) const char *mux_reg_name; @@ -446,208 +428,6 @@ enum omap1xxx_index { }; -enum omap24xx_index { - /* 24xx I2C */ - M19_24XX_I2C1_SCL, - L15_24XX_I2C1_SDA, - J15_24XX_I2C2_SCL, - H19_24XX_I2C2_SDA, - - /* 24xx Menelaus interrupt */ - W19_24XX_SYS_NIRQ, - - /* 24xx clock */ - W14_24XX_SYS_CLKOUT, - - /* 24xx GPMC chipselects, wait pin monitoring */ - E2_GPMC_NCS2, - L2_GPMC_NCS7, - L3_GPMC_WAIT0, - N7_GPMC_WAIT1, - M1_GPMC_WAIT2, - P1_GPMC_WAIT3, - - /* 242X McBSP */ - Y15_24XX_MCBSP2_CLKX, - R14_24XX_MCBSP2_FSX, - W15_24XX_MCBSP2_DR, - V15_24XX_MCBSP2_DX, - - /* 24xx GPIO */ - M21_242X_GPIO11, - P21_242X_GPIO12, - AA10_242X_GPIO13, - AA6_242X_GPIO14, - AA4_242X_GPIO15, - Y11_242X_GPIO16, - AA12_242X_GPIO17, - AA8_242X_GPIO58, - Y20_24XX_GPIO60, - W4__24XX_GPIO74, - N15_24XX_GPIO85, - M15_24XX_GPIO92, - P20_24XX_GPIO93, - P18_24XX_GPIO95, - M18_24XX_GPIO96, - L14_24XX_GPIO97, - J15_24XX_GPIO99, - V14_24XX_GPIO117, - P14_24XX_GPIO125, - - /* 242x DBG GPIO */ - V4_242X_GPIO49, - W2_242X_GPIO50, - U4_242X_GPIO51, - V3_242X_GPIO52, - V2_242X_GPIO53, - V6_242X_GPIO53, - T4_242X_GPIO54, - Y4_242X_GPIO54, - T3_242X_GPIO55, - U2_242X_GPIO56, - - /* 24xx external DMA requests */ - AA10_242X_DMAREQ0, - AA6_242X_DMAREQ1, - E4_242X_DMAREQ2, - G4_242X_DMAREQ3, - D3_242X_DMAREQ4, - E3_242X_DMAREQ5, - - /* UART3 */ - K15_24XX_UART3_TX, - K14_24XX_UART3_RX, - - /* MMC/SDIO */ - G19_24XX_MMC_CLKO, - H18_24XX_MMC_CMD, - F20_24XX_MMC_DAT0, - H14_24XX_MMC_DAT1, - E19_24XX_MMC_DAT2, - D19_24XX_MMC_DAT3, - F19_24XX_MMC_DAT_DIR0, - E20_24XX_MMC_DAT_DIR1, - F18_24XX_MMC_DAT_DIR2, - E18_24XX_MMC_DAT_DIR3, - G18_24XX_MMC_CMD_DIR, - H15_24XX_MMC_CLKI, - - /* Full speed USB */ - J20_24XX_USB0_PUEN, - J19_24XX_USB0_VP, - K20_24XX_USB0_VM, - J18_24XX_USB0_RCV, - K19_24XX_USB0_TXEN, - J14_24XX_USB0_SE0, - K18_24XX_USB0_DAT, - - N14_24XX_USB1_SE0, - W12_24XX_USB1_SE0, - P15_24XX_USB1_DAT, - R13_24XX_USB1_DAT, - W20_24XX_USB1_TXEN, - P13_24XX_USB1_TXEN, - V19_24XX_USB1_RCV, - V12_24XX_USB1_RCV, - - AA10_24XX_USB2_SE0, - Y11_24XX_USB2_DAT, - AA12_24XX_USB2_TXEN, - AA6_24XX_USB2_RCV, - AA4_24XX_USB2_TLLSE0, - - /* Keypad GPIO*/ - T19_24XX_KBR0, - R19_24XX_KBR1, - V18_24XX_KBR2, - M21_24XX_KBR3, - E5__24XX_KBR4, - M18_24XX_KBR5, - R20_24XX_KBC0, - M14_24XX_KBC1, - H19_24XX_KBC2, - V17_24XX_KBC3, - P21_24XX_KBC4, - L14_24XX_KBC5, - N19_24XX_KBC6, - - /* 24xx Menelaus Keypad GPIO */ - B3__24XX_KBR5, - AA4_24XX_KBC2, - B13_24XX_KBC6, - - /* 2430 USB */ - AD9_2430_USB0_PUEN, - Y11_2430_USB0_VP, - AD7_2430_USB0_VM, - AE7_2430_USB0_RCV, - AD4_2430_USB0_TXEN, - AF9_2430_USB0_SE0, - AE6_2430_USB0_DAT, - AD24_2430_USB1_SE0, - AB24_2430_USB1_RCV, - Y25_2430_USB1_TXEN, - AA26_2430_USB1_DAT, - - /* 2430 HS-USB */ - AD9_2430_USB0HS_DATA3, - Y11_2430_USB0HS_DATA4, - AD7_2430_USB0HS_DATA5, - AE7_2430_USB0HS_DATA6, - AD4_2430_USB0HS_DATA2, - AF9_2430_USB0HS_DATA0, - AE6_2430_USB0HS_DATA1, - AE8_2430_USB0HS_CLK, - AD8_2430_USB0HS_DIR, - AE5_2430_USB0HS_STP, - AE9_2430_USB0HS_NXT, - AC7_2430_USB0HS_DATA7, - - /* 2430 McBSP */ - AD6_2430_MCBSP_CLKS, - - AB2_2430_MCBSP1_CLKR, - AD5_2430_MCBSP1_FSR, - AA1_2430_MCBSP1_DX, - AF3_2430_MCBSP1_DR, - AB3_2430_MCBSP1_FSX, - Y9_2430_MCBSP1_CLKX, - - AC10_2430_MCBSP2_FSX, - AD16_2430_MCBSP2_CLX, - AE13_2430_MCBSP2_DX, - AD13_2430_MCBSP2_DR, - AC10_2430_MCBSP2_FSX_OFF, - AD16_2430_MCBSP2_CLX_OFF, - AE13_2430_MCBSP2_DX_OFF, - AD13_2430_MCBSP2_DR_OFF, - - AC9_2430_MCBSP3_CLKX, - AE4_2430_MCBSP3_FSX, - AE2_2430_MCBSP3_DR, - AF4_2430_MCBSP3_DX, - - N3_2430_MCBSP4_CLKX, - AD23_2430_MCBSP4_DR, - AB25_2430_MCBSP4_DX, - AC25_2430_MCBSP4_FSX, - - AE16_2430_MCBSP5_CLKX, - AF12_2430_MCBSP5_FSX, - K7_2430_MCBSP5_DX, - M1_2430_MCBSP5_DR, - - /* 2430 McSPI*/ - Y18_2430_MCSPI1_CLK, - AD15_2430_MCSPI1_SIMO, - AE17_2430_MCSPI1_SOMI, - U1_2430_MCSPI1_CS0, - - /* Touchscreen GPIO */ - AF19_2430_GPIO_85, - -}; - struct omap_mux_cfg { struct pin_config *pins; unsigned long size; diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 06703635ace1..0d4aa0d5876c 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -54,7 +54,7 @@ int __init_or_module omap_cfg_reg(const unsigned long index) { struct pin_config *reg; - if (cpu_is_omap34xx() || cpu_is_omap44xx()) { + if (!cpu_class_is_omap1()) { printk(KERN_ERR "mux: Broken omap_cfg_reg(%lu) entry\n", index); WARN_ON(1); -- cgit v1.2.2 From f0ca2c05dd44988b7ce9a974442cd0441bfd3450 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:46 +0300 Subject: omap: Use 32KiHZ timer by default Use 32KiHZ timer by default as this is available on all omaps except 15xx based systems. Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 78b49a626d06..3e2e7a827d5a 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -120,7 +120,7 @@ config OMAP_IOMMU_DEBUG choice prompt "System timer" - default OMAP_MPU_TIMER + default OMAP_32K_TIMER if !ARCH_OMAP15XX config OMAP_MPU_TIMER bool "Use mpu timer" -- cgit v1.2.2 From 4a54db612463e330e0e02e2234fc6b783b3eea84 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:47 +0300 Subject: omap: Make omap specific features appear under Kconfig menu This will make Kconfig look nicer for selecting omap processor type Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 3e2e7a827d5a..a4e87278b8f1 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -1,6 +1,6 @@ if ARCH_OMAP -menu "TI OMAP Implementations" +menu "TI OMAP Common Features" config ARCH_OMAP_OTG bool -- cgit v1.2.2 From 68ac8f7dda26de7fc321426d52f4ac6bd785bad3 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 5 Jul 2010 16:31:47 +0300 Subject: omap2/3/4: Move Kconfig options to mach-omap2/Kconfig Move omap2/3/4 specific Kconfig options to mach-omap2/Kconfig Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/Kconfig | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index a4e87278b8f1..b7a3d80c539f 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -21,24 +21,6 @@ config ARCH_OMAP2PLUS help "Systems based on omap24xx, omap34xx or omap44xx" -config ARCH_OMAP2 - bool "TI OMAP2" - depends on ARCH_OMAP2PLUS - select CPU_V6 - -config ARCH_OMAP3 - bool "TI OMAP3" - depends on ARCH_OMAP2PLUS - select CPU_V7 - select USB_ARCH_HAS_EHCI - select ARM_L1_CACHE_SHIFT_6 - -config ARCH_OMAP4 - bool "TI OMAP4" - depends on ARCH_OMAP2PLUS - select CPU_V7 - select ARM_GIC - endchoice comment "OMAP Feature Selections" -- cgit v1.2.2 From ab6f7751905e5cf713d081dbb3b97b8f6909ab34 Mon Sep 17 00:00:00 2001 From: Christoph Egger <siccegge@cs.fau.de> Date: Mon, 5 Jul 2010 16:31:54 +0300 Subject: Removing dead OMAP_DSP OMAP_DSP doesn't exist in Kconfig, therefore removing all references for it from the source code. Signed-off-by: Christoph Egger <siccegge@cs.fau.de> [tony@atomide.com: updated to apply on top of already queued patches] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/devices.c | 63 ---------------------------- arch/arm/plat-omap/include/plat/dsp_common.h | 40 ------------------ 2 files changed, 103 deletions(-) delete mode 100644 arch/arm/plat-omap/include/plat/dsp_common.h (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index ca5b2290f5a3..d1920be7833b 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c @@ -27,70 +27,8 @@ #include <mach/gpio.h> #include <plat/menelaus.h> #include <plat/mcbsp.h> -#include <plat/dsp_common.h> #include <plat/omap44xx.h> -#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) - -static struct dsp_platform_data dsp_pdata = { - .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list), -}; - -static struct resource omap_dsp_resources[] = { - { - .name = "dsp_mmu", - .start = -1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device omap_dsp_device = { - .name = "dsp", - .id = -1, - .num_resources = ARRAY_SIZE(omap_dsp_resources), - .resource = omap_dsp_resources, - .dev = { - .platform_data = &dsp_pdata, - }, -}; - -static inline void omap_init_dsp(void) -{ - struct resource *res; - int irq; - - if (cpu_is_omap15xx()) - irq = INT_1510_DSP_MMU; - else if (cpu_is_omap16xx()) - irq = INT_1610_DSP_MMU; - else if (cpu_is_omap24xx()) - irq = INT_24XX_DSP_MMU; - - res = platform_get_resource_byname(&omap_dsp_device, - IORESOURCE_IRQ, "dsp_mmu"); - res->start = irq; - - platform_device_register(&omap_dsp_device); -} - -int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev) -{ - static DEFINE_MUTEX(dsp_pdata_lock); - - spin_lock_init(&kdev->lock); - - mutex_lock(&dsp_pdata_lock); - list_add_tail(&kdev->entry, &dsp_pdata.kdev_list); - mutex_unlock(&dsp_pdata_lock); - - return 0; -} -EXPORT_SYMBOL(dsp_kfunc_device_register); - -#else -static inline void omap_init_dsp(void) { } -#endif /* CONFIG_OMAP_DSP */ - /*-------------------------------------------------------------------------*/ #if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE) @@ -359,7 +297,6 @@ static int __init omap_init_devices(void) /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ - omap_init_dsp(); omap_init_rng(); omap_init_mcpdm(); omap_init_uwire(); diff --git a/arch/arm/plat-omap/include/plat/dsp_common.h b/arch/arm/plat-omap/include/plat/dsp_common.h deleted file mode 100644 index da97736f3efa..000000000000 --- a/arch/arm/plat-omap/include/plat/dsp_common.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1) - * - * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved. - * - * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA - * - */ - -#ifndef ASM_ARCH_DSP_COMMON_H -#define ASM_ARCH_DSP_COMMON_H - -#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_OMAP_MMU_FWK) -extern void omap_dsp_request_mpui(void); -extern void omap_dsp_release_mpui(void); -extern int omap_dsp_request_mem(void); -extern int omap_dsp_release_mem(void); -#else -static inline int omap_dsp_request_mem(void) -{ - return 0; -} -#define omap_dsp_release_mem() do {} while (0) -#endif - -#endif /* ASM_ARCH_DSP_COMMON_H */ -- cgit v1.2.2 From 3c8ed2a90e7b8ce34dbf4cb35b67b48e351308fa Mon Sep 17 00:00:00 2001 From: Christoph Egger <siccegge@cs.fau.de> Date: Mon, 5 Jul 2010 16:31:54 +0300 Subject: Replacing LEDS_OMAP_DEBUG with OMAP_DEBUG_LEDS LEDS_OMAP_DEBUG doesn't exist in Kconfig, therefore replacing all references for it with OMAP_DEBUG_LEDS from the source code. Signed-off-by: Christoph Egger <siccegge@cs.fau.de> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/Kconfig | 2 +- arch/arm/plat-omap/debug-leds.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index b7a3d80c539f..e2ed952df23d 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -33,7 +33,7 @@ config OMAP_DEBUG_DEVICES config OMAP_DEBUG_LEDS bool depends on OMAP_DEBUG_DEVICES - default y if LEDS || LEDS_OMAP_DEBUG + default y if LEDS config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c index 53fcef7c5201..fc05b1022602 100644 --- a/arch/arm/plat-omap/debug-leds.c +++ b/arch/arm/plat-omap/debug-leds.c @@ -39,7 +39,7 @@ static struct h2p2_dbg_fpga __iomem *fpga; static u16 led_state, hw_led_state; -#ifdef CONFIG_LEDS_OMAP_DEBUG +#ifdef CONFIG_OMAP_DEBUG_LEDS #define new_led_api() 1 #else #define new_led_api() 0 -- cgit v1.2.2 From b3c1cff6985a78dcf2842960f866b07230ccef10 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:27 -0600 Subject: OMAP: clock: add kerneldoc for structures; move flags closer to structs Add kerneldoc for struct clk, struct clksel_rate, struct clksel. Move flag macros for struct clk.flags and struct clksel_rate.flags closer to the structures. Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/include/plat/clock.h | 130 ++++++++++++++++++++++++++------ 1 file changed, 107 insertions(+), 23 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h index dfc472ca0cc4..fef4696dcf67 100644 --- a/arch/arm/plat-omap/include/plat/clock.h +++ b/arch/arm/plat-omap/include/plat/clock.h @@ -19,6 +19,22 @@ struct module; struct clk; struct clockdomain; +/** + * struct clkops - some clock function pointers + * @enable: fn ptr that enables the current clock in hardware + * @disable: fn ptr that enables the current clock in hardware + * @find_idlest: function returning the IDLEST register for the clock's IP blk + * @find_companion: function returning the "companion" clk reg for the clock + * + * A "companion" clk is an accompanying clock to the one being queried + * that must be enabled for the IP module connected to the clock to + * become accessible by the hardware. Neither @find_idlest nor + * @find_companion should be needed; that information is IP + * block-specific; the hwmod code has been created to handle this, but + * until hwmod data is ready and drivers have been converted to use PM + * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and + * @find_companion must, unfortunately, remain. + */ struct clkops { int (*enable)(struct clk *); void (*disable)(struct clk *); @@ -30,12 +46,45 @@ struct clkops { #ifdef CONFIG_ARCH_OMAP2PLUS +/* struct clksel_rate.flags possibilities */ +#define RATE_IN_242X (1 << 0) +#define RATE_IN_243X (1 << 1) +#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */ +#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */ +#define RATE_IN_36XX (1 << 4) +#define RATE_IN_4430 (1 << 5) + +#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) +#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX) + +/** + * struct clksel_rate - register bitfield values corresponding to clk divisors + * @val: register bitfield value (shifted to bit 0) + * @div: clock divisor corresponding to @val + * @flags: (see "struct clksel_rate.flags possibilities" above) + * + * @val should match the value of a read from struct clk.clksel_reg + * AND'ed with struct clk.clksel_mask, shifted right to bit 0. + * + * @div is the divisor that should be applied to the parent clock's rate + * to produce the current clock's rate. + * + * XXX @flags probably should be replaced with an struct omap_chip. + */ struct clksel_rate { u32 val; u8 div; u8 flags; }; +/** + * struct clksel - available parent clocks, and a pointer to their divisors + * @parent: struct clk * to a possible parent clock + * @rates: available divisors for this parent clock + * + * A struct clksel is always associated with one or more struct clks + * and one or more struct clksel_rates. + */ struct clksel { struct clk *parent; const struct clksel_rate *rates; @@ -116,6 +165,60 @@ struct dpll_data { #endif +/* struct clk.flags possibilities */ +#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ +#define CLOCK_IDLE_CONTROL (1 << 1) +#define CLOCK_NO_IDLE_PARENT (1 << 2) +#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ +#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ + +/** + * struct clk - OMAP struct clk + * @node: list_head connecting this clock into the full clock list + * @ops: struct clkops * for this clock + * @name: the name of the clock in the hardware (used in hwmod data and debug) + * @parent: pointer to this clock's parent struct clk + * @children: list_head connecting to the child clks' @sibling list_heads + * @sibling: list_head connecting this clk to its parent clk's @children + * @rate: current clock rate + * @enable_reg: register to write to enable the clock (see @enable_bit) + * @recalc: fn ptr that returns the clock's current rate + * @set_rate: fn ptr that can change the clock's current rate + * @round_rate: fn ptr that can round the clock's current rate + * @init: fn ptr to do clock-specific initialization + * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg) + * @usecount: number of users that have requested this clock to be enabled + * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div + * @flags: see "struct clk.flags possibilities" above + * @clksel_reg: for clksel clks, register va containing src/divisor select + * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector + * @clksel: for clksel clks, pointer to struct clksel for this clock + * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock + * @clkdm_name: clockdomain name that this clock is contained in + * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime + * @rate_offset: bitshift for rate selection bitfield (OMAP1 only) + * @src_offset: bitshift for source selection bitfield (OMAP1 only) + * + * XXX @rate_offset, @src_offset should probably be removed and OMAP1 + * clock code converted to use clksel. + * + * XXX @usecount is poorly named. It should be "enable_count" or + * something similar. "users" in the description refers to kernel + * code (core code or drivers) that have called clk_enable() and not + * yet called clk_disable(); the usecount of parent clocks is also + * incremented by the clock code when clk_enable() is called on child + * clocks and decremented by the clock code when clk_disable() is + * called on child clocks. + * + * XXX @clkdm, @usecount, @children, @sibling should be marked for + * internal use only. + * + * @children and @sibling are used to optimize parent-to-child clock + * tree traversals. (child-to-parent traversals use @parent.) + * + * XXX The notion of the clock's current rate probably needs to be + * separated from the clock's target rate. + */ struct clk { struct list_head node; const struct clkops *ops; @@ -129,8 +232,8 @@ struct clk { int (*set_rate)(struct clk *, unsigned long); long (*round_rate)(struct clk *, unsigned long); void (*init)(struct clk *); - __u8 enable_bit; - __s8 usecount; + u8 enable_bit; + s8 usecount; u8 fixed_div; u8 flags; #ifdef CONFIG_ARCH_OMAP2PLUS @@ -141,8 +244,8 @@ struct clk { const char *clkdm_name; struct clockdomain *clkdm; #else - __u8 rate_offset; - __u8 src_offset; + u8 rate_offset; + u8 src_offset; #endif #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) struct dentry *dent; /* For visible tree hierarchy */ @@ -188,23 +291,4 @@ extern const struct clkops clkops_null; extern struct clk dummy_ck; -/* Clock flags */ -#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */ -#define CLOCK_IDLE_CONTROL (1 << 1) -#define CLOCK_NO_IDLE_PARENT (1 << 2) -#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */ -#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */ - -/* Clksel_rate flags */ -#define RATE_IN_242X (1 << 0) -#define RATE_IN_243X (1 << 1) -#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */ -#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */ -#define RATE_IN_36XX (1 << 4) -#define RATE_IN_4430 (1 << 5) - -#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) - -#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX) - #endif -- cgit v1.2.2 From 848240223c35fcc71c424ad51a8e8aef42d3879c Mon Sep 17 00:00:00 2001 From: Kevin Hilman <khilman@deeprootsystems.com> Date: Mon, 26 Jul 2010 16:34:29 -0600 Subject: OMAP: hwmod: add non-locking versions of enable and idle functions Some hwmods may need to be idled/enabled in atomic context, so non-locking versions of these functions are required. Most users should not need these and usage of theses should be controlled to understand why access is being done in atomic context. For this reason, the non-locking functions are only exposed at the hwmod level and not at the omap-device level. The use-case that led to the need for the non-locking versions is hwmods that are enabled/idled from within the core idle/suspend path. Since interrupts are already disabled here, the mutex-based locking in hwmod can sleep and will cause potential deadlocks. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 0eccc09ac4a9..253f6e55638c 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -486,7 +486,9 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)); int omap_hwmod_late_init(void); int omap_hwmod_enable(struct omap_hwmod *oh); +int _omap_hwmod_enable(struct omap_hwmod *oh); int omap_hwmod_idle(struct omap_hwmod *oh); +int _omap_hwmod_idle(struct omap_hwmod *oh); int omap_hwmod_shutdown(struct omap_hwmod *oh); int omap_hwmod_enable_clocks(struct omap_hwmod *oh); -- cgit v1.2.2 From 97d60162f64ef068b639d8a77ef3bc148baa53ad Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:30 -0600 Subject: OMAP: hwmod: allow omap_hwmod_late_init() caller to skip module idle in _setup() On kernels that don't use the omap_device_enable() calls to enable devices, leave all on-chip devices enabled in hwmod _setup(). Otherwise, accesses to those devices are likely to fail, crashing the system. It's expected that kernels built without CONFIG_PM_RUNTIME will be the primary use-case for this. This functionality is controlled by adding an extra parameter to omap_hwmod_late_init(). This patch is based on the patch "OMAP: hwmod: don't auto-disable hwmod when !CONFIG_PM_RUNTIME" by Kevin Hilman <khilman@deeprootsystems.com>. Cc: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 253f6e55638c..aebfacb3106e 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -482,8 +482,9 @@ int omap_hwmod_init(struct omap_hwmod **ohs); int omap_hwmod_register(struct omap_hwmod *oh); int omap_hwmod_unregister(struct omap_hwmod *oh); struct omap_hwmod *omap_hwmod_lookup(const char *name); -int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh)); -int omap_hwmod_late_init(void); +int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), + void *data); +int omap_hwmod_late_init(u8 skip_setup_idle); int omap_hwmod_enable(struct omap_hwmod *oh); int _omap_hwmod_enable(struct omap_hwmod *oh); -- cgit v1.2.2 From 681fddc6d087359c1e3f86529973f5bf62afe4c0 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak <rnayak@ti.com> Date: Mon, 26 Jul 2010 16:34:30 -0600 Subject: OMAP4: hwmod: Enable omap_device build for OMAP4 Enable omap_device layer support for OMAP4, so that drivers can use them to enable/idle/shutdown devices. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Benoit Cousson <b-cousson@ti.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 98f01910c2cf..9405831b746a 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o # omap_device support (OMAP2+ only at the moment) obj-$(CONFIG_ARCH_OMAP2) += omap_device.o obj-$(CONFIG_ARCH_OMAP3) += omap_device.o +obj-$(CONFIG_ARCH_OMAP4) += omap_device.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o -- cgit v1.2.2 From 0656358159d7e26205bb9360840759c7c3c0725f Mon Sep 17 00:00:00 2001 From: Kevin Hilman <khilman@deeprootsystems.com> Date: Mon, 26 Jul 2010 16:34:30 -0600 Subject: OMAP: omap_device: ensure hwmod tracks attached omap_device pointer The omap_hwmod struct has a field to track the omap_device that is attached to it, but it was not being assigned. Fix by assigning omap_device pointer when omap_device is built. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> [paul@pwsan.com: use an array index rather than pointer arithmetic] Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/omap_device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f899603051ac..f9dec0d32fa4 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -359,7 +359,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, struct omap_device *od; char *pdev_name2; struct resource *res = NULL; - int res_count; + int i, res_count; struct omap_hwmod **hwmods; if (!ohs || oh_cnt == 0 || !pdev_name) @@ -416,6 +416,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, else ret = omap_device_register(od); + for (i = 0; i < oh_cnt; i++) + hwmods[i]->od = od; + if (ret) goto odbs_exit4; -- cgit v1.2.2 From 6f88e9bc21746be9b15f1d8dcacf7595807e8828 Mon Sep 17 00:00:00 2001 From: Kevin Hilman <khilman@deeprootsystems.com> Date: Mon, 26 Jul 2010 16:34:31 -0600 Subject: OMAP: PM: create omap_devices for MPU, DSP, L3 Create simple omap_devices for the main processors and busses. This is required to support the forth-coming device-based OPP approach, where OPPs are managed and tracked at the device level. Also, move these common PM init functions into a common_pm_init call that is called as a device_initcall(). The PM init is done at this level to ensure that the driver core is initialized before initialized. Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com> [paul@pwsan.com: sparse warnings cleaned up; newly-created functions moved from mach-omap2/io.c to mach-omap2/pm.c; newly-created functions renamed to start with "omap2" rather than "omap"] Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/include/plat/common.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index d265018f5e6b..fe83e901ba6c 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -87,4 +87,8 @@ void omap2_set_globals_uart(struct omap_globals *); } \ }) +extern struct device *omap2_get_mpuss_device(void); +extern struct device *omap2_get_dsp_device(void); +extern struct device *omap2_get_l3_device(void); + #endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */ -- cgit v1.2.2 From db2a60bf2527209b42e6f512d5892089a835ceaa Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:33 -0600 Subject: OMAP: hwmod/device: add omap_{device,hwmod}_get_mpu_rt_va Add omap_device_get_mpu_rt_va(). This is intended to be used by device drivers (currently, via a struct platform_data function pointer) to retrieve their corresponding device's virtual base address that the MPU should use to access the device. This is needed because the omap_hwmod code does its own ioremap(), in order to gain access to the module's OCP_SYSCONFIG register. Add omap_hwmod_get_mpu_rt_va(). omap_device_get_mpu_rt_va() calls this function to do the real work. While here, rename struct omap_hwmod._rt_va to struct omap_hwmod._mpu_rt_va, to reinforce that it refers to the MPU's register target virtual address base (as opposed to, for example, the L3's). In the future, this belongs as a function in an omap_bus, so it is not necessary to call this through a platform_data function pointer. The use-case for this function was originally presented by Santosh Shilimkar <santosh.shilimkar@ti.com>. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com> --- arch/arm/plat-omap/include/plat/omap_device.h | 2 ++ arch/arm/plat-omap/include/plat/omap_hwmod.h | 7 ++++--- arch/arm/plat-omap/omap_device.c | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index 3694b622c4ac..25cd9ac3b095 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h @@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, int omap_device_register(struct omap_device *od); int omap_early_device_register(struct omap_device *od); +void __iomem *omap_device_get_rt_va(struct omap_device *od); + /* OMAP PM interface */ int omap_device_align_pm_lat(struct platform_device *pdev, u32 new_wakeup_lat_limit); diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index aebfacb3106e..a4e508dfaba2 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -1,7 +1,7 @@ /* * omap_hwmod macros, structures * - * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009-2010 Nokia Corporation * Paul Walmsley * * Created in collaboration with (alphabetical order): Benoît Cousson, @@ -419,7 +419,7 @@ struct omap_hwmod_class { * @slaves: ptr to array of OCP ifs that this hwmod can respond on * @dev_attr: arbitrary device attributes that can be passed to the driver * @_sysc_cache: internal-use hwmod flags - * @_rt_va: cached register target start address (internal use) + * @_mpu_rt_va: cached register target start address (internal use) * @_mpu_port_index: cached MPU register target slave ID (internal use) * @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6) * @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift @@ -460,7 +460,7 @@ struct omap_hwmod { struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ void *dev_attr; u32 _sysc_cache; - void __iomem *_rt_va; + void __iomem *_mpu_rt_va; struct list_head node; u16 flags; u8 _mpu_port_index; @@ -507,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh); int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res); struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh); +void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh); int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh); diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f9dec0d32fa4..dee4629b7b47 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -655,6 +655,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) return omap_hwmod_get_pwrdm(od->hwmods[0]); } +/** + * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base + * @od: struct omap_device * + * + * Return the MPU's virtual address for the base of the hwmod, from + * the ioremap() that the hwmod code does. Only valid if there is one + * hwmod associated with this device. Returns NULL if there are zero + * or more than one hwmods associated with this omap_device; + * otherwise, passes along the return value from + * omap_hwmod_get_mpu_rt_va(). + */ +void __iomem *omap_device_get_rt_va(struct omap_device *od) +{ + if (od->hwmods_cnt != 1) + return NULL; + + return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); +} + /* * Public functions intended for use in omap_device_pm_latency * .activate_func and .deactivate_func function pointers -- cgit v1.2.2 From 887adeac28a3e354ebb3f9aeca6fc2296c105267 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:33 -0600 Subject: OMAP2+: hwmod/device: update documentation and copyright MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update some minor documentation issues and update copyright for omap_device/omap_hwmod code. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Benoît Cousson <b-cousson@ti.com> --- arch/arm/plat-omap/omap_device.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index dee4629b7b47..ea0d659fcb1c 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -1,7 +1,7 @@ /* * omap_device implementation * - * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2009-2010 Nokia Corporation * Paul Walmsley, Kevin Hilman * * Developed in collaboration with (alphabetical order): Benoit @@ -90,8 +90,11 @@ #define USE_WAKEUP_LAT 0 #define IGNORE_WAKEUP_LAT 1 - -#define OMAP_DEVICE_MAGIC 0xf00dcafe +/* + * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device + * obtained via container_of() is in fact a struct omap_device + */ +#define OMAP_DEVICE_MAGIC 0xf00dcafe /* Private functions */ -- cgit v1.2.2 From 564889c1c02698d66db76764ee4e0a5e86903971 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:34 -0600 Subject: OMAP: PM constraints: add return values; add requesting device param to omap_pm_set_max_dev_wakeup_lat() Add return values to the PM constraint functions. This allows the PM core to provide feedback to the caller if a constraint is not possible. Update the one upstream user of omap_pm_set_max_mpu_wakeup_lat() to add a compatibility wrapper, needed until the driver is changed. Update some of the documentation to conform more closely to kerneldoc style. Add an additional device parameter to omap_pm_set_max_dev_wakeup_lat() to identify the device requesting the constraint. This is so repeated calls to omap_pm_set_max_dev_wakeup_lat() with the same requesting device can override the device's previously-set constraint. Also, it allows the PM core to make a decision as to whether or not the constraint should be satisfied, based on the caller's identity. Signed-off-by: Paul Walmsley <paul@pwsan.com> --- arch/arm/plat-omap/i2c.c | 12 +++++- arch/arm/plat-omap/include/plat/omap-pm.h | 69 +++++++++++++++++-------------- arch/arm/plat-omap/omap-pm-noop.c | 34 +++++++++------ 3 files changed, 71 insertions(+), 44 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index eec2b4993c69..a5ce4f0aad35 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id) return platform_device_register(pdev); } +/* + * XXX This function is a temporary compatibility wrapper - only + * needed until the I2C driver can be converted to call + * omap_pm_set_max_dev_wakeup_lat() and handle a return code. + */ +static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) +{ + omap_pm_set_max_mpu_wakeup_lat(dev, t); +} + static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) { struct resource *res; @@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) struct omap_i2c_bus_platform_data *pd; pd = pdev->dev.platform_data; - pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat; + pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; } return platform_device_register(pdev); diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h index 3ee41d711492..3d468bafe918 100644 --- a/arch/arm/plat-omap/include/plat/omap-pm.h +++ b/arch/arm/plat-omap/include/plat/omap-pm.h @@ -1,8 +1,8 @@ /* * omap-pm.h - OMAP power management interface * - * Copyright (C) 2008-2009 Texas Instruments, Inc. - * Copyright (C) 2008-2009 Nokia Corporation + * Copyright (C) 2008-2010 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation * Paul Walmsley * * Interface developed by (in alphabetical order): Karthik Dasu, Jouni @@ -89,7 +89,7 @@ void omap_pm_if_exit(void); * @t: maximum MPU wakeup latency in microseconds * * Request that the maximum interrupt latency for the MPU to be no - * greater than 't' microseconds. "Interrupt latency" in this case is + * greater than @t microseconds. "Interrupt latency" in this case is * defined as the elapsed time from the occurrence of a hardware or * timer interrupt to the time when the device driver's interrupt * service routine has been entered by the MPU. @@ -105,15 +105,19 @@ void omap_pm_if_exit(void); * elapsed from when a device driver enables a hardware device with * clk_enable(), to when the device is ready for register access or * other use. To control this device wakeup latency, use - * set_max_dev_wakeup_lat() + * omap_pm_set_max_dev_wakeup_lat() * - * Multiple calls to set_max_mpu_wakeup_lat() will replace the + * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the * previous t value. To remove the latency target for the MPU, call * with t = -1. * - * No return value. + * XXX This constraint will be deprecated soon in favor of the more + * general omap_pm_set_max_dev_wakeup_lat() + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. */ -void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); +int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); /** @@ -123,8 +127,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); * @r: minimum throughput (in KiB/s) * * Request that the minimum data throughput on the OCP interconnect - * attached to device 'dev' interconnect agent 'tbus_id' be no less - * than 'r' KiB/s. + * attached to device @dev interconnect agent @tbus_id be no less + * than @r KiB/s. * * It is expected that the OMAP PM or bus code will use this * information to set the interconnect clock to run at the lowest @@ -138,40 +142,44 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t); * code will also need to add an minimum L3 interconnect speed * constraint, * - * Multiple calls to set_min_bus_tput() will replace the previous rate - * value for this device. To remove the interconnect throughput - * restriction for this device, call with r = 0. + * Multiple calls to omap_pm_set_min_bus_tput() will replace the + * previous rate value for this device. To remove the interconnect + * throughput restriction for this device, call with r = 0. * - * No return value. + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. */ -void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r); +int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r); /** * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency - * @dev: struct device * + * @req_dev: struct device * requesting the constraint, or NULL if none + * @dev: struct device * to set the constraint one * @t: maximum device wakeup latency in microseconds * - * Request that the maximum amount of time necessary for a device to - * become accessible after its clocks are enabled should be no greater - * than 't' microseconds. Specifically, this represents the time from - * when a device driver enables device clocks with clk_enable(), to - * when the register reads and writes on the device will succeed. - * This function should be called before clk_disable() is called, - * since the power state transition decision may be made during - * clk_disable(). + * Request that the maximum amount of time necessary for a device @dev + * to become accessible after its clocks are enabled should be no + * greater than @t microseconds. Specifically, this represents the + * time from when a device driver enables device clocks with + * clk_enable(), to when the register reads and writes on the device + * will succeed. This function should be called before clk_disable() + * is called, since the power state transition decision may be made + * during clk_disable(). * * It is intended that underlying PM code will use this information to * determine what power state to put the powerdomain enclosing this * device into. * - * Multiple calls to set_max_dev_wakeup_lat() will replace the - * previous wakeup latency values for this device. To remove the wakeup - * latency restriction for this device, call with t = -1. + * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the + * previous wakeup latency values for this device. To remove the + * wakeup latency restriction for this device, call with t = -1. * - * No return value. + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. */ -void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t); +int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev, + long t); /** @@ -198,9 +206,10 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t); * value for this device. To remove the maximum DMA latency for this * device, call with t = -1. * - * No return value. + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. */ -void omap_pm_set_max_sdma_lat(struct device *dev, long t); +int omap_pm_set_max_sdma_lat(struct device *dev, long t); /* diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index 186bca82cfab..b0414f90c6e3 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -34,11 +34,11 @@ struct omap_opp *l3_opps; * Device-driver-originated constraints (via board-*.c files) */ -void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) +int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) { if (!dev || t < -1) { - WARN_ON(1); - return; + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; }; if (t == -1) @@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t) * * TI CDP code can call constraint_set here. */ + + return 0; } -void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) +int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) { if (!dev || (agent_id != OCP_INITIATOR_AGENT && agent_id != OCP_TARGET_AGENT)) { - WARN_ON(1); - return; + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; }; if (r == 0) @@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r) * * TI CDP code can call constraint_set here on the VDD2 OPP. */ + + return 0; } -void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) +int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev, + long t) { - if (!dev || t < -1) { - WARN_ON(1); - return; + if (!req_dev || !dev || t < -1) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; }; if (t == -1) @@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t) * * TI CDP code can call constraint_set here. */ + + return 0; } -void omap_pm_set_max_sdma_lat(struct device *dev, long t) +int omap_pm_set_max_sdma_lat(struct device *dev, long t) { if (!dev || t < -1) { - WARN_ON(1); - return; + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; }; if (t == -1) @@ -139,6 +146,7 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t) * TI CDP code can call constraint_set here. */ + return 0; } -- cgit v1.2.2 From fb8ce14c7e16bd218decb3e1655c5d4ff08042f2 Mon Sep 17 00:00:00 2001 From: Paul Walmsley <paul@pwsan.com> Date: Mon, 26 Jul 2010 16:34:34 -0600 Subject: OMAP: PM constraints: add omap_pm_set_min_clk_rate() Add omap_pm_set_min_clk_rate(). This constraint is meant for use by device drivers to translate a certain device-specific performance constraint (e.g., "minimum polygons per second") to a clock rate for the driver's device, given the driver's intimate knowledge of the device hardware (e.g., device type, device hardware revision, firmware revision, etc.) From a general PM core perspective, clock rate is probably the closest general analog to "performance" that is available, but the exact mapping from a use-case-specific performance constraint to clock rate must be done by the driver. Drivers intended for upstream merging shouldn't hardcode specific clock rates in their code without basing those rates on some performance criteria requested through the driver's subsystem (ideally, from userspace). Imre Deak <imre.deak@nokia.com> described the need and use-case for this constraint, and discussed the implementation - thanks, Imre. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Imre Deak <imre.deak@nokia.com> --- arch/arm/plat-omap/include/plat/omap-pm.h | 61 +++++++++++++++++++++++++++++++ arch/arm/plat-omap/omap-pm-noop.c | 27 ++++++++++++++ 2 files changed, 88 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h index 3d468bafe918..728fbb9dd549 100644 --- a/arch/arm/plat-omap/include/plat/omap-pm.h +++ b/arch/arm/plat-omap/include/plat/omap-pm.h @@ -16,6 +16,7 @@ #include <linux/device.h> #include <linux/cpufreq.h> +#include <linux/clk.h> #include "powerdomain.h" @@ -212,6 +213,66 @@ int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev, int omap_pm_set_max_sdma_lat(struct device *dev, long t); +/** + * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev + * @dev: struct device * requesting the constraint + * @clk: struct clk * to set the minimum rate constraint on + * @r: minimum rate in Hz + * + * Request that the minimum clock rate on the device @dev's clk @clk + * be no less than @r Hz. + * + * It is expected that the OMAP PM code will use this information to + * find an OPP or clock setting that will satisfy this clock rate + * constraint, along with any other applicable system constraints on + * the clock rate or corresponding voltage, etc. + * + * omap_pm_set_min_clk_rate() differs from the clock code's + * clk_set_rate() in that it considers other constraints before taking + * any hardware action, and may change a system OPP rather than just a + * clock rate. clk_set_rate() is intended to be a low-level + * interface. + * + * omap_pm_set_min_clk_rate() is easily open to abuse. A better API + * would be something like "omap_pm_set_min_dev_performance()"; + * however, there is no easily-generalizable concept of performance + * that applies to all devices. Only a device (and possibly the + * device subsystem) has both the subsystem-specific knowledge, and + * the hardware IP block-specific knowledge, to translate a constraint + * on "touchscreen sampling accuracy" or "number of pixels or polygons + * rendered per second" to a clock rate. This translation can be + * dependent on the hardware IP block's revision, or firmware version, + * and the driver is the only code on the system that has this + * information and can know how to translate that into a clock rate. + * + * The intended use-case for this function is for userspace or other + * kernel code to communicate a particular performance requirement to + * a subsystem; then for the subsystem to communicate that requirement + * to something that is meaningful to the device driver; then for the + * device driver to convert that requirement to a clock rate, and to + * then call omap_pm_set_min_clk_rate(). + * + * Users of this function (such as device drivers) should not simply + * call this function with some high clock rate to ensure "high + * performance." Rather, the device driver should take a performance + * constraint from its subsystem, such as "render at least X polygons + * per second," and use some formula or table to convert that into a + * clock rate constraint given the hardware type and hardware + * revision. Device drivers or subsystems should not assume that they + * know how to make a power/performance tradeoff - some device use + * cases may tolerate a lower-fidelity device function for lower power + * consumption; others may demand a higher-fidelity device function, + * no matter what the power consumption. + * + * Multiple calls to omap_pm_set_min_clk_rate() will replace the + * previous rate value for the device @dev. To remove the minimum clock + * rate constraint for the device, call with r = 0. + * + * Returns -EINVAL for an invalid argument, -ERANGE if the constraint + * is not satisfiable, or 0 upon success. + */ +int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r); + /* * DSP Bridge-specific constraints */ diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c index b0414f90c6e3..e129ce80c53b 100644 --- a/arch/arm/plat-omap/omap-pm-noop.c +++ b/arch/arm/plat-omap/omap-pm-noop.c @@ -149,6 +149,33 @@ int omap_pm_set_max_sdma_lat(struct device *dev, long t) return 0; } +int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r) +{ + if (!dev || !c || r < 0) { + WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__); + return -EINVAL; + } + + if (r == 0) + pr_debug("OMAP PM: remove min clk rate constraint: " + "dev %s\n", dev_name(dev)); + else + pr_debug("OMAP PM: add min clk rate constraint: " + "dev %s, rate = %ld Hz\n", dev_name(dev), r); + + /* + * Code in a real implementation should keep track of these + * constraints on the clock, and determine the highest minimum + * clock rate. It should iterate over each OPP and determine + * whether the OPP will result in a clock rate that would + * satisfy this constraint (and any other PM constraint in effect + * at that time). Once it finds the lowest-voltage OPP that + * meets those conditions, it should switch to it, or return + * an error if the code is not capable of doing so. + */ + + return 0; +} /* * DSP Bridge-specific constraints -- cgit v1.2.2 From 3f9eaf0984952f69cb2d0c1b0f99b95b74742094 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar <santosh.shilimkar@ti.com> Date: Mon, 2 Aug 2010 13:18:18 +0300 Subject: omap4: Add smc API to read AuxCoreBoot0 register This patch adds a secure API to read AuxCoreBoot0 register to check the cpu boot status. It also moves the other smc APIs to common omap44xx-smc.S. This APIs should not be marked as __INIT because we need these to be present for CPU hotplug Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/smp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 8983d54c4fd2..6a3ff65c0303 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h @@ -30,6 +30,7 @@ extern void omap_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); extern void omap_auxcoreboot_addr(u32 cpu_addr); +extern u32 omap_read_auxcoreboot0(void); /* * We use Soft IRQ1 as the IPI -- cgit v1.2.2 From 35ddf7c003f54fc9878a15384beb9a900d40319d Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 2 Aug 2010 14:21:39 +0300 Subject: omap: Add back UART MDR1 check into uncompress.h Recent DEBUG_LL and uncompress.h changes removed the check_port() as pointed out by Cory Maccarrone <darkstar6262@gmail.com>. This causes some boards to not boot, so add back the MDR1 register check. The MDR1 register tells the mode of omap uart. Based on an earlier patch by Cory Maccarrone <darkstar6262@gmail.com>. Tested-by: Cory Maccarrone <darkstar6262@gmail.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/uncompress.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index bbedd71943f6..ddf723be48dc 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -25,6 +25,8 @@ #include <plat/serial.h> +#define MDR1_MODE_MASK 0x07 + static volatile u8 *uart_base; static int uart_shift; @@ -42,6 +44,10 @@ static void putc(int c) if (!uart_base) return; + /* Check for UART 16x mode */ + if ((uart_base[UART_OMAP_MDR1 << uart_shift] & MDR1_MODE_MASK) != 0) + return; + while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE)) barrier(); uart_base[UART_TX << uart_shift] = c; -- cgit v1.2.2 From 8b8fbd39e20b5db95f8f4b3bda4c9d3fcf8e3afc Mon Sep 17 00:00:00 2001 From: Cory Maccarrone <darkstar6262@gmail.com> Date: Mon, 2 Aug 2010 14:21:39 +0300 Subject: omap1: omap7xx clocks, mux, serial fixes This change adds in the necessary clocks and mux pins for UART control on omap7xx devices. I also made a change in the serial code to only try and initialize two UARTs in omap_serial_init, as these devices don't have three. Signed-off-by: Cory Maccarrone <darkstar6262@gmail.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/mux.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h index c7472a28ce24..82c374c2f868 100644 --- a/arch/arm/plat-omap/include/plat/mux.h +++ b/arch/arm/plat-omap/include/plat/mux.h @@ -191,6 +191,10 @@ enum omap7xx_index { SPI_7XX_4, SPI_7XX_5, SPI_7XX_6, + + /* UART */ + UART_7XX_1, + UART_7XX_2, }; enum omap1xxx_index { -- cgit v1.2.2 From 25d6f63093ef5fa596318d7790e6d5029a711a75 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 2 Aug 2010 14:21:39 +0300 Subject: omap2: Fix GPIO numbers and smc91x for 2430sdp Fix GPIO numbers and smc91x for 2430sdp. The earlier code had cut and paste errors from 3430sdp code. Also, 2430 has five GPIO banks for a total of 160 GPIO lines. Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/gpio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 9b7e3545f325..7951eefe1a0e 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -390,7 +390,9 @@ static inline int gpio_valid(int gpio) return 0; if (cpu_is_omap7xx() && gpio < 192) return 0; - if (cpu_is_omap24xx() && gpio < 128) + if (cpu_is_omap2420() && gpio < 128) + return 0; + if (cpu_is_omap2430() && gpio < 160) return 0; if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192) return 0; -- cgit v1.2.2 From 72a1179ed41e0fc6bd5eb58e02e8d230eba10e24 Mon Sep 17 00:00:00 2001 From: Samu Onkalo <samu.p.onkalo@nokia.com> Date: Mon, 2 Aug 2010 14:21:40 +0300 Subject: omap: dma: Support for prefetch in destination synchronizedtransfer Omap DMA controller can prefetch data in advance in case of destination synchronized data transfer. This may increase performance when target HW block doesn't have fifo. Data is waiting for transfer request in DMA fifo instead of read from memory. Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/dma.c | 11 +++++++---- arch/arm/plat-omap/include/plat/dma.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index f7f571e7987e..ec7eddf9e525 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -290,7 +290,7 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, val = dma_read(CCR(lch)); /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */ - val &= ~((3 << 19) | 0x1f); + val &= ~((1 << 23) | (3 << 19) | 0x1f); val |= (dma_trigger & ~0x1f) << 14; val |= dma_trigger & 0x1f; @@ -304,11 +304,14 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, else val &= ~(1 << 18); - if (src_or_dst_synch) + if (src_or_dst_synch == OMAP_DMA_DST_SYNC_PREFETCH) { + val &= ~(1 << 24); /* dest synch */ + val |= (1 << 23); /* Prefetch */ + } else if (src_or_dst_synch) { val |= 1 << 24; /* source synch */ - else + } else { val &= ~(1 << 24); /* dest synch */ - + } dma_write(val, CCR(lch)); } diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h index 02232ca2c37f..af3a03941add 100644 --- a/arch/arm/plat-omap/include/plat/dma.h +++ b/arch/arm/plat-omap/include/plat/dma.h @@ -345,6 +345,7 @@ #define OMAP_DMA_SYNC_BLOCK 0x02 #define OMAP_DMA_SYNC_PACKET 0x03 +#define OMAP_DMA_DST_SYNC_PREFETCH 0x02 #define OMAP_DMA_SRC_SYNC 0x01 #define OMAP_DMA_DST_SYNC 0x00 -- cgit v1.2.2 From ad0c63f1d623ea9d3e0c0521d5ce9cd522c4e1f0 Mon Sep 17 00:00:00 2001 From: "stanley.miao" <stanley.miao@windriver.com> Date: Mon, 2 Aug 2010 14:21:40 +0300 Subject: OMAP3: AM3505/3517 do not have IO wakeup capability AM3505/3517 doesn't have IO wakeup capability, so we do not need to set the bit OMAP3430_EN_IO and the bit OMAP3430_EN_IO_CHAIN in the register PM_WKEN_WKUP when the system enters suspend state. Tested on AM3517EVM and OMAP3530EVM. Signed-off-by: Stanley.Miao <stanley.miao@windriver.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/cpu.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index 75141742300c..aa2f4f079f57 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -444,6 +444,7 @@ extern u32 omap3_features; #define OMAP3_HAS_NEON BIT(3) #define OMAP3_HAS_ISP BIT(4) #define OMAP3_HAS_192MHZ_CLK BIT(5) +#define OMAP3_HAS_IO_WAKEUP BIT(6) #define OMAP3_HAS_FEATURE(feat,flag) \ static inline unsigned int omap3_has_ ##feat(void) \ @@ -457,5 +458,6 @@ OMAP3_HAS_FEATURE(iva, IVA) OMAP3_HAS_FEATURE(neon, NEON) OMAP3_HAS_FEATURE(isp, ISP) OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) +OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) #endif -- cgit v1.2.2 From 948d38e799f0ab87cf8ed9113fcdaaee61acf321 Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai <s-ghorai@ti.com> Date: Fri, 9 Jul 2010 09:14:44 +0000 Subject: omap3 gpmc: functionality enhancement few functions added in gpmc module and to be used by other drivers like NAND. Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/gpmc.h | 39 +++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 145838a81ef6..561c64f5ab50 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -27,8 +27,27 @@ #define GPMC_CONFIG 0x50 #define GPMC_STATUS 0x54 -#define GPMC_CS0_BASE 0x60 -#define GPMC_CS_SIZE 0x30 + +/* Control Commands */ +#define GPMC_CONFIG_RDY_BSY 0x00000001 +#define GPMC_CONFIG_DEV_SIZE 0x00000002 +#define GPMC_CONFIG_DEV_TYPE 0x00000003 +#define GPMC_SET_IRQ_STATUS 0x00000004 +#define GPMC_CONFIG_WP 0x00000005 + +#define GPMC_GET_IRQ_STATUS 0x00000006 +#define GPMC_PREFETCH_FIFO_CNT 0x00000007 /* bytes available in FIFO for r/w */ +#define GPMC_PREFETCH_COUNT 0x00000008 /* remaining bytes to be read/write*/ +#define GPMC_STATUS_BUFFER 0x00000009 /* 1: buffer is available to write */ + +#define GPMC_NAND_COMMAND 0x0000000a +#define GPMC_NAND_ADDRESS 0x0000000b +#define GPMC_NAND_DATA 0x0000000c + +/* ECC commands */ +#define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ +#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ +#define GPMC_ECC_READSYN 2 /* Reset before syndrom is read back */ #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) @@ -56,6 +75,14 @@ #define GPMC_CONFIG1_FCLK_DIV4 (GPMC_CONFIG1_FCLK_DIV(3)) #define GPMC_CONFIG7_CSVALID (1 << 6) +#define GPMC_DEVICETYPE_NOR 0 +#define GPMC_DEVICETYPE_NAND 2 +#define GPMC_CONFIG_WRITEPROTECT 0x00000010 +#define GPMC_STATUS_BUFF_EMPTY 0x00000001 +#define WR_RD_PIN_MONITORING 0x00600000 +#define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) +#define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) + /* * Note that all values in this struct are in nanoseconds, while * the register values are in gpmc_fck cycles. @@ -108,10 +135,16 @@ extern int gpmc_cs_set_reserved(int cs, int reserved); extern int gpmc_cs_reserved(int cs); extern int gpmc_prefetch_enable(int cs, int dma_mode, unsigned int u32_count, int is_write); -extern void gpmc_prefetch_reset(void); +extern int gpmc_prefetch_reset(int cs); extern int gpmc_prefetch_status(void); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); extern void gpmc_init(void); +extern int gpmc_read_status(int cmd); +extern int gpmc_cs_configure(int cs, int cmd, int wval); +extern int gpmc_nand_read(int cs, int cmd); +extern int gpmc_nand_write(int cs, int cmd, int wval); +int gpmc_enable_hwecc(int cs, int mode, int dev_width, int ecc_size); +int gpmc_calculate_ecc(int cs, const u_char *dat, u_char *ecc_code); #endif -- cgit v1.2.2 From 2c01946c6b9ebaa5a89710bc42ca224a7f52f227 Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai <s-ghorai@ti.com> Date: Fri, 9 Jul 2010 09:14:45 +0000 Subject: omap3 nand: cleanup virtual address usages This patch removes direct reference of gpmc address from generic nand platform code. Nand platform code now uses wrapper functions which are implemented in gpmc module. Signed-off-by: Sukumar Ghorai <s-ghorai@ti.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/gpmc.h | 5 ----- arch/arm/plat-omap/include/plat/nand.h | 6 ++---- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h index 561c64f5ab50..9fd99b9e40ab 100644 --- a/arch/arm/plat-omap/include/plat/gpmc.h +++ b/arch/arm/plat-omap/include/plat/gpmc.h @@ -25,9 +25,6 @@ #define GPMC_CS_NAND_ADDRESS 0x20 #define GPMC_CS_NAND_DATA 0x24 -#define GPMC_CONFIG 0x50 -#define GPMC_STATUS 0x54 - /* Control Commands */ #define GPMC_CONFIG_RDY_BSY 0x00000001 #define GPMC_CONFIG_DEV_SIZE 0x00000002 @@ -66,7 +63,6 @@ #define GPMC_CONFIG1_DEVICESIZE_16 GPMC_CONFIG1_DEVICESIZE(1) #define GPMC_CONFIG1_DEVICETYPE(val) ((val & 3) << 10) #define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0) -#define GPMC_CONFIG1_DEVICETYPE_NAND GPMC_CONFIG1_DEVICETYPE(2) #define GPMC_CONFIG1_MUXADDDATA (1 << 9) #define GPMC_CONFIG1_TIME_PARA_GRAN (1 << 4) #define GPMC_CONFIG1_FCLK_DIV(val) (val & 3) @@ -136,7 +132,6 @@ extern int gpmc_cs_reserved(int cs); extern int gpmc_prefetch_enable(int cs, int dma_mode, unsigned int u32_count, int is_write); extern int gpmc_prefetch_reset(int cs); -extern int gpmc_prefetch_status(void); extern void omap3_gpmc_save_context(void); extern void omap3_gpmc_restore_context(void); extern void gpmc_init(void); diff --git a/arch/arm/plat-omap/include/plat/nand.h b/arch/arm/plat-omap/include/plat/nand.h index f8efd5466b1d..6562cd082bb1 100644 --- a/arch/arm/plat-omap/include/plat/nand.h +++ b/arch/arm/plat-omap/include/plat/nand.h @@ -21,13 +21,11 @@ struct omap_nand_platform_data { int (*dev_ready)(struct omap_nand_platform_data *); int dma_channel; unsigned long phys_base; - void __iomem *gpmc_cs_baseaddr; - void __iomem *gpmc_baseaddr; int devsize; }; -/* size (4 KiB) for IO mapping */ -#define NAND_IO_SIZE SZ_4K +/* minimum size for IO mapping */ +#define NAND_IO_SIZE 4 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE) extern int gpmc_nand_init(struct omap_nand_platform_data *d); -- cgit v1.2.2 From 5a1819e3a82b65454cbba818efe0528785c9fb6a Mon Sep 17 00:00:00 2001 From: Tobias Klauser <tklauser@distanz.ch> Date: Thu, 20 May 2010 17:12:52 +0200 Subject: OMAP: DSS2: storage class should be before const qualifier The C99 specification states in section 6.11.5: The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> --- arch/arm/plat-omap/include/plat/display.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index 1c529ce9dc11..fbbb966a994f 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -277,8 +277,8 @@ struct omap_video_timings { * identify the mode, and does not actually use the configs * itself. However, the configs should be something that * a normal monitor can also show */ -const extern struct omap_video_timings omap_dss_pal_timings; -const extern struct omap_video_timings omap_dss_ntsc_timings; +extern const struct omap_video_timings omap_dss_pal_timings; +extern const struct omap_video_timings omap_dss_ntsc_timings; #endif struct omap_overlay_info { -- cgit v1.2.2 From 0c244f770f7fdb3e6779b3433aac9cfb6deb3255 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@nokia.com> Date: Wed, 9 Jun 2010 15:19:29 +0300 Subject: OMAP: DSS2: DSI: change dsi_vc_dcs_read_2 parameters Change dsi_vc_dcs_read_2() data parameter to two u8 parameters to make the byte-order clear. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> --- arch/arm/plat-omap/include/plat/display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index fbbb966a994f..b8de70479313 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -238,7 +238,7 @@ int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param); int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len); int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen); int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data); -int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u16 *data); +int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2); int dsi_vc_set_max_rx_packet_size(int channel, u16 len); int dsi_vc_send_null(int channel); int dsi_vc_send_bta_sync(int channel); -- cgit v1.2.2 From 823c8e4a8ae6c5792e0b35b49d2b63292a28575d Mon Sep 17 00:00:00 2001 From: Jani Nikula <ext-jani.1.nikula@nokia.com> Date: Thu, 22 Apr 2010 15:27:36 +0300 Subject: OMAP: DSS2: Add Nokia DSI command mode panel configuration struct Introduce a configuration struct for platform/board specific information of Nokia DSI command mode panels, to be used in addition to struct omap_dss_device (passed via the 'void *data' member). Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> --- arch/arm/plat-omap/include/plat/nokia-dsi-panel.h | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 arch/arm/plat-omap/include/plat/nokia-dsi-panel.h (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h b/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h new file mode 100644 index 000000000000..01ab6572ccbb --- /dev/null +++ b/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h @@ -0,0 +1,31 @@ +#ifndef __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H +#define __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H + +#include "display.h" + +/** + * struct nokia_dsi_panel_data - Nokia DSI panel driver configuration + * @name: panel name + * @use_ext_te: use external TE + * @ext_te_gpio: external TE GPIO + * @use_esd_check: perform ESD checks + * @max_backlight_level: maximum backlight level + * @set_backlight: pointer to backlight set function + * @get_backlight: pointer to backlight get function + */ +struct nokia_dsi_panel_data { + const char *name; + + int reset_gpio; + + bool use_ext_te; + int ext_te_gpio; + + bool use_esd_check; + + int max_backlight_level; + int (*set_backlight)(struct omap_dss_device *dssdev, int level); + int (*get_backlight)(struct omap_dss_device *dssdev); +}; + +#endif /* __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H */ -- cgit v1.2.2 From c573bcf96a427923d09de0b247691165d9a96023 Mon Sep 17 00:00:00 2001 From: Sergio Aguirre <saaguirre@ti.com> Date: Wed, 4 Aug 2010 14:43:18 +0300 Subject: omap3: Unify omap2_set_globals_3[43,6x]x functions The only difference between them is the physical address of the uart4 port, which is only present in 36xx chips. We don't really need to care about keeping these 2 functions, since the decision to use uart4 is more cleanly done later when we do have access to omap_revision variable. Signed-off-by: Sergio Aguirre <saaguirre@ti.com> Acked-by: Kevin Hilman <khilman@deeprootsystems.com> [tony@atomide.com: added comment for the uart4_phys] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/common.c | 10 ++-------- arch/arm/plat-omap/include/plat/common.h | 3 +-- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index ebed82699eb2..8932350abfd2 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -317,19 +317,13 @@ static struct omap_globals omap3_globals = { .uart1_phys = OMAP3_UART1_BASE, .uart2_phys = OMAP3_UART2_BASE, .uart3_phys = OMAP3_UART3_BASE, + .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */ }; -void __init omap2_set_globals_343x(void) +void __init omap2_set_globals_3xxx(void) { __omap2_set_globals(&omap3_globals); } - -void __init omap2_set_globals_36xx(void) -{ - omap3_globals.uart4_phys = OMAP3_UART4_BASE; - - __omap2_set_globals(&omap3_globals); -} #endif #if defined(CONFIG_ARCH_OMAP4) diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 5e4afbee0fd7..962aaebf59d4 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -58,8 +58,7 @@ struct omap_globals { void omap2_set_globals_242x(void); void omap2_set_globals_243x(void); -void omap2_set_globals_343x(void); -void omap2_set_globals_36xx(void); +void omap2_set_globals_3xxx(void); void omap2_set_globals_443x(void); /* These get called from omap2_set_globals_xxxx(), do not call these */ -- cgit v1.2.2 From 869fef41547db95df8523bf67845a21313709428 Mon Sep 17 00:00:00 2001 From: Mike Rapoport <mike@compulab.co.il> Date: Wed, 4 Aug 2010 14:43:18 +0300 Subject: omap3: introduce omap3_map_io Most OMAP3-based boards use exactly the same code for .map_io method in the machine_desc structure. This patch introduces omap3_map_io and updates board-* files to use it as .map_io method. Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/common.c | 6 ++++++ arch/arm/plat-omap/include/plat/common.h | 2 ++ 2 files changed, 8 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index 8932350abfd2..3008e7104487 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -324,6 +324,12 @@ void __init omap2_set_globals_3xxx(void) { __omap2_set_globals(&omap3_globals); } + +void __init omap3_map_io(void) +{ + omap2_set_globals_3xxx(); + omap34xx_map_common_io(); +} #endif #if defined(CONFIG_ARCH_OMAP4) diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 962aaebf59d4..e9cf3da18a09 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -68,6 +68,8 @@ void omap2_set_globals_control(struct omap_globals *); void omap2_set_globals_prcm(struct omap_globals *); void omap2_set_globals_uart(struct omap_globals *); +void omap3_map_io(void); + /** * omap_test_timeout - busy-loop, testing a condition * @cond: condition to test until it evaluates to true -- cgit v1.2.2 From 49b368a6b3e803fe4f0a10c14f8fde3f20998f04 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Date: Mon, 12 Jul 2010 13:38:07 +0000 Subject: omap: device: improve errors handling Do not forget to check the 'platform_device_add_data()' error code in 'omap_device_build_ss()'. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Acked-by: Nishanth Menon <nm@ti.com> Acked-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/omap_device.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index ea0d659fcb1c..d2b160942ccc 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c @@ -407,7 +407,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id, od->pdev.num_resources = res_count; od->pdev.resource = res; - platform_device_add_data(&od->pdev, pdata, pdata_len); + ret = platform_device_add_data(&od->pdev, pdata, pdata_len); + if (ret) + goto odbs_exit4; od->pm_lats = pm_lats; od->pm_lats_cnt = pm_lats_cnt; -- cgit v1.2.2 From b0a1a6ce0597662c06f970643da60b8ebb5cdd1c Mon Sep 17 00:00:00 2001 From: Anand Gadiyar <gadiyar@ti.com> Date: Tue, 3 Aug 2010 19:59:24 +0000 Subject: OMAP3630: Add ES1.1 and ES1.2 detection Add revision detection for ES1.1 and ES1.2. Set default revision as ES1.2. Add CHIP_GE_OMAP3630ES1_1 to detect revisions 1.1 and later. This is needed for at least one feature that is broken in 3630ES1.0 but exists on older (3430 ES3.1) and newer revisions. Additionally, update some of the CHIP_GE_* macros to use other macros for ease of maintenance. Signed-off-by: Anand Gadiyar <gadiyar@ti.com> Cc: Nishanth Menon <nm@ti.com> Cc: Manjunatha GK <manjugk@ti.com> [tony@atomide.com: update to remove fallthrough handling] Signed-off-by: Tony Lindgren <tony@atomide.com> --- arch/arm/plat-omap/include/plat/cpu.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h index aa2f4f079f57..2e2ae530fced 100644 --- a/arch/arm/plat-omap/include/plat/cpu.h +++ b/arch/arm/plat-omap/include/plat/cpu.h @@ -66,6 +66,8 @@ unsigned int omap_rev(void); * family. This difference can be handled separately. */ #define OMAP_REVBITS_00 0x00 +#define OMAP_REVBITS_01 0x01 +#define OMAP_REVBITS_02 0x02 #define OMAP_REVBITS_10 0x10 #define OMAP_REVBITS_20 0x20 #define OMAP_REVBITS_30 0x30 @@ -376,6 +378,8 @@ IS_OMAP_TYPE(3517, 0x3517) #define OMAP3430_REV_ES3_1_2 0x34305034 #define OMAP3630_REV_ES1_0 0x36300034 +#define OMAP3630_REV_ES1_1 0x36300134 +#define OMAP3630_REV_ES1_2 0x36300234 #define OMAP35XX_CLASS 0x35000034 #define OMAP3503_REV(v) (OMAP35XX_CLASS | (0x3503 << 16) | (v << 8)) @@ -411,6 +415,8 @@ IS_OMAP_TYPE(3517, 0x3517) #define CHIP_IS_OMAP3430ES3_1 (1 << 6) #define CHIP_IS_OMAP3630ES1 (1 << 7) #define CHIP_IS_OMAP4430ES1 (1 << 8) +#define CHIP_IS_OMAP3630ES1_1 (1 << 9) +#define CHIP_IS_OMAP3630ES1_2 (1 << 10) #define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) @@ -424,11 +430,12 @@ IS_OMAP_TYPE(3517, 0x3517) */ #define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \ CHIP_IS_OMAP3430ES3_0 | \ - CHIP_IS_OMAP3430ES3_1 | \ - CHIP_IS_OMAP3630ES1) + CHIP_GE_OMAP3430ES3_1) #define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1 | \ - CHIP_IS_OMAP3630ES1) - + CHIP_IS_OMAP3630ES1 | \ + CHIP_GE_OMAP3630ES1_1) +#define CHIP_GE_OMAP3630ES1_1 (CHIP_IS_OMAP3630ES1_1 | \ + CHIP_IS_OMAP3630ES1_2) int omap_chip_is(struct omap_chip_id oci); void omap2_check_revision(void); -- cgit v1.2.2 From ad6d962735eb48dde1851269bdeaa042fdb39172 Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo <x0095840@ti.com> Date: Fri, 12 Feb 2010 19:02:32 -0600 Subject: Mailbox: free mailbox interrupt before freeing blk queue Free interrupt before freeing blk_queue to avoid any attempt of access to blk_queue after it was freed. Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 08a2df766289..252a58698ef7 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -298,11 +298,10 @@ static int omap_mbox_startup(struct omap_mbox *mbox) static void omap_mbox_fini(struct omap_mbox *mbox) { + free_irq(mbox->irq, mbox); mbox_queue_free(mbox->txq); mbox_queue_free(mbox->rxq); - free_irq(mbox->irq, mbox); - if (unlikely(mbox->ops->shutdown)) { write_lock(&mboxes_lock); if (mbox_configured > 0) -- cgit v1.2.2 From 0e828e8c2bab6d30649447eea68686413c92d340 Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo <x0095840@ti.com> Date: Fri, 12 Feb 2010 19:07:14 -0600 Subject: Mailbox: flush pending deferred works before freeing blk queue flush pending deferred works before freeing blk_queue to prevent any attempt of access to blk_queue after it was freed Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 252a58698ef7..77c23f5a0037 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -299,6 +299,8 @@ static int omap_mbox_startup(struct omap_mbox *mbox) static void omap_mbox_fini(struct omap_mbox *mbox) { free_irq(mbox->irq, mbox); + tasklet_kill(&mbox->txq->tasklet); + flush_work(&mbox->rxq->work); mbox_queue_free(mbox->txq); mbox_queue_free(mbox->rxq); -- cgit v1.2.2 From 9caae4d87ca0087edd6c02efd674f13fe0419ee9 Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo <x0095840@ti.com> Date: Wed, 27 Jan 2010 20:04:02 -0600 Subject: Mailbox: Check valid registered callback before calling This patch checks if the mailbox user has assinged a valid callback fuction before calling it. Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 77c23f5a0037..72efbe5be578 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -146,7 +146,8 @@ static void mbox_rx_work(struct work_struct *work) msg = (mbox_msg_t)rq->special; blk_end_request_all(rq, 0); - mbox->rxq->callback((void *)msg); + if (mbox->rxq->callback) + mbox->rxq->callback((void *)msg); } } -- cgit v1.2.2 From 72b917ef90084885ffcc5adb69095af02d2b6996 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> Date: Thu, 18 Feb 2010 00:48:55 -0600 Subject: Mailbox: new mutext lock for h/w mailbox configuration mailbox startup and shutdown are being executed against a single H/W module, and a mailbox H/W module is totally __independent__ of the registration of logical mailboxes. So, an independent mutext should be used for startup and shutdown. Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 72efbe5be578..986002b089fd 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -34,6 +34,7 @@ static struct omap_mbox *mboxes; static DEFINE_RWLOCK(mboxes_lock); static int mbox_configured; +static DEFINE_MUTEX(mbox_configured_lock); /* Mailbox FIFO handle functions */ static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) @@ -250,16 +251,16 @@ static int omap_mbox_startup(struct omap_mbox *mbox) struct omap_mbox_queue *mq; if (likely(mbox->ops->startup)) { - write_lock(&mboxes_lock); + mutex_lock(&mbox_configured_lock); if (!mbox_configured) ret = mbox->ops->startup(mbox); if (unlikely(ret)) { - write_unlock(&mboxes_lock); + mutex_unlock(&mbox_configured_lock); return ret; } mbox_configured++; - write_unlock(&mboxes_lock); + mutex_unlock(&mbox_configured_lock); } ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, @@ -306,12 +307,12 @@ static void omap_mbox_fini(struct omap_mbox *mbox) mbox_queue_free(mbox->rxq); if (unlikely(mbox->ops->shutdown)) { - write_lock(&mboxes_lock); + mutex_lock(&mbox_configured_lock); if (mbox_configured > 0) mbox_configured--; if (!mbox_configured) mbox->ops->shutdown(mbox); - write_unlock(&mboxes_lock); + mutex_unlock(&mbox_configured_lock); } } -- cgit v1.2.2 From 1ea5d6d18bf1d528ae1081b9176d69c00bd51fa2 Mon Sep 17 00:00:00 2001 From: Fernando Guzman Lugo <x0095840@ti.com> Date: Mon, 8 Feb 2010 13:35:40 -0600 Subject: Mailbox: disable mailbox interrupt when request queue when blk_get_request fails to get the request it is returning without read the message from the mailbox fifo, then when it leaves the isr and interruption is trigger again and again and the workqueue which get elements from the request queue is never executed and the kernel is stuck and shows a softlockup message. Now the mailbox interrupt is disabled when request queue is full and enabled when it pop a elememt form the request queue. Signed-off-by: Fernando Guzman Lugo <x0095840@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 986002b089fd..c3402165488d 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -32,6 +32,7 @@ static struct workqueue_struct *mboxd; static struct omap_mbox *mboxes; static DEFINE_RWLOCK(mboxes_lock); +static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); @@ -141,6 +142,10 @@ static void mbox_rx_work(struct work_struct *work) while (1) { spin_lock_irqsave(q->queue_lock, flags); rq = blk_fetch_request(q); + if (rq_full) { + omap_mbox_enable_irq(mbox, IRQ_RX); + rq_full = false; + } spin_unlock_irqrestore(q->queue_lock, flags); if (!rq) break; @@ -178,8 +183,11 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) while (!mbox_fifo_empty(mbox)) { rq = blk_get_request(q, WRITE, GFP_ATOMIC); - if (unlikely(!rq)) + if (unlikely(!rq)) { + omap_mbox_disable_irq(mbox, IRQ_RX); + rq_full = true; goto nomem; + } msg = mbox_fifo_read(mbox); -- cgit v1.2.2 From 10d1a0028dc4549bd8e887641cc283f5f184f819 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen <ohad@wizery.com> Date: Wed, 5 May 2010 15:33:06 +0000 Subject: omap: mailbox: convert rwlocks to spinlock rwlocks are slower and have potential starvation issues therefore spinlocks are generally preferred. see also: http://lwn.net/Articles/364583/ Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Kanigeri Hari <h-kanigeri2@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index c3402165488d..fafe47bf2f55 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -31,7 +31,7 @@ static struct workqueue_struct *mboxd; static struct omap_mbox *mboxes; -static DEFINE_RWLOCK(mboxes_lock); +static DEFINE_SPINLOCK(mboxes_lock); static bool rq_full; static int mbox_configured; @@ -341,14 +341,14 @@ struct omap_mbox *omap_mbox_get(const char *name) struct omap_mbox *mbox; int ret; - read_lock(&mboxes_lock); + spin_lock(&mboxes_lock); mbox = *(find_mboxes(name)); if (mbox == NULL) { - read_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); return ERR_PTR(-ENOENT); } - read_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); ret = omap_mbox_startup(mbox); if (ret) @@ -374,15 +374,15 @@ int omap_mbox_register(struct device *parent, struct omap_mbox *mbox) if (mbox->next) return -EBUSY; - write_lock(&mboxes_lock); + spin_lock(&mboxes_lock); tmp = find_mboxes(mbox->name); if (*tmp) { ret = -EBUSY; - write_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); goto err_find; } *tmp = mbox; - write_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); return 0; @@ -395,18 +395,18 @@ int omap_mbox_unregister(struct omap_mbox *mbox) { struct omap_mbox **tmp; - write_lock(&mboxes_lock); + spin_lock(&mboxes_lock); tmp = &mboxes; while (*tmp) { if (mbox == *tmp) { *tmp = mbox->next; mbox->next = NULL; - write_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); return 0; } tmp = &(*tmp)->next; } - write_unlock(&mboxes_lock); + spin_unlock(&mboxes_lock); return -EINVAL; } -- cgit v1.2.2 From f375325a040d03e2c620394ebc8bcaf0bdba01da Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen <ohad@wizery.com> Date: Wed, 5 May 2010 15:33:07 +0000 Subject: omap: mailbox cleanup: split MODULE_AUTHOR line use multiple MODULE_AUTHOR lines for multiple authors Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index fafe47bf2f55..66c6e87fa3ec 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -430,4 +430,5 @@ module_exit(omap_mbox_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("omap mailbox: interrupt driven messaging"); -MODULE_AUTHOR("Toshihiro Kobayashi and Hiroshi DOYU"); +MODULE_AUTHOR("Toshihiro Kobayashi"); +MODULE_AUTHOR("Hiroshi DOYU"); -- cgit v1.2.2 From 01072d8f4b9911047ef435a807cfd7223c94d94d Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen <ohad@wizery.com> Date: Wed, 5 May 2010 15:33:08 +0000 Subject: omap: mailbox: remove (un)likely macros from cold paths Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 66c6e87fa3ec..81076b54d37b 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -258,12 +258,12 @@ static int omap_mbox_startup(struct omap_mbox *mbox) int ret = 0; struct omap_mbox_queue *mq; - if (likely(mbox->ops->startup)) { + if (mbox->ops->startup) { mutex_lock(&mbox_configured_lock); if (!mbox_configured) ret = mbox->ops->startup(mbox); - if (unlikely(ret)) { + if (ret) { mutex_unlock(&mbox_configured_lock); return ret; } @@ -273,7 +273,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox) ret = request_irq(mbox->irq, mbox_interrupt, IRQF_SHARED, mbox->name, mbox); - if (unlikely(ret)) { + if (ret) { printk(KERN_ERR "failed to register mailbox interrupt:%d\n", ret); goto fail_request_irq; @@ -300,7 +300,7 @@ static int omap_mbox_startup(struct omap_mbox *mbox) fail_alloc_txq: free_irq(mbox->irq, mbox); fail_request_irq: - if (unlikely(mbox->ops->shutdown)) + if (mbox->ops->shutdown) mbox->ops->shutdown(mbox); return ret; @@ -314,7 +314,7 @@ static void omap_mbox_fini(struct omap_mbox *mbox) mbox_queue_free(mbox->txq); mbox_queue_free(mbox->rxq); - if (unlikely(mbox->ops->shutdown)) { + if (mbox->ops->shutdown) { mutex_lock(&mbox_configured_lock); if (mbox_configured > 0) mbox_configured--; -- cgit v1.2.2 From b5bebe410204cf84337b54c372cceda2d6b27de6 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen <ohad@wizery.com> Date: Wed, 5 May 2010 15:33:09 +0000 Subject: omap: mailbox: convert block api to kfifo The underlying buffering implementation of mailbox is converted from block API to kfifo due to the simplicity and speed of kfifo. The default size of the kfifo buffer is set to 256 bytes. This value is configurable at compile time (via CONFIG_OMAP_MBOX_KFIFO_SIZE), and can be changed at runtime (via the mbox_kfifo_size module parameter). Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/Kconfig | 9 +++ arch/arm/plat-omap/include/plat/mailbox.h | 4 +- arch/arm/plat-omap/mailbox.c | 119 +++++++++++++----------------- 3 files changed, 64 insertions(+), 68 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 78b49a626d06..111d39a47ad1 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -106,6 +106,15 @@ config OMAP_MBOX_FWK Say Y here if you want to use OMAP Mailbox framework support for DSP, IVA1.0 and IVA2 in OMAP1/2/3. +config OMAP_MBOX_KFIFO_SIZE + int "Mailbox kfifo default buffer size (bytes)" + depends on OMAP_MBOX_FWK + default 256 + help + Specify the default size of mailbox's kfifo buffers (bytes). + This can also be changed at runtime (via the mbox_kfifo_size + module parameter). + config OMAP_IOMMU tristate diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 729166b76a7c..0c3c4a5f4b42 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -5,8 +5,8 @@ #include <linux/wait.h> #include <linux/workqueue.h> -#include <linux/blkdev.h> #include <linux/interrupt.h> +#include <linux/kfifo.h> typedef u32 mbox_msg_t; struct omap_mbox; @@ -42,7 +42,7 @@ struct omap_mbox_ops { struct omap_mbox_queue { spinlock_t lock; - struct request_queue *queue; + struct kfifo fifo; struct work_struct work; struct tasklet_struct tasklet; int (*callback)(void *); diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 81076b54d37b..ec0e1596b4f3 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -21,11 +21,14 @@ * */ +#include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> #include <linux/device.h> #include <linux/delay.h> #include <linux/slab.h> +#include <linux/kfifo.h> +#include <linux/err.h> #include <plat/mailbox.h> @@ -37,6 +40,10 @@ static bool rq_full; static int mbox_configured; static DEFINE_MUTEX(mbox_configured_lock); +static unsigned int mbox_kfifo_size = CONFIG_OMAP_MBOX_KFIFO_SIZE; +module_param(mbox_kfifo_size, uint, S_IRUGO); +MODULE_PARM_DESC(mbox_kfifo_size, "Size of omap's mailbox kfifo (bytes)"); + /* Mailbox FIFO handle functions */ static inline mbox_msg_t mbox_fifo_read(struct omap_mbox *mbox) { @@ -69,7 +76,7 @@ static inline int is_mbox_irq(struct omap_mbox *mbox, omap_mbox_irq_t irq) /* * message sender */ -static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) +static int __mbox_poll_for_space(struct omap_mbox *mbox) { int ret = 0, i = 1000; @@ -80,49 +87,50 @@ static int __mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) return -1; udelay(1); } - mbox_fifo_write(mbox, msg); return ret; } - int omap_mbox_msg_send(struct omap_mbox *mbox, mbox_msg_t msg) { + struct omap_mbox_queue *mq = mbox->txq; + int ret = 0, len; - struct request *rq; - struct request_queue *q = mbox->txq->queue; + spin_lock(&mq->lock); - rq = blk_get_request(q, WRITE, GFP_ATOMIC); - if (unlikely(!rq)) - return -ENOMEM; + if (kfifo_avail(&mq->fifo) < sizeof(msg)) { + ret = -ENOMEM; + goto out; + } + + len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); + WARN_ON(len != sizeof(msg)); - blk_insert_request(q, rq, 0, (void *) msg); tasklet_schedule(&mbox->txq->tasklet); - return 0; +out: + spin_unlock(&mq->lock); + return ret; } EXPORT_SYMBOL(omap_mbox_msg_send); static void mbox_tx_tasklet(unsigned long tx_data) { - int ret; - struct request *rq; struct omap_mbox *mbox = (struct omap_mbox *)tx_data; - struct request_queue *q = mbox->txq->queue; - - while (1) { - - rq = blk_fetch_request(q); - - if (!rq) - break; + struct omap_mbox_queue *mq = mbox->txq; + mbox_msg_t msg; + int ret; - ret = __mbox_msg_send(mbox, (mbox_msg_t)rq->special); - if (ret) { + while (kfifo_len(&mq->fifo)) { + if (__mbox_poll_for_space(mbox)) { omap_mbox_enable_irq(mbox, IRQ_TX); - blk_requeue_request(q, rq); - return; + break; } - blk_end_request_all(rq, 0); + + ret = kfifo_out(&mq->fifo, (unsigned char *)&msg, + sizeof(msg)); + WARN_ON(ret != sizeof(msg)); + + mbox_fifo_write(mbox, msg); } } @@ -133,41 +141,21 @@ static void mbox_rx_work(struct work_struct *work) { struct omap_mbox_queue *mq = container_of(work, struct omap_mbox_queue, work); - struct omap_mbox *mbox = mq->queue->queuedata; - struct request_queue *q = mbox->rxq->queue; - struct request *rq; mbox_msg_t msg; - unsigned long flags; - - while (1) { - spin_lock_irqsave(q->queue_lock, flags); - rq = blk_fetch_request(q); - if (rq_full) { - omap_mbox_enable_irq(mbox, IRQ_RX); - rq_full = false; - } - spin_unlock_irqrestore(q->queue_lock, flags); - if (!rq) - break; + int len; + + while (kfifo_len(&mq->fifo) >= sizeof(msg)) { + len = kfifo_out(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); + WARN_ON(len != sizeof(msg)); - msg = (mbox_msg_t)rq->special; - blk_end_request_all(rq, 0); - if (mbox->rxq->callback) - mbox->rxq->callback((void *)msg); + if (mq->callback) + mq->callback((void *)msg); } } /* * Mailbox interrupt handler */ -static void mbox_txq_fn(struct request_queue *q) -{ -} - -static void mbox_rxq_fn(struct request_queue *q) -{ -} - static void __mbox_tx_interrupt(struct omap_mbox *mbox) { omap_mbox_disable_irq(mbox, IRQ_TX); @@ -177,13 +165,12 @@ static void __mbox_tx_interrupt(struct omap_mbox *mbox) static void __mbox_rx_interrupt(struct omap_mbox *mbox) { - struct request *rq; + struct omap_mbox_queue *mq = mbox->rxq; mbox_msg_t msg; - struct request_queue *q = mbox->rxq->queue; + int len; while (!mbox_fifo_empty(mbox)) { - rq = blk_get_request(q, WRITE, GFP_ATOMIC); - if (unlikely(!rq)) { + if (unlikely(kfifo_avail(&mq->fifo) < sizeof(msg))) { omap_mbox_disable_irq(mbox, IRQ_RX); rq_full = true; goto nomem; @@ -191,8 +178,9 @@ static void __mbox_rx_interrupt(struct omap_mbox *mbox) msg = mbox_fifo_read(mbox); + len = kfifo_in(&mq->fifo, (unsigned char *)&msg, sizeof(msg)); + WARN_ON(len != sizeof(msg)); - blk_insert_request(q, rq, 0, (void *)msg); if (mbox->ops->type == OMAP_MBOX_TYPE1) break; } @@ -217,11 +205,9 @@ static irqreturn_t mbox_interrupt(int irq, void *p) } static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, - request_fn_proc *proc, void (*work) (struct work_struct *), void (*tasklet)(unsigned long)) { - struct request_queue *q; struct omap_mbox_queue *mq; mq = kzalloc(sizeof(struct omap_mbox_queue), GFP_KERNEL); @@ -230,11 +216,8 @@ static struct omap_mbox_queue *mbox_queue_alloc(struct omap_mbox *mbox, spin_lock_init(&mq->lock); - q = blk_init_queue(proc, &mq->lock); - if (!q) + if (kfifo_alloc(&mq->fifo, mbox_kfifo_size, GFP_KERNEL)) goto error; - q->queuedata = mbox; - mq->queue = q; if (work) INIT_WORK(&mq->work, work); @@ -249,7 +232,7 @@ error: static void mbox_queue_free(struct omap_mbox_queue *q) { - blk_cleanup_queue(q->queue); + kfifo_free(&q->fifo); kfree(q); } @@ -279,14 +262,14 @@ static int omap_mbox_startup(struct omap_mbox *mbox) goto fail_request_irq; } - mq = mbox_queue_alloc(mbox, mbox_txq_fn, NULL, mbox_tx_tasklet); + mq = mbox_queue_alloc(mbox, NULL, mbox_tx_tasklet); if (!mq) { ret = -ENOMEM; goto fail_alloc_txq; } mbox->txq = mq; - mq = mbox_queue_alloc(mbox, mbox_rxq_fn, mbox_rx_work, NULL); + mq = mbox_queue_alloc(mbox, mbox_rx_work, NULL); if (!mq) { ret = -ENOMEM; goto fail_alloc_rxq; @@ -418,6 +401,10 @@ static int __init omap_mbox_init(void) if (!mboxd) return -ENOMEM; + /* kfifo size sanity check: alignment and minimal size */ + mbox_kfifo_size = ALIGN(mbox_kfifo_size, sizeof(mbox_msg_t)); + mbox_kfifo_size = max_t(unsigned int, mbox_kfifo_size, sizeof(mbox_msg_t)); + return 0; } module_init(omap_mbox_init); -- cgit v1.2.2 From 6b23398591a51943dbf08f30cfc2475a895cb1b4 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> Date: Tue, 18 May 2010 16:15:32 +0300 Subject: omap mailbox: Set a device in logical mbox instance for traceability With this patch, you'll get the following sysfs directories. This structure implies that a single platform device, "omap2-mailbox" holds multiple logical mbox instances. This could be the base to add sysfs files for each logical mboxes. Then userland application can access a mbox through sysfs entries if necessary(ex: setting kfifo size dynamically) ~# tree -d -L 2 /sys/devices/platform/omap2-mailbox/ /sys/devices/platform/omap2-mailbox/ |-- driver -> ../../../bus/platform/drivers/omap2-mailbox |-- mbox | |-- dsp <- they are each instances of logical mailbox. | |-- ducati | |-- iva2 | |-- mbox01 | |-- mbox02 | |-- mbox03 | |-- ..... | `-- tesla |-- power `-- subsystem -> ../../../bus/platform This was wrongly dropped by: commit c7c158e57bce6220644f2bcd65d82e1468aa40ec Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/mailbox.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index ec0e1596b4f3..87e0cde8d0db 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -347,6 +347,8 @@ void omap_mbox_put(struct omap_mbox *mbox) } EXPORT_SYMBOL(omap_mbox_put); +static struct class omap_mbox_class = { .name = "mbox", }; + int omap_mbox_register(struct device *parent, struct omap_mbox *mbox) { int ret = 0; @@ -357,6 +359,11 @@ int omap_mbox_register(struct device *parent, struct omap_mbox *mbox) if (mbox->next) return -EBUSY; + mbox->dev = device_create(&omap_mbox_class, + parent, 0, mbox, "%s", mbox->name); + if (IS_ERR(mbox->dev)) + return PTR_ERR(mbox->dev); + spin_lock(&mboxes_lock); tmp = find_mboxes(mbox->name); if (*tmp) { @@ -385,6 +392,7 @@ int omap_mbox_unregister(struct omap_mbox *mbox) *tmp = mbox->next; mbox->next = NULL; spin_unlock(&mboxes_lock); + device_unregister(mbox->dev); return 0; } tmp = &(*tmp)->next; @@ -397,6 +405,12 @@ EXPORT_SYMBOL(omap_mbox_unregister); static int __init omap_mbox_init(void) { + int err; + + err = class_register(&omap_mbox_class); + if (err) + return err; + mboxd = create_workqueue("mboxd"); if (!mboxd) return -ENOMEM; @@ -407,11 +421,12 @@ static int __init omap_mbox_init(void) return 0; } -module_init(omap_mbox_init); +subsys_initcall(omap_mbox_init); static void __exit omap_mbox_exit(void) { destroy_workqueue(mboxd); + class_unregister(&omap_mbox_class); } module_exit(omap_mbox_exit); -- cgit v1.2.2 From fc9960b2823d581ab8a1541fc8b9f2748ee3e5f2 Mon Sep 17 00:00:00 2001 From: Felipe Contreras <felipe.contreras@gmail.com> Date: Fri, 11 Jun 2010 15:51:43 +0000 Subject: omap: mailbox: remove unecessary fields Nobody is using them. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/include/plat/mailbox.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index 0c3c4a5f4b42..aad8bf80c224 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -52,19 +52,11 @@ struct omap_mbox_queue { struct omap_mbox { char *name; unsigned int irq; - struct omap_mbox_queue *txq, *rxq; - struct omap_mbox_ops *ops; - - mbox_msg_t seq_snd, seq_rcv; - struct device *dev; - struct omap_mbox *next; void *priv; - - void (*err_notify)(void); }; int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg); -- cgit v1.2.2 From 9c80c8cd740f802eed27ed1c1334262b205bb8f5 Mon Sep 17 00:00:00 2001 From: Felipe Contreras <felipe.contreras@gmail.com> Date: Fri, 11 Jun 2010 15:51:46 +0000 Subject: omap: mailbox: simplify omap_mbox_register() No need to dynamically register mailboxes one by one. Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/include/plat/mailbox.h | 5 +- arch/arm/plat-omap/mailbox.c | 95 ++++++++++++------------------- 2 files changed, 37 insertions(+), 63 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index aad8bf80c224..c44fde30c7c1 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -55,7 +55,6 @@ struct omap_mbox { struct omap_mbox_queue *txq, *rxq; struct omap_mbox_ops *ops; struct device *dev; - struct omap_mbox *next; void *priv; }; @@ -65,8 +64,8 @@ void omap_mbox_init_seq(struct omap_mbox *); struct omap_mbox *omap_mbox_get(const char *); void omap_mbox_put(struct omap_mbox *); -int omap_mbox_register(struct device *parent, struct omap_mbox *); -int omap_mbox_unregister(struct omap_mbox *); +int omap_mbox_register(struct device *parent, struct omap_mbox **); +int omap_mbox_unregister(void); static inline void omap_mbox_save_ctx(struct omap_mbox *mbox) { diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index 87e0cde8d0db..fe0882130852 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -33,8 +33,7 @@ #include <plat/mailbox.h> static struct workqueue_struct *mboxd; -static struct omap_mbox *mboxes; -static DEFINE_SPINLOCK(mboxes_lock); +static struct omap_mbox **mboxes; static bool rq_full; static int mbox_configured; @@ -307,31 +306,20 @@ static void omap_mbox_fini(struct omap_mbox *mbox) } } -static struct omap_mbox **find_mboxes(const char *name) -{ - struct omap_mbox **p; - - for (p = &mboxes; *p; p = &(*p)->next) { - if (strcmp((*p)->name, name) == 0) - break; - } - - return p; -} - struct omap_mbox *omap_mbox_get(const char *name) { struct omap_mbox *mbox; int ret; - spin_lock(&mboxes_lock); - mbox = *(find_mboxes(name)); - if (mbox == NULL) { - spin_unlock(&mboxes_lock); - return ERR_PTR(-ENOENT); - } + if (!mboxes) + return ERR_PTR(-EINVAL); - spin_unlock(&mboxes_lock); + for (mbox = *mboxes; mbox; mbox++) + if (!strcmp(mbox->name, name)) + break; + + if (!mbox) + return ERR_PTR(-ENOENT); ret = omap_mbox_startup(mbox); if (ret) @@ -349,57 +337,44 @@ EXPORT_SYMBOL(omap_mbox_put); static struct class omap_mbox_class = { .name = "mbox", }; -int omap_mbox_register(struct device *parent, struct omap_mbox *mbox) +int omap_mbox_register(struct device *parent, struct omap_mbox **list) { - int ret = 0; - struct omap_mbox **tmp; + int ret; + int i; - if (!mbox) + mboxes = list; + if (!mboxes) return -EINVAL; - if (mbox->next) - return -EBUSY; - - mbox->dev = device_create(&omap_mbox_class, - parent, 0, mbox, "%s", mbox->name); - if (IS_ERR(mbox->dev)) - return PTR_ERR(mbox->dev); - - spin_lock(&mboxes_lock); - tmp = find_mboxes(mbox->name); - if (*tmp) { - ret = -EBUSY; - spin_unlock(&mboxes_lock); - goto err_find; - } - *tmp = mbox; - spin_unlock(&mboxes_lock); + for (i = 0; mboxes[i]; i++) { + struct omap_mbox *mbox = mboxes[i]; + mbox->dev = device_create(&omap_mbox_class, + parent, 0, mbox, "%s", mbox->name); + if (IS_ERR(mbox->dev)) { + ret = PTR_ERR(mbox->dev); + goto err_out; + } + } return 0; -err_find: +err_out: + while (i--) + device_unregister(mboxes[i]->dev); return ret; } EXPORT_SYMBOL(omap_mbox_register); -int omap_mbox_unregister(struct omap_mbox *mbox) +int omap_mbox_unregister(void) { - struct omap_mbox **tmp; - - spin_lock(&mboxes_lock); - tmp = &mboxes; - while (*tmp) { - if (mbox == *tmp) { - *tmp = mbox->next; - mbox->next = NULL; - spin_unlock(&mboxes_lock); - device_unregister(mbox->dev); - return 0; - } - tmp = &(*tmp)->next; - } - spin_unlock(&mboxes_lock); + int i; - return -EINVAL; + if (!mboxes) + return -EINVAL; + + for (i = 0; mboxes[i]; i++) + device_unregister(mboxes[i]->dev); + mboxes = NULL; + return 0; } EXPORT_SYMBOL(omap_mbox_unregister); -- cgit v1.2.2 From b3e69146f43fa351aa3cdffe2e76ec42174da612 Mon Sep 17 00:00:00 2001 From: Felipe Contreras <felipe.contreras@gmail.com> Date: Fri, 11 Jun 2010 15:51:49 +0000 Subject: omap: mailbox: reorganize headers Remove kernel.h and module.h since they are not used correctly anyway. Also, remove device.h since it comes along with platform_device.h (always will I guess). Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> --- arch/arm/plat-omap/include/plat/mailbox.h | 3 ++- arch/arm/plat-omap/mailbox.c | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h index c44fde30c7c1..997656552109 100644 --- a/arch/arm/plat-omap/include/plat/mailbox.h +++ b/arch/arm/plat-omap/include/plat/mailbox.h @@ -3,9 +3,10 @@ #ifndef MAILBOX_H #define MAILBOX_H -#include <linux/wait.h> +#include <linux/spinlock.h> #include <linux/workqueue.h> #include <linux/interrupt.h> +#include <linux/device.h> #include <linux/kfifo.h> typedef u32 mbox_msg_t; diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c index fe0882130852..d2fafb892f7f 100644 --- a/arch/arm/plat-omap/mailbox.c +++ b/arch/arm/plat-omap/mailbox.c @@ -21,10 +21,9 @@ * */ -#include <linux/kernel.h> -#include <linux/module.h> #include <linux/interrupt.h> -#include <linux/device.h> +#include <linux/spinlock.h> +#include <linux/mutex.h> #include <linux/delay.h> #include <linux/slab.h> #include <linux/kfifo.h> -- cgit v1.2.2 From 26a8c2507a224d39003665cd6e7678520c733c04 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen <tomi.valkeinen@nokia.com> Date: Wed, 9 Jun 2010 15:31:34 +0300 Subject: OMAP: DSS2: change manual update scaling setup Currently the update area on manual update displays is automatically enlargened to fully cover scaled overlays. This patch makes that optional, allowing the panel driver to choose if it's used or not. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com> --- arch/arm/plat-omap/include/plat/display.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h index b8de70479313..8bd15bdb4132 100644 --- a/arch/arm/plat-omap/include/plat/display.h +++ b/arch/arm/plat-omap/include/plat/display.h @@ -560,7 +560,8 @@ void omapdss_dsi_vc_enable_hs(int channel, bool enable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable); int omap_dsi_prepare_update(struct omap_dss_device *dssdev, - u16 *x, u16 *y, u16 *w, u16 *h); + u16 *x, u16 *y, u16 *w, u16 *h, + bool enlarge_update_area); int omap_dsi_update(struct omap_dss_device *dssdev, int channel, u16 x, u16 y, u16 w, u16 h, -- cgit v1.2.2 From 4816858cce279b5e8d1eab0b4832d89d8f2ca58c Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas <notasas@gmail.com> Date: Tue, 10 Aug 2010 18:01:52 -0700 Subject: omap_hsmmc: add init_card pass-through callback This will allow us to set up special cards in machine drivers just after they are detected by MMC core. Signed-off-by: Grazvydas Ignotas <notasas@gmail.com> Cc: Adrian Hunter <adrian.hunter@nokia.com> Cc: Tony Lindgren <tony@atomide.com> Cc: Bob Copeland <me@bobcopeland.com> Cc: Kalle Valo <kvalo@adurom.com> Cc: Madhusudhan Chikkature <madhu.cr@ti.com> Cc: Kishore Kadiyala <kishore.kadiyala@ti.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: <linux-mmc@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> --- arch/arm/plat-omap/include/plat/mmc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index c835f1e994c6..9b89ec601ee2 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -122,6 +122,8 @@ struct omap_mmc_platform_data { /* Call back after enabling / disabling regulators */ void (*after_set_reg)(struct device *dev, int slot, int power_on, int vdd); + /* if we have special card, init it using this callback */ + void (*init_card)(struct mmc_card *card); /* return MMC cover switch state, can be NULL if not supported. * -- cgit v1.2.2 From a4192d32ae6788dc607e96fa85f9c9c8274e2212 Mon Sep 17 00:00:00 2001 From: Tony Lindgren <tony@atomide.com> Date: Mon, 16 Aug 2010 09:21:20 +0300 Subject: omap: Fix sev instruction usage for multi-omap Otherwise we get the following error with omap3_defconfig and CONFIG_SMP: Error: selected processor does not support `sev' Signed-off-by: Tony Lindgren <tony@atomide.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> --- arch/arm/plat-omap/include/plat/smp.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'arch/arm/plat-omap') diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 6a3ff65c0303..5177a9c5a25a 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h @@ -19,13 +19,6 @@ #include <asm/hardware/gic.h> -/* - * set_event() is used to wake up secondary core from wfe using sev. ROM - * code puts the second core into wfe(standby). - * - */ -#define set_event() __asm__ __volatile__ ("sev" : : : "memory") - /* Needed for secondary core boot */ extern void omap_secondary_startup(void); extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask); -- cgit v1.2.2