diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 12:10:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-01 12:10:16 -0400 |
| commit | e10b87d2b5b4574cdf3a5a19b22ca88b91ba7151 (patch) | |
| tree | 21c0714515e1fb1722b918b5e43ecbd7349e2202 /drivers | |
| parent | 3da3f872aa175f59e20766ed30aaea67fd4fa7d1 (diff) | |
| parent | 536628d0983f1c6a7ccece28ded635661aa30319 (diff) | |
Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-3.x
* 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-3.x: (39 commits)
SH: static should be at beginning of declaration
sh: move CLKDEV_xxx_ID macro to sh_clk.h
sh: clock-shx3: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7786: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7785: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7757: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7366: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7343: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7722: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7724: add CLKDEV_ICK_ID for cleanup
sh: clock-sh7366: modify I2C clock settings
sh: clock-sh7343: modify I2C clock settings
sh: clock-sh7723: modify I2C clock settings
sh: clock-sh7722: modify I2C clock settings
sh: clock-sh7724: modify I2C clock settings
serial: sh-sci: Fix up pretty name printing for port IRQs.
serial: sh-sci: Kill off per-port enable/disable callbacks.
serial: sh-sci: Add missing module description/author bits.
serial: sh-sci: Regtype probing doesn't need to be fatal.
sh: Tidy up pre-clkdev clk_get() error handling.
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/dma/shdma.c | 88 | ||||
| -rw-r--r-- | drivers/dma/shdma.h | 4 | ||||
| -rw-r--r-- | drivers/sh/clk/core.c | 29 | ||||
| -rw-r--r-- | drivers/tty/serial/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/tty/serial/sh-sci.c | 757 | ||||
| -rw-r--r-- | drivers/tty/serial/sh-sci.h | 434 |
6 files changed, 559 insertions, 755 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 028330044201..7f49235d14b9 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
| @@ -70,12 +70,36 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) | |||
| 70 | 70 | ||
| 71 | static u16 dmaor_read(struct sh_dmae_device *shdev) | 71 | static u16 dmaor_read(struct sh_dmae_device *shdev) |
| 72 | { | 72 | { |
| 73 | return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32)); | 73 | u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32); |
| 74 | |||
| 75 | if (shdev->pdata->dmaor_is_32bit) | ||
| 76 | return __raw_readl(addr); | ||
| 77 | else | ||
| 78 | return __raw_readw(addr); | ||
| 74 | } | 79 | } |
| 75 | 80 | ||
| 76 | static void dmaor_write(struct sh_dmae_device *shdev, u16 data) | 81 | static void dmaor_write(struct sh_dmae_device *shdev, u16 data) |
| 77 | { | 82 | { |
| 78 | __raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32)); | 83 | u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32); |
| 84 | |||
| 85 | if (shdev->pdata->dmaor_is_32bit) | ||
| 86 | __raw_writel(data, addr); | ||
| 87 | else | ||
| 88 | __raw_writew(data, addr); | ||
| 89 | } | ||
| 90 | |||
| 91 | static void chcr_write(struct sh_dmae_chan *sh_dc, u32 data) | ||
| 92 | { | ||
| 93 | struct sh_dmae_device *shdev = to_sh_dev(sh_dc); | ||
| 94 | |||
| 95 | __raw_writel(data, sh_dc->base + shdev->chcr_offset / sizeof(u32)); | ||
| 96 | } | ||
| 97 | |||
| 98 | static u32 chcr_read(struct sh_dmae_chan *sh_dc) | ||
| 99 | { | ||
| 100 | struct sh_dmae_device *shdev = to_sh_dev(sh_dc); | ||
| 101 | |||
| 102 | return __raw_readl(sh_dc->base + shdev->chcr_offset / sizeof(u32)); | ||
| 79 | } | 103 | } |
| 80 | 104 | ||
| 81 | /* | 105 | /* |
| @@ -120,7 +144,7 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev) | |||
| 120 | 144 | ||
| 121 | static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) | 145 | static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) |
| 122 | { | 146 | { |
| 123 | u32 chcr = sh_dmae_readl(sh_chan, CHCR); | 147 | u32 chcr = chcr_read(sh_chan); |
| 124 | 148 | ||
| 125 | if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE) | 149 | if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE) |
| 126 | return true; /* working */ | 150 | return true; /* working */ |
| @@ -130,8 +154,7 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) | |||
| 130 | 154 | ||
| 131 | static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) | 155 | static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) |
| 132 | { | 156 | { |
| 133 | struct sh_dmae_device *shdev = container_of(sh_chan->common.device, | 157 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 134 | struct sh_dmae_device, common); | ||
| 135 | struct sh_dmae_pdata *pdata = shdev->pdata; | 158 | struct sh_dmae_pdata *pdata = shdev->pdata; |
| 136 | int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) | | 159 | int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) | |
| 137 | ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift); | 160 | ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift); |
| @@ -144,8 +167,7 @@ static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) | |||
| 144 | 167 | ||
| 145 | static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size) | 168 | static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size) |
| 146 | { | 169 | { |
| 147 | struct sh_dmae_device *shdev = container_of(sh_chan->common.device, | 170 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 148 | struct sh_dmae_device, common); | ||
| 149 | struct sh_dmae_pdata *pdata = shdev->pdata; | 171 | struct sh_dmae_pdata *pdata = shdev->pdata; |
| 150 | int i; | 172 | int i; |
| 151 | 173 | ||
| @@ -169,18 +191,23 @@ static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) | |||
| 169 | 191 | ||
| 170 | static void dmae_start(struct sh_dmae_chan *sh_chan) | 192 | static void dmae_start(struct sh_dmae_chan *sh_chan) |
| 171 | { | 193 | { |
| 172 | u32 chcr = sh_dmae_readl(sh_chan, CHCR); | 194 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 195 | u32 chcr = chcr_read(sh_chan); | ||
| 196 | |||
| 197 | if (shdev->pdata->needs_tend_set) | ||
| 198 | sh_dmae_writel(sh_chan, 0xFFFFFFFF, TEND); | ||
| 173 | 199 | ||
| 174 | chcr |= CHCR_DE | CHCR_IE; | 200 | chcr |= CHCR_DE | shdev->chcr_ie_bit; |
| 175 | sh_dmae_writel(sh_chan, chcr & ~CHCR_TE, CHCR); | 201 | chcr_write(sh_chan, chcr & ~CHCR_TE); |
| 176 | } | 202 | } |
| 177 | 203 | ||
| 178 | static void dmae_halt(struct sh_dmae_chan *sh_chan) | 204 | static void dmae_halt(struct sh_dmae_chan *sh_chan) |
| 179 | { | 205 | { |
| 180 | u32 chcr = sh_dmae_readl(sh_chan, CHCR); | 206 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 207 | u32 chcr = chcr_read(sh_chan); | ||
| 181 | 208 | ||
| 182 | chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); | 209 | chcr &= ~(CHCR_DE | CHCR_TE | shdev->chcr_ie_bit); |
| 183 | sh_dmae_writel(sh_chan, chcr, CHCR); | 210 | chcr_write(sh_chan, chcr); |
| 184 | } | 211 | } |
| 185 | 212 | ||
| 186 | static void dmae_init(struct sh_dmae_chan *sh_chan) | 213 | static void dmae_init(struct sh_dmae_chan *sh_chan) |
| @@ -192,7 +219,7 @@ static void dmae_init(struct sh_dmae_chan *sh_chan) | |||
| 192 | u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan, | 219 | u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan, |
| 193 | LOG2_DEFAULT_XFER_SIZE); | 220 | LOG2_DEFAULT_XFER_SIZE); |
| 194 | sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr); | 221 | sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr); |
| 195 | sh_dmae_writel(sh_chan, chcr, CHCR); | 222 | chcr_write(sh_chan, chcr); |
| 196 | } | 223 | } |
| 197 | 224 | ||
| 198 | static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) | 225 | static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) |
| @@ -202,23 +229,25 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) | |||
| 202 | return -EBUSY; | 229 | return -EBUSY; |
| 203 | 230 | ||
| 204 | sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val); | 231 | sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val); |
| 205 | sh_dmae_writel(sh_chan, val, CHCR); | 232 | chcr_write(sh_chan, val); |
| 206 | 233 | ||
| 207 | return 0; | 234 | return 0; |
| 208 | } | 235 | } |
| 209 | 236 | ||
| 210 | static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) | 237 | static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) |
| 211 | { | 238 | { |
| 212 | struct sh_dmae_device *shdev = container_of(sh_chan->common.device, | 239 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 213 | struct sh_dmae_device, common); | ||
| 214 | struct sh_dmae_pdata *pdata = shdev->pdata; | 240 | struct sh_dmae_pdata *pdata = shdev->pdata; |
| 215 | const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; | 241 | const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id]; |
| 216 | u16 __iomem *addr = shdev->dmars; | 242 | u16 __iomem *addr = shdev->dmars; |
| 217 | int shift = chan_pdata->dmars_bit; | 243 | unsigned int shift = chan_pdata->dmars_bit; |
| 218 | 244 | ||
| 219 | if (dmae_is_busy(sh_chan)) | 245 | if (dmae_is_busy(sh_chan)) |
| 220 | return -EBUSY; | 246 | return -EBUSY; |
| 221 | 247 | ||
| 248 | if (pdata->no_dmars) | ||
| 249 | return 0; | ||
| 250 | |||
| 222 | /* in the case of a missing DMARS resource use first memory window */ | 251 | /* in the case of a missing DMARS resource use first memory window */ |
| 223 | if (!addr) | 252 | if (!addr) |
| 224 | addr = (u16 __iomem *)shdev->chan_reg; | 253 | addr = (u16 __iomem *)shdev->chan_reg; |
| @@ -296,9 +325,7 @@ static struct sh_desc *sh_dmae_get_desc(struct sh_dmae_chan *sh_chan) | |||
| 296 | static const struct sh_dmae_slave_config *sh_dmae_find_slave( | 325 | static const struct sh_dmae_slave_config *sh_dmae_find_slave( |
| 297 | struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param) | 326 | struct sh_dmae_chan *sh_chan, struct sh_dmae_slave *param) |
| 298 | { | 327 | { |
| 299 | struct dma_device *dma_dev = sh_chan->common.device; | 328 | struct sh_dmae_device *shdev = to_sh_dev(sh_chan); |
| 300 | struct sh_dmae_device *shdev = container_of(dma_dev, | ||
| 301 | struct sh_dmae_device, common); | ||
| 302 | struct sh_dmae_pdata *pdata = shdev->pdata; | 329 | struct sh_dmae_pdata *pdata = shdev->pdata; |
| 303 | int i; | 330 | int i; |
| 304 | 331 | ||
| @@ -771,10 +798,8 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) | |||
| 771 | 798 | ||
| 772 | spin_lock_bh(&sh_chan->desc_lock); | 799 | spin_lock_bh(&sh_chan->desc_lock); |
| 773 | /* DMA work check */ | 800 | /* DMA work check */ |
| 774 | if (dmae_is_busy(sh_chan)) { | 801 | if (dmae_is_busy(sh_chan)) |
| 775 | spin_unlock_bh(&sh_chan->desc_lock); | 802 | goto sh_chan_xfer_ld_queue_end; |
| 776 | return; | ||
| 777 | } | ||
| 778 | 803 | ||
| 779 | /* Find the first not transferred descriptor */ | 804 | /* Find the first not transferred descriptor */ |
| 780 | list_for_each_entry(desc, &sh_chan->ld_queue, node) | 805 | list_for_each_entry(desc, &sh_chan->ld_queue, node) |
| @@ -788,6 +813,7 @@ static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan) | |||
| 788 | break; | 813 | break; |
| 789 | } | 814 | } |
| 790 | 815 | ||
| 816 | sh_chan_xfer_ld_queue_end: | ||
| 791 | spin_unlock_bh(&sh_chan->desc_lock); | 817 | spin_unlock_bh(&sh_chan->desc_lock); |
| 792 | } | 818 | } |
| 793 | 819 | ||
| @@ -846,7 +872,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data) | |||
| 846 | 872 | ||
| 847 | spin_lock(&sh_chan->desc_lock); | 873 | spin_lock(&sh_chan->desc_lock); |
| 848 | 874 | ||
| 849 | chcr = sh_dmae_readl(sh_chan, CHCR); | 875 | chcr = chcr_read(sh_chan); |
| 850 | 876 | ||
| 851 | if (chcr & CHCR_TE) { | 877 | if (chcr & CHCR_TE) { |
| 852 | /* DMA stop */ | 878 | /* DMA stop */ |
| @@ -1144,6 +1170,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
| 1144 | /* platform data */ | 1170 | /* platform data */ |
| 1145 | shdev->pdata = pdata; | 1171 | shdev->pdata = pdata; |
| 1146 | 1172 | ||
| 1173 | if (pdata->chcr_offset) | ||
| 1174 | shdev->chcr_offset = pdata->chcr_offset; | ||
| 1175 | else | ||
| 1176 | shdev->chcr_offset = CHCR; | ||
| 1177 | |||
| 1178 | if (pdata->chcr_ie_bit) | ||
| 1179 | shdev->chcr_ie_bit = pdata->chcr_ie_bit; | ||
| 1180 | else | ||
| 1181 | shdev->chcr_ie_bit = CHCR_IE; | ||
| 1182 | |||
| 1147 | platform_set_drvdata(pdev, shdev); | 1183 | platform_set_drvdata(pdev, shdev); |
| 1148 | 1184 | ||
| 1149 | pm_runtime_enable(&pdev->dev); | 1185 | pm_runtime_enable(&pdev->dev); |
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h index 5ae9fc512180..dc56576f9fdb 100644 --- a/drivers/dma/shdma.h +++ b/drivers/dma/shdma.h | |||
| @@ -47,10 +47,14 @@ struct sh_dmae_device { | |||
| 47 | struct list_head node; | 47 | struct list_head node; |
| 48 | u32 __iomem *chan_reg; | 48 | u32 __iomem *chan_reg; |
| 49 | u16 __iomem *dmars; | 49 | u16 __iomem *dmars; |
| 50 | unsigned int chcr_offset; | ||
| 51 | u32 chcr_ie_bit; | ||
| 50 | }; | 52 | }; |
| 51 | 53 | ||
| 52 | #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common) | 54 | #define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common) |
| 53 | #define to_sh_desc(lh) container_of(lh, struct sh_desc, node) | 55 | #define to_sh_desc(lh) container_of(lh, struct sh_desc, node) |
| 54 | #define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx) | 56 | #define tx_to_sh_desc(tx) container_of(tx, struct sh_desc, async_tx) |
| 57 | #define to_sh_dev(chan) container_of(chan->common.device,\ | ||
| 58 | struct sh_dmae_device, common) | ||
| 55 | 59 | ||
| 56 | #endif /* __DMA_SHDMA_H */ | 60 | #endif /* __DMA_SHDMA_H */ |
diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index d6702e57d428..dc8d022c07a1 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c | |||
| @@ -34,6 +34,9 @@ static LIST_HEAD(clock_list); | |||
| 34 | static DEFINE_SPINLOCK(clock_lock); | 34 | static DEFINE_SPINLOCK(clock_lock); |
| 35 | static DEFINE_MUTEX(clock_list_sem); | 35 | static DEFINE_MUTEX(clock_list_sem); |
| 36 | 36 | ||
| 37 | /* clock disable operations are not passed on to hardware during boot */ | ||
| 38 | static int allow_disable; | ||
| 39 | |||
| 37 | void clk_rate_table_build(struct clk *clk, | 40 | void clk_rate_table_build(struct clk *clk, |
| 38 | struct cpufreq_frequency_table *freq_table, | 41 | struct cpufreq_frequency_table *freq_table, |
| 39 | int nr_freqs, | 42 | int nr_freqs, |
| @@ -228,7 +231,7 @@ static void __clk_disable(struct clk *clk) | |||
| 228 | return; | 231 | return; |
| 229 | 232 | ||
| 230 | if (!(--clk->usecount)) { | 233 | if (!(--clk->usecount)) { |
| 231 | if (likely(clk->ops && clk->ops->disable)) | 234 | if (likely(allow_disable && clk->ops && clk->ops->disable)) |
| 232 | clk->ops->disable(clk); | 235 | clk->ops->disable(clk); |
| 233 | if (likely(clk->parent)) | 236 | if (likely(clk->parent)) |
| 234 | __clk_disable(clk->parent); | 237 | __clk_disable(clk->parent); |
| @@ -393,7 +396,7 @@ int clk_register(struct clk *clk) | |||
| 393 | { | 396 | { |
| 394 | int ret; | 397 | int ret; |
| 395 | 398 | ||
| 396 | if (clk == NULL || IS_ERR(clk)) | 399 | if (IS_ERR_OR_NULL(clk)) |
| 397 | return -EINVAL; | 400 | return -EINVAL; |
| 398 | 401 | ||
| 399 | /* | 402 | /* |
| @@ -744,3 +747,25 @@ err_out: | |||
| 744 | return err; | 747 | return err; |
| 745 | } | 748 | } |
| 746 | late_initcall(clk_debugfs_init); | 749 | late_initcall(clk_debugfs_init); |
| 750 | |||
| 751 | static int __init clk_late_init(void) | ||
| 752 | { | ||
| 753 | unsigned long flags; | ||
| 754 | struct clk *clk; | ||
| 755 | |||
| 756 | /* disable all clocks with zero use count */ | ||
| 757 | mutex_lock(&clock_list_sem); | ||
| 758 | spin_lock_irqsave(&clock_lock, flags); | ||
| 759 | |||
| 760 | list_for_each_entry(clk, &clock_list, node) | ||
| 761 | if (!clk->usecount && clk->ops && clk->ops->disable) | ||
| 762 | clk->ops->disable(clk); | ||
| 763 | |||
| 764 | /* from now on allow clock disable operations */ | ||
| 765 | allow_disable = 1; | ||
| 766 | |||
| 767 | spin_unlock_irqrestore(&clock_lock, flags); | ||
| 768 | mutex_unlock(&clock_list_sem); | ||
| 769 | return 0; | ||
| 770 | } | ||
| 771 | late_initcall(clk_late_init); | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index cb40b82daf36..4dcb37bbdf92 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
| @@ -959,7 +959,7 @@ config SERIAL_IP22_ZILOG_CONSOLE | |||
| 959 | 959 | ||
| 960 | config SERIAL_SH_SCI | 960 | config SERIAL_SH_SCI |
| 961 | tristate "SuperH SCI(F) serial port support" | 961 | tristate "SuperH SCI(F) serial port support" |
| 962 | depends on HAVE_CLK && (SUPERH || H8300 || ARCH_SHMOBILE) | 962 | depends on HAVE_CLK && (SUPERH || ARCH_SHMOBILE) |
| 963 | select SERIAL_CORE | 963 | select SERIAL_CORE |
| 964 | 964 | ||
| 965 | config SERIAL_SH_SCI_NR_UARTS | 965 | config SERIAL_SH_SCI_NR_UARTS |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index ebd8629c108d..d0a56235c50e 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
| @@ -54,10 +54,6 @@ | |||
| 54 | #include <asm/sh_bios.h> | 54 | #include <asm/sh_bios.h> |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | #ifdef CONFIG_H8300 | ||
| 58 | #include <asm/gpio.h> | ||
| 59 | #endif | ||
| 60 | |||
| 61 | #include "sh-sci.h" | 57 | #include "sh-sci.h" |
| 62 | 58 | ||
| 63 | struct sci_port { | 59 | struct sci_port { |
| @@ -66,12 +62,6 @@ struct sci_port { | |||
| 66 | /* Platform configuration */ | 62 | /* Platform configuration */ |
| 67 | struct plat_sci_port *cfg; | 63 | struct plat_sci_port *cfg; |
| 68 | 64 | ||
| 69 | /* Port enable callback */ | ||
| 70 | void (*enable)(struct uart_port *port); | ||
| 71 | |||
| 72 | /* Port disable callback */ | ||
| 73 | void (*disable)(struct uart_port *port); | ||
| 74 | |||
| 75 | /* Break timer */ | 65 | /* Break timer */ |
| 76 | struct timer_list break_timer; | 66 | struct timer_list break_timer; |
| 77 | int break_flag; | 67 | int break_flag; |
| @@ -81,6 +71,8 @@ struct sci_port { | |||
| 81 | /* Function clock */ | 71 | /* Function clock */ |
| 82 | struct clk *fclk; | 72 | struct clk *fclk; |
| 83 | 73 | ||
| 74 | char *irqstr[SCIx_NR_IRQS]; | ||
| 75 | |||
| 84 | struct dma_chan *chan_tx; | 76 | struct dma_chan *chan_tx; |
| 85 | struct dma_chan *chan_rx; | 77 | struct dma_chan *chan_rx; |
| 86 | 78 | ||
| @@ -121,6 +113,278 @@ to_sci_port(struct uart_port *uart) | |||
| 121 | return container_of(uart, struct sci_port, port); | 113 | return container_of(uart, struct sci_port, port); |
| 122 | } | 114 | } |
| 123 | 115 | ||
| 116 | struct plat_sci_reg { | ||
| 117 | u8 offset, size; | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Helper for invalidating specific entries of an inherited map. */ | ||
| 121 | #define sci_reg_invalid { .offset = 0, .size = 0 } | ||
| 122 | |||
| 123 | static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { | ||
| 124 | [SCIx_PROBE_REGTYPE] = { | ||
| 125 | [0 ... SCIx_NR_REGS - 1] = sci_reg_invalid, | ||
| 126 | }, | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Common SCI definitions, dependent on the port's regshift | ||
| 130 | * value. | ||
| 131 | */ | ||
| 132 | [SCIx_SCI_REGTYPE] = { | ||
| 133 | [SCSMR] = { 0x00, 8 }, | ||
| 134 | [SCBRR] = { 0x01, 8 }, | ||
| 135 | [SCSCR] = { 0x02, 8 }, | ||
| 136 | [SCxTDR] = { 0x03, 8 }, | ||
| 137 | [SCxSR] = { 0x04, 8 }, | ||
| 138 | [SCxRDR] = { 0x05, 8 }, | ||
| 139 | [SCFCR] = sci_reg_invalid, | ||
| 140 | [SCFDR] = sci_reg_invalid, | ||
| 141 | [SCTFDR] = sci_reg_invalid, | ||
| 142 | [SCRFDR] = sci_reg_invalid, | ||
| 143 | [SCSPTR] = sci_reg_invalid, | ||
| 144 | [SCLSR] = sci_reg_invalid, | ||
| 145 | }, | ||
| 146 | |||
| 147 | /* | ||
| 148 | * Common definitions for legacy IrDA ports, dependent on | ||
| 149 | * regshift value. | ||
| 150 | */ | ||
| 151 | [SCIx_IRDA_REGTYPE] = { | ||
| 152 | [SCSMR] = { 0x00, 8 }, | ||
| 153 | [SCBRR] = { 0x01, 8 }, | ||
| 154 | [SCSCR] = { 0x02, 8 }, | ||
| 155 | [SCxTDR] = { 0x03, 8 }, | ||
| 156 | [SCxSR] = { 0x04, 8 }, | ||
| 157 | [SCxRDR] = { 0x05, 8 }, | ||
| 158 | [SCFCR] = { 0x06, 8 }, | ||
| 159 | [SCFDR] = { 0x07, 16 }, | ||
| 160 | [SCTFDR] = sci_reg_invalid, | ||
| 161 | [SCRFDR] = sci_reg_invalid, | ||
| 162 | [SCSPTR] = sci_reg_invalid, | ||
| 163 | [SCLSR] = sci_reg_invalid, | ||
| 164 | }, | ||
| 165 | |||
| 166 | /* | ||
| 167 | * Common SCIFA definitions. | ||
| 168 | */ | ||
| 169 | [SCIx_SCIFA_REGTYPE] = { | ||
| 170 | [SCSMR] = { 0x00, 16 }, | ||
| 171 | [SCBRR] = { 0x04, 8 }, | ||
| 172 | [SCSCR] = { 0x08, 16 }, | ||
| 173 | [SCxTDR] = { 0x20, 8 }, | ||
| 174 | [SCxSR] = { 0x14, 16 }, | ||
| 175 | [SCxRDR] = { 0x24, 8 }, | ||
| 176 | [SCFCR] = { 0x18, 16 }, | ||
| 177 | [SCFDR] = { 0x1c, 16 }, | ||
| 178 | [SCTFDR] = sci_reg_invalid, | ||
| 179 | [SCRFDR] = sci_reg_invalid, | ||
| 180 | [SCSPTR] = sci_reg_invalid, | ||
| 181 | [SCLSR] = sci_reg_invalid, | ||
| 182 | }, | ||
| 183 | |||
| 184 | /* | ||
| 185 | * Common SCIFB definitions. | ||
| 186 | */ | ||
| 187 | [SCIx_SCIFB_REGTYPE] = { | ||
| 188 | [SCSMR] = { 0x00, 16 }, | ||
| 189 | [SCBRR] = { 0x04, 8 }, | ||
| 190 | [SCSCR] = { 0x08, 16 }, | ||
| 191 | [SCxTDR] = { 0x40, 8 }, | ||
| 192 | [SCxSR] = { 0x14, 16 }, | ||
| 193 | [SCxRDR] = { 0x60, 8 }, | ||
| 194 | [SCFCR] = { 0x18, 16 }, | ||
| 195 | [SCFDR] = { 0x1c, 16 }, | ||
| 196 | [SCTFDR] = sci_reg_invalid, | ||
| 197 | [SCRFDR] = sci_reg_invalid, | ||
| 198 | [SCSPTR] = sci_reg_invalid, | ||
| 199 | [SCLSR] = sci_reg_invalid, | ||
| 200 | }, | ||
| 201 | |||
| 202 | /* | ||
| 203 | * Common SH-3 SCIF definitions. | ||
| 204 | */ | ||
| 205 | [SCIx_SH3_SCIF_REGTYPE] = { | ||
| 206 | [SCSMR] = { 0x00, 8 }, | ||
| 207 | [SCBRR] = { 0x02, 8 }, | ||
| 208 | [SCSCR] = { 0x04, 8 }, | ||
| 209 | [SCxTDR] = { 0x06, 8 }, | ||
| 210 | [SCxSR] = { 0x08, 16 }, | ||
| 211 | [SCxRDR] = { 0x0a, 8 }, | ||
| 212 | [SCFCR] = { 0x0c, 8 }, | ||
| 213 | [SCFDR] = { 0x0e, 16 }, | ||
| 214 | [SCTFDR] = sci_reg_invalid, | ||
| 215 | [SCRFDR] = sci_reg_invalid, | ||
| 216 | [SCSPTR] = sci_reg_invalid, | ||
| 217 | [SCLSR] = sci_reg_invalid, | ||
| 218 | }, | ||
| 219 | |||
| 220 | /* | ||
| 221 | * Common SH-4(A) SCIF(B) definitions. | ||
| 222 | */ | ||
| 223 | [SCIx_SH4_SCIF_REGTYPE] = { | ||
| 224 | [SCSMR] = { 0x00, 16 }, | ||
| 225 | [SCBRR] = { 0x04, 8 }, | ||
| 226 | [SCSCR] = { 0x08, 16 }, | ||
| 227 | [SCxTDR] = { 0x0c, 8 }, | ||
| 228 | [SCxSR] = { 0x10, 16 }, | ||
| 229 | [SCxRDR] = { 0x14, 8 }, | ||
| 230 | [SCFCR] = { 0x18, 16 }, | ||
| 231 | [SCFDR] = { 0x1c, 16 }, | ||
| 232 | [SCTFDR] = sci_reg_invalid, | ||
| 233 | [SCRFDR] = sci_reg_invalid, | ||
| 234 | [SCSPTR] = { 0x20, 16 }, | ||
| 235 | [SCLSR] = { 0x24, 16 }, | ||
| 236 | }, | ||
| 237 | |||
| 238 | /* | ||
| 239 | * Common SH-4(A) SCIF(B) definitions for ports without an SCSPTR | ||
| 240 | * register. | ||
| 241 | */ | ||
| 242 | [SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE] = { | ||
| 243 | [SCSMR] = { 0x00, 16 }, | ||
| 244 | [SCBRR] = { 0x04, 8 }, | ||
| 245 | [SCSCR] = { 0x08, 16 }, | ||
| 246 | [SCxTDR] = { 0x0c, 8 }, | ||
| 247 | [SCxSR] = { 0x10, 16 }, | ||
| 248 | [SCxRDR] = { 0x14, 8 }, | ||
| 249 | [SCFCR] = { 0x18, 16 }, | ||
| 250 | [SCFDR] = { 0x1c, 16 }, | ||
| 251 | [SCTFDR] = sci_reg_invalid, | ||
| 252 | [SCRFDR] = sci_reg_invalid, | ||
| 253 | [SCSPTR] = sci_reg_invalid, | ||
| 254 | [SCLSR] = { 0x24, 16 }, | ||
| 255 | }, | ||
| 256 | |||
| 257 | /* | ||
| 258 | * Common SH-4(A) SCIF(B) definitions for ports with FIFO data | ||
| 259 | * count registers. | ||
| 260 | */ | ||
| 261 | [SCIx_SH4_SCIF_FIFODATA_REGTYPE] = { | ||
| 262 | [SCSMR] = { 0x00, 16 }, | ||
| 263 | [SCBRR] = { 0x04, 8 }, | ||
| 264 | [SCSCR] = { 0x08, 16 }, | ||
| 265 | [SCxTDR] = { 0x0c, 8 }, | ||
| 266 | [SCxSR] = { 0x10, 16 }, | ||
| 267 | [SCxRDR] = { 0x14, 8 }, | ||
| 268 | [SCFCR] = { 0x18, 16 }, | ||
| 269 | [SCFDR] = { 0x1c, 16 }, | ||
| 270 | [SCTFDR] = { 0x1c, 16 }, /* aliased to SCFDR */ | ||
| 271 | [SCRFDR] = { 0x20, 16 }, | ||
| 272 | [SCSPTR] = { 0x24, 16 }, | ||
| 273 | [SCLSR] = { 0x28, 16 }, | ||
| 274 | }, | ||
| 275 | |||
| 276 | /* | ||
| 277 | * SH7705-style SCIF(B) ports, lacking both SCSPTR and SCLSR | ||
| 278 | * registers. | ||
| 279 | */ | ||
| 280 | [SCIx_SH7705_SCIF_REGTYPE] = { | ||
| 281 | [SCSMR] = { 0x00, 16 }, | ||
| 282 | [SCBRR] = { 0x04, 8 }, | ||
| 283 | [SCSCR] = { 0x08, 16 }, | ||
| 284 | [SCxTDR] = { 0x20, 8 }, | ||
| 285 | [SCxSR] = { 0x14, 16 }, | ||
| 286 | [SCxRDR] = { 0x24, 8 }, | ||
| 287 | [SCFCR] = { 0x18, 16 }, | ||
| 288 | [SCFDR] = { 0x1c, 16 }, | ||
| 289 | [SCTFDR] = sci_reg_invalid, | ||
| 290 | [SCRFDR] = sci_reg_invalid, | ||
| 291 | [SCSPTR] = sci_reg_invalid, | ||
| 292 | [SCLSR] = sci_reg_invalid, | ||
| 293 | }, | ||
| 294 | }; | ||
| 295 | |||
| 296 | #define sci_getreg(up, offset) (sci_regmap[to_sci_port(up)->cfg->regtype] + offset) | ||
| 297 | |||
| 298 | /* | ||
| 299 | * The "offset" here is rather misleading, in that it refers to an enum | ||
| 300 | * value relative to the port mapping rather than the fixed offset | ||
| 301 | * itself, which needs to be manually retrieved from the platform's | ||
| 302 | * register map for the given port. | ||
| 303 | */ | ||
| 304 | static unsigned int sci_serial_in(struct uart_port *p, int offset) | ||
| 305 | { | ||
| 306 | struct plat_sci_reg *reg = sci_getreg(p, offset); | ||
| 307 | |||
| 308 | if (reg->size == 8) | ||
| 309 | return ioread8(p->membase + (reg->offset << p->regshift)); | ||
| 310 | else if (reg->size == 16) | ||
| 311 | return ioread16(p->membase + (reg->offset << p->regshift)); | ||
| 312 | else | ||
| 313 | WARN(1, "Invalid register access\n"); | ||
| 314 | |||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | static void sci_serial_out(struct uart_port *p, int offset, int value) | ||
| 319 | { | ||
| 320 | struct plat_sci_reg *reg = sci_getreg(p, offset); | ||
| 321 | |||
| 322 | if (reg->size == 8) | ||
| 323 | iowrite8(value, p->membase + (reg->offset << p->regshift)); | ||
| 324 | else if (reg->size == 16) | ||
| 325 | iowrite16(value, p->membase + (reg->offset << p->regshift)); | ||
| 326 | else | ||
| 327 | WARN(1, "Invalid register access\n"); | ||
| 328 | } | ||
| 329 | |||
| 330 | #define sci_in(up, offset) (up->serial_in(up, offset)) | ||
| 331 | #define sci_out(up, offset, value) (up->serial_out(up, offset, value)) | ||
| 332 | |||
| 333 | static int sci_probe_regmap(struct plat_sci_port *cfg) | ||
| 334 | { | ||
| 335 | switch (cfg->type) { | ||
| 336 | case PORT_SCI: | ||
| 337 | cfg->regtype = SCIx_SCI_REGTYPE; | ||
| 338 | break; | ||
| 339 | case PORT_IRDA: | ||
| 340 | cfg->regtype = SCIx_IRDA_REGTYPE; | ||
| 341 | break; | ||
| 342 | case PORT_SCIFA: | ||
| 343 | cfg->regtype = SCIx_SCIFA_REGTYPE; | ||
| 344 | break; | ||
| 345 | case PORT_SCIFB: | ||
| 346 | cfg->regtype = SCIx_SCIFB_REGTYPE; | ||
| 347 | break; | ||
| 348 | case PORT_SCIF: | ||
| 349 | /* | ||
| 350 | * The SH-4 is a bit of a misnomer here, although that's | ||
| 351 | * where this particular port layout originated. This | ||
| 352 | * configuration (or some slight variation thereof) | ||
| 353 | * remains the dominant model for all SCIFs. | ||
| 354 | */ | ||
| 355 | cfg->regtype = SCIx_SH4_SCIF_REGTYPE; | ||
| 356 | break; | ||
| 357 | default: | ||
| 358 | printk(KERN_ERR "Can't probe register map for given port\n"); | ||
| 359 | return -EINVAL; | ||
| 360 | } | ||
| 361 | |||
| 362 | return 0; | ||
| 363 | } | ||
| 364 | |||
| 365 | static void sci_port_enable(struct sci_port *sci_port) | ||
| 366 | { | ||
| 367 | if (!sci_port->port.dev) | ||
| 368 | return; | ||
| 369 | |||
| 370 | pm_runtime_get_sync(sci_port->port.dev); | ||
| 371 | |||
| 372 | clk_enable(sci_port->iclk); | ||
| 373 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | ||
| 374 | clk_enable(sci_port->fclk); | ||
| 375 | } | ||
| 376 | |||
| 377 | static void sci_port_disable(struct sci_port *sci_port) | ||
| 378 | { | ||
| 379 | if (!sci_port->port.dev) | ||
| 380 | return; | ||
| 381 | |||
| 382 | clk_disable(sci_port->fclk); | ||
| 383 | clk_disable(sci_port->iclk); | ||
| 384 | |||
| 385 | pm_runtime_put_sync(sci_port->port.dev); | ||
| 386 | } | ||
| 387 | |||
| 124 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 388 | #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
| 125 | 389 | ||
| 126 | #ifdef CONFIG_CONSOLE_POLL | 390 | #ifdef CONFIG_CONSOLE_POLL |
| @@ -164,223 +428,76 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
| 164 | } | 428 | } |
| 165 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ | 429 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ |
| 166 | 430 | ||
| 167 | #if defined(__H8300H__) || defined(__H8300S__) | ||
| 168 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) | 431 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
| 169 | { | 432 | { |
| 170 | int ch = (port->mapbase - SMR0) >> 3; | 433 | struct sci_port *s = to_sci_port(port); |
| 171 | 434 | struct plat_sci_reg *reg = sci_regmap[s->cfg->regtype] + SCSPTR; | |
| 172 | /* set DDR regs */ | ||
| 173 | H8300_GPIO_DDR(h8300_sci_pins[ch].port, | ||
| 174 | h8300_sci_pins[ch].rx, | ||
| 175 | H8300_GPIO_INPUT); | ||
| 176 | H8300_GPIO_DDR(h8300_sci_pins[ch].port, | ||
| 177 | h8300_sci_pins[ch].tx, | ||
| 178 | H8300_GPIO_OUTPUT); | ||
| 179 | |||
| 180 | /* tx mark output*/ | ||
| 181 | H8300_SCI_DR(ch) |= h8300_sci_pins[ch].tx; | ||
| 182 | } | ||
| 183 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
| 184 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 185 | { | ||
| 186 | if (port->mapbase == 0xA4400000) { | ||
| 187 | __raw_writew(__raw_readw(PACR) & 0xffc0, PACR); | ||
| 188 | __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR); | ||
| 189 | } else if (port->mapbase == 0xA4410000) | ||
| 190 | __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR); | ||
| 191 | } | ||
| 192 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721) | ||
| 193 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 194 | { | ||
| 195 | unsigned short data; | ||
| 196 | |||
| 197 | if (cflag & CRTSCTS) { | ||
| 198 | /* enable RTS/CTS */ | ||
| 199 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | ||
| 200 | /* Clear PTCR bit 9-2; enable all scif pins but sck */ | ||
| 201 | data = __raw_readw(PORT_PTCR); | ||
| 202 | __raw_writew((data & 0xfc03), PORT_PTCR); | ||
| 203 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | ||
| 204 | /* Clear PVCR bit 9-2 */ | ||
| 205 | data = __raw_readw(PORT_PVCR); | ||
| 206 | __raw_writew((data & 0xfc03), PORT_PVCR); | ||
| 207 | } | ||
| 208 | } else { | ||
| 209 | if (port->mapbase == 0xa4430000) { /* SCIF0 */ | ||
| 210 | /* Clear PTCR bit 5-2; enable only tx and rx */ | ||
| 211 | data = __raw_readw(PORT_PTCR); | ||
| 212 | __raw_writew((data & 0xffc3), PORT_PTCR); | ||
| 213 | } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ | ||
| 214 | /* Clear PVCR bit 5-2 */ | ||
| 215 | data = __raw_readw(PORT_PVCR); | ||
| 216 | __raw_writew((data & 0xffc3), PORT_PVCR); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | } | ||
| 220 | #elif defined(CONFIG_CPU_SH3) | ||
| 221 | /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ | ||
| 222 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 223 | { | ||
| 224 | unsigned short data; | ||
| 225 | |||
| 226 | /* We need to set SCPCR to enable RTS/CTS */ | ||
| 227 | data = __raw_readw(SCPCR); | ||
| 228 | /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/ | ||
| 229 | __raw_writew(data & 0x0fcf, SCPCR); | ||
| 230 | |||
| 231 | if (!(cflag & CRTSCTS)) { | ||
| 232 | /* We need to set SCPCR to enable RTS/CTS */ | ||
| 233 | data = __raw_readw(SCPCR); | ||
| 234 | /* Clear out SCP7MD1,0, SCP4MD1,0, | ||
| 235 | Set SCP6MD1,0 = {01} (output) */ | ||
| 236 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); | ||
| 237 | 435 | ||
| 238 | data = __raw_readb(SCPDR); | 436 | /* |
| 239 | /* Set /RTS2 (bit6) = 0 */ | 437 | * Use port-specific handler if provided. |
| 240 | __raw_writeb(data & 0xbf, SCPDR); | 438 | */ |
| 439 | if (s->cfg->ops && s->cfg->ops->init_pins) { | ||
| 440 | s->cfg->ops->init_pins(port, cflag); | ||
| 441 | return; | ||
| 241 | } | 442 | } |
| 242 | } | ||
| 243 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | ||
| 244 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 245 | { | ||
| 246 | unsigned short data; | ||
| 247 | 443 | ||
| 248 | if (port->mapbase == 0xffe00000) { | 444 | /* |
| 249 | data = __raw_readw(PSCR); | 445 | * For the generic path SCSPTR is necessary. Bail out if that's |
| 250 | data &= ~0x03cf; | 446 | * unavailable, too. |
| 251 | if (!(cflag & CRTSCTS)) | 447 | */ |
| 252 | data |= 0x0340; | 448 | if (!reg->size) |
| 449 | return; | ||
| 253 | 450 | ||
| 254 | __raw_writew(data, PSCR); | ||
| 255 | } | ||
| 256 | } | ||
| 257 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \ | ||
| 258 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ | ||
| 259 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
| 260 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
| 261 | defined(CONFIG_CPU_SUBTYPE_SH7786) || \ | ||
| 262 | defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
| 263 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 264 | { | ||
| 265 | if (!(cflag & CRTSCTS)) | ||
| 266 | __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */ | ||
| 267 | } | ||
| 268 | #elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A) | ||
| 269 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 270 | { | ||
| 271 | if (!(cflag & CRTSCTS)) | 451 | if (!(cflag & CRTSCTS)) |
| 272 | __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */ | 452 | sci_out(port, SCSPTR, 0x0080); /* Set RTS = 1 */ |
| 273 | } | 453 | } |
| 274 | #else | ||
| 275 | static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | ||
| 276 | { | ||
| 277 | /* Nothing to do */ | ||
| 278 | } | ||
| 279 | #endif | ||
| 280 | 454 | ||
| 281 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ | 455 | static int sci_txfill(struct uart_port *port) |
| 282 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
| 283 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
| 284 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
| 285 | static int scif_txfill(struct uart_port *port) | ||
| 286 | { | 456 | { |
| 287 | return sci_in(port, SCTFDR) & 0xff; | 457 | struct plat_sci_reg *reg; |
| 288 | } | ||
| 289 | 458 | ||
| 290 | static int scif_txroom(struct uart_port *port) | 459 | reg = sci_getreg(port, SCTFDR); |
| 291 | { | 460 | if (reg->size) |
| 292 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
| 293 | } | ||
| 294 | |||
| 295 | static int scif_rxfill(struct uart_port *port) | ||
| 296 | { | ||
| 297 | return sci_in(port, SCRFDR) & 0xff; | ||
| 298 | } | ||
| 299 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
| 300 | static int scif_txfill(struct uart_port *port) | ||
| 301 | { | ||
| 302 | if (port->mapbase == 0xffe00000 || | ||
| 303 | port->mapbase == 0xffe08000) | ||
| 304 | /* SCIF0/1*/ | ||
| 305 | return sci_in(port, SCTFDR) & 0xff; | 461 | return sci_in(port, SCTFDR) & 0xff; |
| 306 | else | 462 | |
| 307 | /* SCIF2 */ | 463 | reg = sci_getreg(port, SCFDR); |
| 464 | if (reg->size) | ||
| 308 | return sci_in(port, SCFDR) >> 8; | 465 | return sci_in(port, SCFDR) >> 8; |
| 309 | } | ||
| 310 | 466 | ||
| 311 | static int scif_txroom(struct uart_port *port) | 467 | return !(sci_in(port, SCxSR) & SCI_TDRE); |
| 312 | { | ||
| 313 | if (port->mapbase == 0xffe00000 || | ||
| 314 | port->mapbase == 0xffe08000) | ||
| 315 | /* SCIF0/1*/ | ||
| 316 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
| 317 | else | ||
| 318 | /* SCIF2 */ | ||
| 319 | return SCIF2_TXROOM_MAX - scif_txfill(port); | ||
| 320 | } | 468 | } |
| 321 | 469 | ||
| 322 | static int scif_rxfill(struct uart_port *port) | 470 | static int sci_txroom(struct uart_port *port) |
| 323 | { | ||
| 324 | if ((port->mapbase == 0xffe00000) || | ||
| 325 | (port->mapbase == 0xffe08000)) { | ||
| 326 | /* SCIF0/1*/ | ||
| 327 | return sci_in(port, SCRFDR) & 0xff; | ||
| 328 | } else { | ||
| 329 | /* SCIF2 */ | ||
| 330 | return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; | ||
| 331 | } | ||
| 332 | } | ||
| 333 | #elif defined(CONFIG_ARCH_SH7372) | ||
| 334 | static int scif_txfill(struct uart_port *port) | ||
| 335 | { | 471 | { |
| 336 | if (port->type == PORT_SCIFA) | 472 | return port->fifosize - sci_txfill(port); |
| 337 | return sci_in(port, SCFDR) >> 8; | ||
| 338 | else | ||
| 339 | return sci_in(port, SCTFDR); | ||
| 340 | } | 473 | } |
| 341 | 474 | ||
| 342 | static int scif_txroom(struct uart_port *port) | 475 | static int sci_rxfill(struct uart_port *port) |
| 343 | { | 476 | { |
| 344 | return port->fifosize - scif_txfill(port); | 477 | struct plat_sci_reg *reg; |
| 345 | } | ||
| 346 | 478 | ||
| 347 | static int scif_rxfill(struct uart_port *port) | 479 | reg = sci_getreg(port, SCRFDR); |
| 348 | { | 480 | if (reg->size) |
| 349 | if (port->type == PORT_SCIFA) | 481 | return sci_in(port, SCRFDR) & 0xff; |
| 350 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
| 351 | else | ||
| 352 | return sci_in(port, SCRFDR); | ||
| 353 | } | ||
| 354 | #else | ||
| 355 | static int scif_txfill(struct uart_port *port) | ||
| 356 | { | ||
| 357 | return sci_in(port, SCFDR) >> 8; | ||
| 358 | } | ||
| 359 | 482 | ||
| 360 | static int scif_txroom(struct uart_port *port) | 483 | reg = sci_getreg(port, SCFDR); |
| 361 | { | 484 | if (reg->size) |
| 362 | return SCIF_TXROOM_MAX - scif_txfill(port); | 485 | return sci_in(port, SCFDR) & ((port->fifosize << 1) - 1); |
| 363 | } | ||
| 364 | 486 | ||
| 365 | static int scif_rxfill(struct uart_port *port) | 487 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; |
| 366 | { | ||
| 367 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | ||
| 368 | } | 488 | } |
| 369 | #endif | ||
| 370 | 489 | ||
| 371 | static int sci_txfill(struct uart_port *port) | 490 | /* |
| 491 | * SCI helper for checking the state of the muxed port/RXD pins. | ||
| 492 | */ | ||
| 493 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 372 | { | 494 | { |
| 373 | return !(sci_in(port, SCxSR) & SCI_TDRE); | 495 | struct sci_port *s = to_sci_port(port); |
| 374 | } | ||
| 375 | 496 | ||
| 376 | static int sci_txroom(struct uart_port *port) | 497 | if (s->cfg->port_reg <= 0) |
| 377 | { | 498 | return 1; |
| 378 | return !sci_txfill(port); | ||
| 379 | } | ||
| 380 | 499 | ||
| 381 | static int sci_rxfill(struct uart_port *port) | 500 | return !!__raw_readb(s->cfg->port_reg); |
| 382 | { | ||
| 383 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; | ||
| 384 | } | 501 | } |
| 385 | 502 | ||
| 386 | /* ********************************************************************** * | 503 | /* ********************************************************************** * |
| @@ -406,10 +523,7 @@ static void sci_transmit_chars(struct uart_port *port) | |||
| 406 | return; | 523 | return; |
| 407 | } | 524 | } |
| 408 | 525 | ||
| 409 | if (port->type == PORT_SCI) | 526 | count = sci_txroom(port); |
| 410 | count = sci_txroom(port); | ||
| 411 | else | ||
| 412 | count = scif_txroom(port); | ||
| 413 | 527 | ||
| 414 | do { | 528 | do { |
| 415 | unsigned char c; | 529 | unsigned char c; |
| @@ -464,13 +578,8 @@ static void sci_receive_chars(struct uart_port *port) | |||
| 464 | return; | 578 | return; |
| 465 | 579 | ||
| 466 | while (1) { | 580 | while (1) { |
| 467 | if (port->type == PORT_SCI) | ||
| 468 | count = sci_rxfill(port); | ||
| 469 | else | ||
| 470 | count = scif_rxfill(port); | ||
| 471 | |||
| 472 | /* Don't copy more bytes than there is room for in the buffer */ | 581 | /* Don't copy more bytes than there is room for in the buffer */ |
| 473 | count = tty_buffer_request_room(tty, count); | 582 | count = tty_buffer_request_room(tty, sci_rxfill(port)); |
| 474 | 583 | ||
| 475 | /* If for any reason we can't copy more data, we're done! */ | 584 | /* If for any reason we can't copy more data, we're done! */ |
| 476 | if (count == 0) | 585 | if (count == 0) |
| @@ -561,8 +670,7 @@ static void sci_break_timer(unsigned long data) | |||
| 561 | { | 670 | { |
| 562 | struct sci_port *port = (struct sci_port *)data; | 671 | struct sci_port *port = (struct sci_port *)data; |
| 563 | 672 | ||
| 564 | if (port->enable) | 673 | sci_port_enable(port); |
| 565 | port->enable(&port->port); | ||
| 566 | 674 | ||
| 567 | if (sci_rxd_in(&port->port) == 0) { | 675 | if (sci_rxd_in(&port->port) == 0) { |
| 568 | port->break_flag = 1; | 676 | port->break_flag = 1; |
| @@ -574,8 +682,7 @@ static void sci_break_timer(unsigned long data) | |||
| 574 | } else | 682 | } else |
| 575 | port->break_flag = 0; | 683 | port->break_flag = 0; |
| 576 | 684 | ||
| 577 | if (port->disable) | 685 | sci_port_disable(port); |
| 578 | port->disable(&port->port); | ||
| 579 | } | 686 | } |
| 580 | 687 | ||
| 581 | static int sci_handle_errors(struct uart_port *port) | 688 | static int sci_handle_errors(struct uart_port *port) |
| @@ -583,13 +690,19 @@ static int sci_handle_errors(struct uart_port *port) | |||
| 583 | int copied = 0; | 690 | int copied = 0; |
| 584 | unsigned short status = sci_in(port, SCxSR); | 691 | unsigned short status = sci_in(port, SCxSR); |
| 585 | struct tty_struct *tty = port->state->port.tty; | 692 | struct tty_struct *tty = port->state->port.tty; |
| 693 | struct sci_port *s = to_sci_port(port); | ||
| 586 | 694 | ||
| 587 | if (status & SCxSR_ORER(port)) { | 695 | /* |
| 588 | /* overrun error */ | 696 | * Handle overruns, if supported. |
| 589 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | 697 | */ |
| 590 | copied++; | 698 | if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) { |
| 699 | if (status & (1 << s->cfg->overrun_bit)) { | ||
| 700 | /* overrun error */ | ||
| 701 | if (tty_insert_flip_char(tty, 0, TTY_OVERRUN)) | ||
| 702 | copied++; | ||
| 591 | 703 | ||
| 592 | dev_notice(port->dev, "overrun error"); | 704 | dev_notice(port->dev, "overrun error"); |
| 705 | } | ||
| 593 | } | 706 | } |
| 594 | 707 | ||
| 595 | if (status & SCxSR_FER(port)) { | 708 | if (status & SCxSR_FER(port)) { |
| @@ -637,12 +750,15 @@ static int sci_handle_errors(struct uart_port *port) | |||
| 637 | static int sci_handle_fifo_overrun(struct uart_port *port) | 750 | static int sci_handle_fifo_overrun(struct uart_port *port) |
| 638 | { | 751 | { |
| 639 | struct tty_struct *tty = port->state->port.tty; | 752 | struct tty_struct *tty = port->state->port.tty; |
| 753 | struct sci_port *s = to_sci_port(port); | ||
| 754 | struct plat_sci_reg *reg; | ||
| 640 | int copied = 0; | 755 | int copied = 0; |
| 641 | 756 | ||
| 642 | if (port->type != PORT_SCIF) | 757 | reg = sci_getreg(port, SCLSR); |
| 758 | if (!reg->size) | ||
| 643 | return 0; | 759 | return 0; |
| 644 | 760 | ||
| 645 | if ((sci_in(port, SCLSR) & SCIF_ORER) != 0) { | 761 | if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) { |
| 646 | sci_out(port, SCLSR, 0); | 762 | sci_out(port, SCLSR, 0); |
| 647 | 763 | ||
| 648 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 764 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
| @@ -840,74 +956,102 @@ static int sci_notifier(struct notifier_block *self, | |||
| 840 | return NOTIFY_OK; | 956 | return NOTIFY_OK; |
| 841 | } | 957 | } |
| 842 | 958 | ||
| 843 | static void sci_clk_enable(struct uart_port *port) | 959 | static struct sci_irq_desc { |
| 844 | { | 960 | const char *desc; |
| 845 | struct sci_port *sci_port = to_sci_port(port); | 961 | irq_handler_t handler; |
| 846 | 962 | } sci_irq_desc[] = { | |
| 847 | pm_runtime_get_sync(port->dev); | 963 | /* |
| 964 | * Split out handlers, the default case. | ||
| 965 | */ | ||
| 966 | [SCIx_ERI_IRQ] = { | ||
| 967 | .desc = "rx err", | ||
| 968 | .handler = sci_er_interrupt, | ||
| 969 | }, | ||
| 848 | 970 | ||
| 849 | clk_enable(sci_port->iclk); | 971 | [SCIx_RXI_IRQ] = { |
| 850 | sci_port->port.uartclk = clk_get_rate(sci_port->iclk); | 972 | .desc = "rx full", |
| 851 | clk_enable(sci_port->fclk); | 973 | .handler = sci_rx_interrupt, |
| 852 | } | 974 | }, |
| 853 | 975 | ||
| 854 | static void sci_clk_disable(struct uart_port *port) | 976 | [SCIx_TXI_IRQ] = { |
| 855 | { | 977 | .desc = "tx empty", |
| 856 | struct sci_port *sci_port = to_sci_port(port); | 978 | .handler = sci_tx_interrupt, |
| 979 | }, | ||
| 857 | 980 | ||
| 858 | clk_disable(sci_port->fclk); | 981 | [SCIx_BRI_IRQ] = { |
| 859 | clk_disable(sci_port->iclk); | 982 | .desc = "break", |
| 983 | .handler = sci_br_interrupt, | ||
| 984 | }, | ||
| 860 | 985 | ||
| 861 | pm_runtime_put_sync(port->dev); | 986 | /* |
| 862 | } | 987 | * Special muxed handler. |
| 988 | */ | ||
| 989 | [SCIx_MUX_IRQ] = { | ||
| 990 | .desc = "mux", | ||
| 991 | .handler = sci_mpxed_interrupt, | ||
| 992 | }, | ||
| 993 | }; | ||
| 863 | 994 | ||
| 864 | static int sci_request_irq(struct sci_port *port) | 995 | static int sci_request_irq(struct sci_port *port) |
| 865 | { | 996 | { |
| 866 | int i; | 997 | struct uart_port *up = &port->port; |
| 867 | irqreturn_t (*handlers[4])(int irq, void *ptr) = { | 998 | int i, j, ret = 0; |
| 868 | sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt, | 999 | |
| 869 | sci_br_interrupt, | 1000 | for (i = j = 0; i < SCIx_NR_IRQS; i++, j++) { |
| 870 | }; | 1001 | struct sci_irq_desc *desc; |
| 871 | const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full", | 1002 | unsigned int irq; |
| 872 | "SCI Transmit Data Empty", "SCI Break" }; | 1003 | |
| 873 | 1004 | if (SCIx_IRQ_IS_MUXED(port)) { | |
| 874 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) { | 1005 | i = SCIx_MUX_IRQ; |
| 875 | if (unlikely(!port->cfg->irqs[0])) | 1006 | irq = up->irq; |
| 876 | return -ENODEV; | 1007 | } else |
| 877 | 1008 | irq = port->cfg->irqs[i]; | |
| 878 | if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt, | 1009 | |
| 879 | IRQF_DISABLED, "sci", port)) { | 1010 | desc = sci_irq_desc + i; |
| 880 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | 1011 | port->irqstr[j] = kasprintf(GFP_KERNEL, "%s:%s", |
| 881 | return -ENODEV; | 1012 | dev_name(up->dev), desc->desc); |
| 1013 | if (!port->irqstr[j]) { | ||
| 1014 | dev_err(up->dev, "Failed to allocate %s IRQ string\n", | ||
| 1015 | desc->desc); | ||
| 1016 | goto out_nomem; | ||
| 882 | } | 1017 | } |
| 883 | } else { | 1018 | |
| 884 | for (i = 0; i < ARRAY_SIZE(handlers); i++) { | 1019 | ret = request_irq(irq, desc->handler, up->irqflags, |
| 885 | if (unlikely(!port->cfg->irqs[i])) | 1020 | port->irqstr[j], port); |
| 886 | continue; | 1021 | if (unlikely(ret)) { |
| 887 | 1022 | dev_err(up->dev, "Can't allocate %s IRQ\n", desc->desc); | |
| 888 | if (request_irq(port->cfg->irqs[i], handlers[i], | 1023 | goto out_noirq; |
| 889 | IRQF_DISABLED, desc[i], port)) { | ||
| 890 | dev_err(port->port.dev, "Can't allocate IRQ\n"); | ||
| 891 | return -ENODEV; | ||
| 892 | } | ||
| 893 | } | 1024 | } |
| 894 | } | 1025 | } |
| 895 | 1026 | ||
| 896 | return 0; | 1027 | return 0; |
| 1028 | |||
| 1029 | out_noirq: | ||
| 1030 | while (--i >= 0) | ||
| 1031 | free_irq(port->cfg->irqs[i], port); | ||
| 1032 | |||
| 1033 | out_nomem: | ||
| 1034 | while (--j >= 0) | ||
| 1035 | kfree(port->irqstr[j]); | ||
| 1036 | |||
| 1037 | return ret; | ||
| 897 | } | 1038 | } |
| 898 | 1039 | ||
| 899 | static void sci_free_irq(struct sci_port *port) | 1040 | static void sci_free_irq(struct sci_port *port) |
| 900 | { | 1041 | { |
| 901 | int i; | 1042 | int i; |
| 902 | 1043 | ||
| 903 | if (port->cfg->irqs[0] == port->cfg->irqs[1]) | 1044 | /* |
| 904 | free_irq(port->cfg->irqs[0], port); | 1045 | * Intentionally in reverse order so we iterate over the muxed |
| 905 | else { | 1046 | * IRQ first. |
| 906 | for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) { | 1047 | */ |
| 907 | if (!port->cfg->irqs[i]) | 1048 | for (i = 0; i < SCIx_NR_IRQS; i++) { |
| 908 | continue; | 1049 | free_irq(port->cfg->irqs[i], port); |
| 1050 | kfree(port->irqstr[i]); | ||
| 909 | 1051 | ||
| 910 | free_irq(port->cfg->irqs[i], port); | 1052 | if (SCIx_IRQ_IS_MUXED(port)) { |
| 1053 | /* If there's only one IRQ, we're done. */ | ||
| 1054 | return; | ||
| 911 | } | 1055 | } |
| 912 | } | 1056 | } |
| 913 | } | 1057 | } |
| @@ -915,7 +1059,7 @@ static void sci_free_irq(struct sci_port *port) | |||
| 915 | static unsigned int sci_tx_empty(struct uart_port *port) | 1059 | static unsigned int sci_tx_empty(struct uart_port *port) |
| 916 | { | 1060 | { |
| 917 | unsigned short status = sci_in(port, SCxSR); | 1061 | unsigned short status = sci_in(port, SCxSR); |
| 918 | unsigned short in_tx_fifo = scif_txfill(port); | 1062 | unsigned short in_tx_fifo = sci_txfill(port); |
| 919 | 1063 | ||
| 920 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; | 1064 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; |
| 921 | } | 1065 | } |
| @@ -1438,8 +1582,7 @@ static int sci_startup(struct uart_port *port) | |||
| 1438 | 1582 | ||
| 1439 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1583 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
| 1440 | 1584 | ||
| 1441 | if (s->enable) | 1585 | sci_port_enable(s); |
| 1442 | s->enable(port); | ||
| 1443 | 1586 | ||
| 1444 | ret = sci_request_irq(s); | 1587 | ret = sci_request_irq(s); |
| 1445 | if (unlikely(ret < 0)) | 1588 | if (unlikely(ret < 0)) |
| @@ -1465,8 +1608,7 @@ static void sci_shutdown(struct uart_port *port) | |||
| 1465 | sci_free_dma(port); | 1608 | sci_free_dma(port); |
| 1466 | sci_free_irq(s); | 1609 | sci_free_irq(s); |
| 1467 | 1610 | ||
| 1468 | if (s->disable) | 1611 | sci_port_disable(s); |
| 1469 | s->disable(port); | ||
| 1470 | } | 1612 | } |
| 1471 | 1613 | ||
| 1472 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1614 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, |
| @@ -1513,8 +1655,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1513 | if (likely(baud && port->uartclk)) | 1655 | if (likely(baud && port->uartclk)) |
| 1514 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); | 1656 | t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); |
| 1515 | 1657 | ||
| 1516 | if (s->enable) | 1658 | sci_port_enable(s); |
| 1517 | s->enable(port); | ||
| 1518 | 1659 | ||
| 1519 | do { | 1660 | do { |
| 1520 | status = sci_in(port, SCxSR); | 1661 | status = sci_in(port, SCxSR); |
| @@ -1584,8 +1725,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
| 1584 | if ((termios->c_cflag & CREAD) != 0) | 1725 | if ((termios->c_cflag & CREAD) != 0) |
| 1585 | sci_start_rx(port); | 1726 | sci_start_rx(port); |
| 1586 | 1727 | ||
| 1587 | if (s->disable) | 1728 | sci_port_disable(s); |
| 1588 | s->disable(port); | ||
| 1589 | } | 1729 | } |
| 1590 | 1730 | ||
| 1591 | static const char *sci_type(struct uart_port *port) | 1731 | static const char *sci_type(struct uart_port *port) |
| @@ -1726,6 +1866,7 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1726 | struct plat_sci_port *p) | 1866 | struct plat_sci_port *p) |
| 1727 | { | 1867 | { |
| 1728 | struct uart_port *port = &sci_port->port; | 1868 | struct uart_port *port = &sci_port->port; |
| 1869 | int ret; | ||
| 1729 | 1870 | ||
| 1730 | port->ops = &sci_uart_ops; | 1871 | port->ops = &sci_uart_ops; |
| 1731 | port->iotype = UPIO_MEM; | 1872 | port->iotype = UPIO_MEM; |
| @@ -1746,6 +1887,12 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1746 | break; | 1887 | break; |
| 1747 | } | 1888 | } |
| 1748 | 1889 | ||
| 1890 | if (p->regtype == SCIx_PROBE_REGTYPE) { | ||
| 1891 | ret = sci_probe_regmap(p); | ||
| 1892 | if (unlikely(!ret)) | ||
| 1893 | return ret; | ||
| 1894 | } | ||
| 1895 | |||
| 1749 | if (dev) { | 1896 | if (dev) { |
| 1750 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); | 1897 | sci_port->iclk = clk_get(&dev->dev, "sci_ick"); |
| 1751 | if (IS_ERR(sci_port->iclk)) { | 1898 | if (IS_ERR(sci_port->iclk)) { |
| @@ -1764,8 +1911,6 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1764 | if (IS_ERR(sci_port->fclk)) | 1911 | if (IS_ERR(sci_port->fclk)) |
| 1765 | sci_port->fclk = NULL; | 1912 | sci_port->fclk = NULL; |
| 1766 | 1913 | ||
| 1767 | sci_port->enable = sci_clk_enable; | ||
| 1768 | sci_port->disable = sci_clk_disable; | ||
| 1769 | port->dev = &dev->dev; | 1914 | port->dev = &dev->dev; |
| 1770 | 1915 | ||
| 1771 | pm_runtime_enable(&dev->dev); | 1916 | pm_runtime_enable(&dev->dev); |
| @@ -1775,20 +1920,51 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
| 1775 | sci_port->break_timer.function = sci_break_timer; | 1920 | sci_port->break_timer.function = sci_break_timer; |
| 1776 | init_timer(&sci_port->break_timer); | 1921 | init_timer(&sci_port->break_timer); |
| 1777 | 1922 | ||
| 1923 | /* | ||
| 1924 | * Establish some sensible defaults for the error detection. | ||
| 1925 | */ | ||
| 1926 | if (!p->error_mask) | ||
| 1927 | p->error_mask = (p->type == PORT_SCI) ? | ||
| 1928 | SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK; | ||
| 1929 | |||
| 1930 | /* | ||
| 1931 | * Establish sensible defaults for the overrun detection, unless | ||
| 1932 | * the part has explicitly disabled support for it. | ||
| 1933 | */ | ||
| 1934 | if (p->overrun_bit != SCIx_NOT_SUPPORTED) { | ||
| 1935 | if (p->type == PORT_SCI) | ||
| 1936 | p->overrun_bit = 5; | ||
| 1937 | else if (p->scbrr_algo_id == SCBRR_ALGO_4) | ||
| 1938 | p->overrun_bit = 9; | ||
| 1939 | else | ||
| 1940 | p->overrun_bit = 0; | ||
| 1941 | |||
| 1942 | /* | ||
| 1943 | * Make the error mask inclusive of overrun detection, if | ||
| 1944 | * supported. | ||
| 1945 | */ | ||
| 1946 | p->error_mask |= (1 << p->overrun_bit); | ||
| 1947 | } | ||
| 1948 | |||
| 1778 | sci_port->cfg = p; | 1949 | sci_port->cfg = p; |
| 1779 | 1950 | ||
| 1780 | port->mapbase = p->mapbase; | 1951 | port->mapbase = p->mapbase; |
| 1781 | port->type = p->type; | 1952 | port->type = p->type; |
| 1782 | port->flags = p->flags; | 1953 | port->flags = p->flags; |
| 1954 | port->regshift = p->regshift; | ||
| 1783 | 1955 | ||
| 1784 | /* | 1956 | /* |
| 1785 | * The UART port needs an IRQ value, so we peg this to the TX IRQ | 1957 | * The UART port needs an IRQ value, so we peg this to the RX IRQ |
| 1786 | * for the multi-IRQ ports, which is where we are primarily | 1958 | * for the multi-IRQ ports, which is where we are primarily |
| 1787 | * concerned with the shutdown path synchronization. | 1959 | * concerned with the shutdown path synchronization. |
| 1788 | * | 1960 | * |
| 1789 | * For the muxed case there's nothing more to do. | 1961 | * For the muxed case there's nothing more to do. |
| 1790 | */ | 1962 | */ |
| 1791 | port->irq = p->irqs[SCIx_RXI_IRQ]; | 1963 | port->irq = p->irqs[SCIx_RXI_IRQ]; |
| 1964 | port->irqflags = IRQF_DISABLED; | ||
| 1965 | |||
| 1966 | port->serial_in = sci_serial_in; | ||
| 1967 | port->serial_out = sci_serial_out; | ||
| 1792 | 1968 | ||
| 1793 | if (p->dma_dev) | 1969 | if (p->dma_dev) |
| 1794 | dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", | 1970 | dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n", |
| @@ -1814,8 +1990,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
| 1814 | struct uart_port *port = &sci_port->port; | 1990 | struct uart_port *port = &sci_port->port; |
| 1815 | unsigned short bits; | 1991 | unsigned short bits; |
| 1816 | 1992 | ||
| 1817 | if (sci_port->enable) | 1993 | sci_port_enable(sci_port); |
| 1818 | sci_port->enable(port); | ||
| 1819 | 1994 | ||
| 1820 | uart_console_write(port, s, count, serial_console_putchar); | 1995 | uart_console_write(port, s, count, serial_console_putchar); |
| 1821 | 1996 | ||
| @@ -1824,8 +1999,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
| 1824 | while ((sci_in(port, SCxSR) & bits) != bits) | 1999 | while ((sci_in(port, SCxSR) & bits) != bits) |
| 1825 | cpu_relax(); | 2000 | cpu_relax(); |
| 1826 | 2001 | ||
| 1827 | if (sci_port->disable) | 2002 | sci_port_disable(sci_port); |
| 1828 | sci_port->disable(port); | ||
| 1829 | } | 2003 | } |
| 1830 | 2004 | ||
| 1831 | static int __devinit serial_console_setup(struct console *co, char *options) | 2005 | static int __devinit serial_console_setup(struct console *co, char *options) |
| @@ -1857,20 +2031,13 @@ static int __devinit serial_console_setup(struct console *co, char *options) | |||
| 1857 | if (unlikely(ret != 0)) | 2031 | if (unlikely(ret != 0)) |
| 1858 | return ret; | 2032 | return ret; |
| 1859 | 2033 | ||
| 1860 | if (sci_port->enable) | 2034 | sci_port_enable(sci_port); |
| 1861 | sci_port->enable(port); | ||
| 1862 | 2035 | ||
| 1863 | if (options) | 2036 | if (options) |
| 1864 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 2037 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
| 1865 | 2038 | ||
| 1866 | ret = uart_set_options(port, co, baud, parity, bits, flow); | ||
| 1867 | #if defined(__H8300H__) || defined(__H8300S__) | ||
| 1868 | /* disable rx interrupt */ | ||
| 1869 | if (ret == 0) | ||
| 1870 | sci_stop_rx(port); | ||
| 1871 | #endif | ||
| 1872 | /* TODO: disable clock */ | 2039 | /* TODO: disable clock */ |
| 1873 | return ret; | 2040 | return uart_set_options(port, co, baud, parity, bits, flow); |
| 1874 | } | 2041 | } |
| 1875 | 2042 | ||
| 1876 | static struct console serial_console = { | 2043 | static struct console serial_console = { |
| @@ -2081,3 +2248,5 @@ module_exit(sci_exit); | |||
| 2081 | 2248 | ||
| 2082 | MODULE_LICENSE("GPL"); | 2249 | MODULE_LICENSE("GPL"); |
| 2083 | MODULE_ALIAS("platform:sh-sci"); | 2250 | MODULE_ALIAS("platform:sh-sci"); |
| 2251 | MODULE_AUTHOR("Paul Mundt"); | ||
| 2252 | MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); | ||
diff --git a/drivers/tty/serial/sh-sci.h b/drivers/tty/serial/sh-sci.h index b04d937c9110..e9bed038aa1f 100644 --- a/drivers/tty/serial/sh-sci.h +++ b/drivers/tty/serial/sh-sci.h | |||
| @@ -2,169 +2,14 @@ | |||
| 2 | #include <linux/io.h> | 2 | #include <linux/io.h> |
| 3 | #include <linux/gpio.h> | 3 | #include <linux/gpio.h> |
| 4 | 4 | ||
| 5 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) | ||
| 6 | #include <asm/regs306x.h> | ||
| 7 | #endif | ||
| 8 | #if defined(CONFIG_H8S2678) | ||
| 9 | #include <asm/regs267x.h> | ||
| 10 | #endif | ||
| 11 | |||
| 12 | #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ | ||
| 13 | defined(CONFIG_CPU_SUBTYPE_SH7707) || \ | ||
| 14 | defined(CONFIG_CPU_SUBTYPE_SH7708) || \ | ||
| 15 | defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
| 16 | # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */ | ||
| 17 | # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ | ||
| 18 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
| 19 | # define SCIF0 0xA4400000 | ||
| 20 | # define SCIF2 0xA4410000 | ||
| 21 | # define SCPCR 0xA4000116 | ||
| 22 | # define SCPDR 0xA4000136 | ||
| 23 | #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
| 24 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | ||
| 25 | defined(CONFIG_ARCH_SH73A0) || \ | ||
| 26 | defined(CONFIG_ARCH_SH7367) || \ | ||
| 27 | defined(CONFIG_ARCH_SH7377) || \ | ||
| 28 | defined(CONFIG_ARCH_SH7372) | ||
| 29 | # define PORT_PTCR 0xA405011EUL | ||
| 30 | # define PORT_PVCR 0xA4050122UL | ||
| 31 | # define SCIF_ORER 0x0200 /* overrun error bit */ | ||
| 32 | #elif defined(CONFIG_SH_RTS7751R2D) | ||
| 33 | # define SCSPTR1 0xFFE0001C /* 8 bit SCIF */ | ||
| 34 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ | ||
| 35 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 36 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | ||
| 37 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | ||
| 38 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
| 39 | defined(CONFIG_CPU_SUBTYPE_SH7091) || \ | ||
| 40 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
| 41 | defined(CONFIG_CPU_SUBTYPE_SH7751R) | ||
| 42 | # define SCSPTR1 0xffe0001c /* 8 bit SCI */ | ||
| 43 | # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ | ||
| 44 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 45 | #elif defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
| 46 | # define SCSPTR0 0xfe600024 /* 16 bit SCIF */ | ||
| 47 | # define SCSPTR1 0xfe610024 /* 16 bit SCIF */ | ||
| 48 | # define SCSPTR2 0xfe620024 /* 16 bit SCIF */ | ||
| 49 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 50 | #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
| 51 | # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ | ||
| 52 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 53 | # define PACR 0xa4050100 | ||
| 54 | # define PBCR 0xa4050102 | ||
| 55 | #elif defined(CONFIG_CPU_SUBTYPE_SH7343) | ||
| 56 | # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ | ||
| 57 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | ||
| 58 | # define PADR 0xA4050120 | ||
| 59 | # define PSDR 0xA405013e | ||
| 60 | # define PWDR 0xA4050166 | ||
| 61 | # define PSCR 0xA405011E | ||
| 62 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 63 | #elif defined(CONFIG_CPU_SUBTYPE_SH7366) | ||
| 64 | # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ | ||
| 65 | # define SCSPTR0 SCPDR0 | ||
| 66 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 67 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) | ||
| 68 | # define SCSPTR0 0xa4050160 | ||
| 69 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 70 | #elif defined(CONFIG_CPU_SUBTYPE_SH7724) | ||
| 71 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 72 | #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) | ||
| 73 | # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ | ||
| 74 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 75 | #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) | ||
| 76 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | ||
| 77 | #elif defined(CONFIG_H8S2678) | ||
| 78 | # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) | ||
| 79 | #elif defined(CONFIG_CPU_SUBTYPE_SH7757) | ||
| 80 | # define SCSPTR0 0xfe4b0020 | ||
| 81 | # define SCIF_ORER 0x0001 | ||
| 82 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
| 83 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | ||
| 84 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 85 | #elif defined(CONFIG_CPU_SUBTYPE_SH7770) | ||
| 86 | # define SCSPTR0 0xff923020 /* 16 bit SCIF */ | ||
| 87 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 88 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) | ||
| 89 | # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ | ||
| 90 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | ||
| 91 | #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
| 92 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
| 93 | # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ | ||
| 94 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | ||
| 95 | #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ | ||
| 96 | defined(CONFIG_CPU_SUBTYPE_SH7203) || \ | ||
| 97 | defined(CONFIG_CPU_SUBTYPE_SH7206) || \ | ||
| 98 | defined(CONFIG_CPU_SUBTYPE_SH7263) | ||
| 99 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ | ||
| 100 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | ||
| 101 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ | ||
| 102 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
| 103 | #elif defined(CONFIG_CPU_SUBTYPE_SHX3) | ||
| 104 | # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ | ||
| 105 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | ||
| 106 | #else | ||
| 107 | # error CPU subtype not defined | ||
| 108 | #endif | ||
| 109 | |||
| 110 | /* SCxSR SCI */ | ||
| 111 | #define SCI_TDRE 0x80 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 112 | #define SCI_RDRF 0x40 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 113 | #define SCI_ORER 0x20 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 114 | #define SCI_FER 0x10 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 115 | #define SCI_PER 0x08 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 116 | #define SCI_TEND 0x04 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 117 | /* SCI_MPB 0x02 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 118 | /* SCI_MPBT 0x01 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ | ||
| 119 | |||
| 120 | #define SCI_ERRORS ( SCI_PER | SCI_FER | SCI_ORER) | ||
| 121 | |||
| 122 | /* SCxSR SCIF */ | ||
| 123 | #define SCIF_ER 0x0080 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 124 | #define SCIF_TEND 0x0040 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 125 | #define SCIF_TDFE 0x0020 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 126 | #define SCIF_BRK 0x0010 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 127 | #define SCIF_FER 0x0008 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 128 | #define SCIF_PER 0x0004 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 129 | #define SCIF_RDF 0x0002 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 130 | #define SCIF_DR 0x0001 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ | ||
| 131 | |||
| 132 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | ||
| 133 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
| 134 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | ||
| 135 | defined(CONFIG_ARCH_SH73A0) || \ | ||
| 136 | defined(CONFIG_ARCH_SH7367) || \ | ||
| 137 | defined(CONFIG_ARCH_SH7377) || \ | ||
| 138 | defined(CONFIG_ARCH_SH7372) | ||
| 139 | # define SCIF_ORER 0x0200 | ||
| 140 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) | ||
| 141 | # define SCIF_RFDC_MASK 0x007f | ||
| 142 | # define SCIF_TXROOM_MAX 64 | ||
| 143 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
| 144 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK ) | ||
| 145 | # define SCIF_RFDC_MASK 0x007f | ||
| 146 | # define SCIF_TXROOM_MAX 64 | ||
| 147 | /* SH7763 SCIF2 support */ | ||
| 148 | # define SCIF2_RFDC_MASK 0x001f | ||
| 149 | # define SCIF2_TXROOM_MAX 16 | ||
| 150 | #else | ||
| 151 | # define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK) | ||
| 152 | # define SCIF_RFDC_MASK 0x001f | ||
| 153 | # define SCIF_TXROOM_MAX 16 | ||
| 154 | #endif | ||
| 155 | |||
| 156 | #ifndef SCIF_ORER | ||
| 157 | #define SCIF_ORER 0x0000 | ||
| 158 | #endif | ||
| 159 | |||
| 160 | #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) | 5 | #define SCxSR_TEND(port) (((port)->type == PORT_SCI) ? SCI_TEND : SCIF_TEND) |
| 161 | #define SCxSR_ERRORS(port) (((port)->type == PORT_SCI) ? SCI_ERRORS : SCIF_ERRORS) | ||
| 162 | #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) | 6 | #define SCxSR_RDxF(port) (((port)->type == PORT_SCI) ? SCI_RDRF : SCIF_RDF) |
| 163 | #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) | 7 | #define SCxSR_TDxE(port) (((port)->type == PORT_SCI) ? SCI_TDRE : SCIF_TDFE) |
| 164 | #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) | 8 | #define SCxSR_FER(port) (((port)->type == PORT_SCI) ? SCI_FER : SCIF_FER) |
| 165 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) | 9 | #define SCxSR_PER(port) (((port)->type == PORT_SCI) ? SCI_PER : SCIF_PER) |
| 166 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) | 10 | #define SCxSR_BRK(port) (((port)->type == PORT_SCI) ? 0x00 : SCIF_BRK) |
| 167 | #define SCxSR_ORER(port) (((port)->type == PORT_SCI) ? SCI_ORER : SCIF_ORER) | 11 | |
| 12 | #define SCxSR_ERRORS(port) (to_sci_port(port)->cfg->error_mask) | ||
| 168 | 13 | ||
| 169 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | 14 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ |
| 170 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 15 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| @@ -191,278 +36,3 @@ | |||
| 191 | 36 | ||
| 192 | #define SCI_MAJOR 204 | 37 | #define SCI_MAJOR 204 |
| 193 | #define SCI_MINOR_START 8 | 38 | #define SCI_MINOR_START 8 |
| 194 | |||
| 195 | #define SCI_IN(size, offset) \ | ||
| 196 | if ((size) == 8) { \ | ||
| 197 | return ioread8(port->membase + (offset)); \ | ||
| 198 | } else { \ | ||
| 199 | return ioread16(port->membase + (offset)); \ | ||
| 200 | } | ||
| 201 | #define SCI_OUT(size, offset, value) \ | ||
| 202 | if ((size) == 8) { \ | ||
| 203 | iowrite8(value, port->membase + (offset)); \ | ||
| 204 | } else if ((size) == 16) { \ | ||
| 205 | iowrite16(value, port->membase + (offset)); \ | ||
| 206 | } | ||
| 207 | |||
| 208 | #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ | ||
| 209 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | ||
| 210 | { \ | ||
| 211 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ | ||
| 212 | SCI_IN(scif_size, scif_offset) \ | ||
| 213 | } else { /* PORT_SCI or PORT_SCIFA */ \ | ||
| 214 | SCI_IN(sci_size, sci_offset); \ | ||
| 215 | } \ | ||
| 216 | } \ | ||
| 217 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | ||
| 218 | { \ | ||
| 219 | if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \ | ||
| 220 | SCI_OUT(scif_size, scif_offset, value) \ | ||
| 221 | } else { /* PORT_SCI or PORT_SCIFA */ \ | ||
| 222 | SCI_OUT(sci_size, sci_offset, value); \ | ||
| 223 | } \ | ||
| 224 | } | ||
| 225 | |||
| 226 | #ifdef CONFIG_H8300 | ||
| 227 | /* h8300 don't have SCIF */ | ||
| 228 | #define CPU_SCIF_FNS(name) \ | ||
| 229 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | ||
| 230 | { \ | ||
| 231 | return 0; \ | ||
| 232 | } \ | ||
| 233 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | ||
| 234 | { \ | ||
| 235 | } | ||
| 236 | #else | ||
| 237 | #define CPU_SCIF_FNS(name, scif_offset, scif_size) \ | ||
| 238 | static inline unsigned int sci_##name##_in(struct uart_port *port) \ | ||
| 239 | { \ | ||
| 240 | SCI_IN(scif_size, scif_offset); \ | ||
| 241 | } \ | ||
| 242 | static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \ | ||
| 243 | { \ | ||
| 244 | SCI_OUT(scif_size, scif_offset, value); \ | ||
| 245 | } | ||
| 246 | #endif | ||
| 247 | |||
| 248 | #define CPU_SCI_FNS(name, sci_offset, sci_size) \ | ||
| 249 | static inline unsigned int sci_##name##_in(struct uart_port* port) \ | ||
| 250 | { \ | ||
| 251 | SCI_IN(sci_size, sci_offset); \ | ||
| 252 | } \ | ||
| 253 | static inline void sci_##name##_out(struct uart_port* port, unsigned int value) \ | ||
| 254 | { \ | ||
| 255 | SCI_OUT(sci_size, sci_offset, value); \ | ||
| 256 | } | ||
| 257 | |||
| 258 | #if defined(CONFIG_CPU_SH3) || \ | ||
| 259 | defined(CONFIG_ARCH_SH73A0) || \ | ||
| 260 | defined(CONFIG_ARCH_SH7367) || \ | ||
| 261 | defined(CONFIG_ARCH_SH7377) || \ | ||
| 262 | defined(CONFIG_ARCH_SH7372) | ||
| 263 | #if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) | ||
| 264 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | ||
| 265 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | ||
| 266 | h8_sci_offset, h8_sci_size) \ | ||
| 267 | CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) | ||
| 268 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ | ||
| 269 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | ||
| 270 | #elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | ||
| 271 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
| 272 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | ||
| 273 | defined(CONFIG_ARCH_SH7367) | ||
| 274 | #define SCIF_FNS(name, scif_offset, scif_size) \ | ||
| 275 | CPU_SCIF_FNS(name, scif_offset, scif_size) | ||
| 276 | #elif defined(CONFIG_ARCH_SH7377) || \ | ||
| 277 | defined(CONFIG_ARCH_SH7372) || \ | ||
| 278 | defined(CONFIG_ARCH_SH73A0) | ||
| 279 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \ | ||
| 280 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) | ||
| 281 | #define SCIF_FNS(name, scif_offset, scif_size) \ | ||
| 282 | CPU_SCIF_FNS(name, scif_offset, scif_size) | ||
| 283 | #else | ||
| 284 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | ||
| 285 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | ||
| 286 | h8_sci_offset, h8_sci_size) \ | ||
| 287 | CPU_SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh3_scif_offset, sh3_scif_size) | ||
| 288 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ | ||
| 289 | CPU_SCIF_FNS(name, sh3_scif_offset, sh3_scif_size) | ||
| 290 | #endif | ||
| 291 | #elif defined(__H8300H__) || defined(__H8300S__) | ||
| 292 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | ||
| 293 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | ||
| 294 | h8_sci_offset, h8_sci_size) \ | ||
| 295 | CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) | ||
| 296 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ | ||
| 297 | CPU_SCIF_FNS(name) | ||
| 298 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | ||
| 299 | defined(CONFIG_CPU_SUBTYPE_SH7724) | ||
| 300 | #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \ | ||
| 301 | CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) | ||
| 302 | #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ | ||
| 303 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | ||
| 304 | #else | ||
| 305 | #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ | ||
| 306 | sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ | ||
| 307 | h8_sci_offset, h8_sci_size) \ | ||
| 308 | CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) | ||
| 309 | #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ | ||
| 310 | CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) | ||
| 311 | #endif | ||
| 312 | |||
| 313 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ | ||
| 314 | defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | ||
| 315 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | ||
| 316 | defined(CONFIG_ARCH_SH7367) | ||
| 317 | |||
| 318 | SCIF_FNS(SCSMR, 0x00, 16) | ||
| 319 | SCIF_FNS(SCBRR, 0x04, 8) | ||
| 320 | SCIF_FNS(SCSCR, 0x08, 16) | ||
| 321 | SCIF_FNS(SCxSR, 0x14, 16) | ||
| 322 | SCIF_FNS(SCFCR, 0x18, 16) | ||
| 323 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
| 324 | SCIF_FNS(SCxTDR, 0x20, 8) | ||
| 325 | SCIF_FNS(SCxRDR, 0x24, 8) | ||
| 326 | SCIF_FNS(SCLSR, 0x00, 0) | ||
| 327 | #elif defined(CONFIG_ARCH_SH7377) || \ | ||
| 328 | defined(CONFIG_ARCH_SH7372) || \ | ||
| 329 | defined(CONFIG_ARCH_SH73A0) | ||
| 330 | SCIF_FNS(SCSMR, 0x00, 16) | ||
| 331 | SCIF_FNS(SCBRR, 0x04, 8) | ||
| 332 | SCIF_FNS(SCSCR, 0x08, 16) | ||
| 333 | SCIF_FNS(SCTDSR, 0x0c, 16) | ||
| 334 | SCIF_FNS(SCFER, 0x10, 16) | ||
| 335 | SCIF_FNS(SCxSR, 0x14, 16) | ||
| 336 | SCIF_FNS(SCFCR, 0x18, 16) | ||
| 337 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
| 338 | SCIF_FNS(SCTFDR, 0x38, 16) | ||
| 339 | SCIF_FNS(SCRFDR, 0x3c, 16) | ||
| 340 | SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8) | ||
| 341 | SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8) | ||
| 342 | SCIF_FNS(SCLSR, 0x00, 0) | ||
| 343 | #elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ | ||
| 344 | defined(CONFIG_CPU_SUBTYPE_SH7724) | ||
| 345 | SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) | ||
| 346 | SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8) | ||
| 347 | SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16) | ||
| 348 | SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8) | ||
| 349 | SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16) | ||
| 350 | SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8) | ||
| 351 | SCIx_FNS(SCSPTR, 0, 0, 0, 0) | ||
| 352 | SCIF_FNS(SCFCR, 0x18, 16) | ||
| 353 | SCIF_FNS(SCFDR, 0x1c, 16) | ||
| 354 | SCIF_FNS(SCLSR, 0x24, 16) | ||
| 355 | #else | ||
| 356 | /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ | ||
| 357 | /* name off sz off sz off sz off sz off sz*/ | ||
| 358 | SCIx_FNS(SCSMR, 0x00, 8, 0x00, 8, 0x00, 8, 0x00, 16, 0x00, 8) | ||
| 359 | SCIx_FNS(SCBRR, 0x02, 8, 0x04, 8, 0x02, 8, 0x04, 8, 0x01, 8) | ||
| 360 | SCIx_FNS(SCSCR, 0x04, 8, 0x08, 8, 0x04, 8, 0x08, 16, 0x02, 8) | ||
| 361 | SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8) | ||
| 362 | SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) | ||
| 363 | SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) | ||
| 364 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) | ||
| 365 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ | ||
| 366 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | ||
| 367 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | ||
| 368 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
| 369 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) | ||
| 370 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | ||
| 371 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | ||
| 372 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) | ||
| 373 | SCIF_FNS(SCLSR, 0, 0, 0x28, 16) | ||
| 374 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | ||
| 375 | SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) | ||
| 376 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | ||
| 377 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | ||
| 378 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) | ||
| 379 | SCIF_FNS(SCLSR, 0, 0, 0x28, 16) | ||
| 380 | #else | ||
| 381 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) | ||
| 382 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) | ||
| 383 | SCIF_FNS(SCSPTR, 0, 0, 0, 0) | ||
| 384 | #else | ||
| 385 | SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) | ||
| 386 | #endif | ||
| 387 | SCIF_FNS(SCLSR, 0, 0, 0x24, 16) | ||
| 388 | #endif | ||
| 389 | #endif | ||
| 390 | #define sci_in(port, reg) sci_##reg##_in(port) | ||
| 391 | #define sci_out(port, reg, value) sci_##reg##_out(port, value) | ||
| 392 | |||
| 393 | /* H8/300 series SCI pins assignment */ | ||
| 394 | #if defined(__H8300H__) || defined(__H8300S__) | ||
| 395 | static const struct __attribute__((packed)) { | ||
| 396 | int port; /* GPIO port no */ | ||
| 397 | unsigned short rx,tx; /* GPIO bit no */ | ||
| 398 | } h8300_sci_pins[] = { | ||
| 399 | #if defined(CONFIG_H83007) || defined(CONFIG_H83068) | ||
| 400 | { /* SCI0 */ | ||
| 401 | .port = H8300_GPIO_P9, | ||
| 402 | .rx = H8300_GPIO_B2, | ||
| 403 | .tx = H8300_GPIO_B0, | ||
| 404 | }, | ||
| 405 | { /* SCI1 */ | ||
| 406 | .port = H8300_GPIO_P9, | ||
| 407 | .rx = H8300_GPIO_B3, | ||
| 408 | .tx = H8300_GPIO_B1, | ||
| 409 | }, | ||
| 410 | { /* SCI2 */ | ||
| 411 | .port = H8300_GPIO_PB, | ||
| 412 | .rx = H8300_GPIO_B7, | ||
| 413 | .tx = H8300_GPIO_B6, | ||
| 414 | } | ||
| 415 | #elif defined(CONFIG_H8S2678) | ||
| 416 | { /* SCI0 */ | ||
| 417 | .port = H8300_GPIO_P3, | ||
| 418 | .rx = H8300_GPIO_B2, | ||
| 419 | .tx = H8300_GPIO_B0, | ||
| 420 | }, | ||
| 421 | { /* SCI1 */ | ||
| 422 | .port = H8300_GPIO_P3, | ||
| 423 | .rx = H8300_GPIO_B3, | ||
| 424 | .tx = H8300_GPIO_B1, | ||
| 425 | }, | ||
| 426 | { /* SCI2 */ | ||
| 427 | .port = H8300_GPIO_P5, | ||
| 428 | .rx = H8300_GPIO_B1, | ||
| 429 | .tx = H8300_GPIO_B0, | ||
| 430 | } | ||
| 431 | #endif | ||
| 432 | }; | ||
| 433 | #endif | ||
| 434 | |||
| 435 | #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ | ||
| 436 | defined(CONFIG_CPU_SUBTYPE_SH7707) || \ | ||
| 437 | defined(CONFIG_CPU_SUBTYPE_SH7708) || \ | ||
| 438 | defined(CONFIG_CPU_SUBTYPE_SH7709) | ||
| 439 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 440 | { | ||
| 441 | if (port->mapbase == 0xfffffe80) | ||
| 442 | return __raw_readb(SCPDR)&0x01 ? 1 : 0; /* SCI */ | ||
| 443 | return 1; | ||
| 444 | } | ||
| 445 | #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ | ||
| 446 | defined(CONFIG_CPU_SUBTYPE_SH7751) || \ | ||
| 447 | defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ | ||
| 448 | defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ | ||
| 449 | defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ | ||
| 450 | defined(CONFIG_CPU_SUBTYPE_SH7091) | ||
| 451 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 452 | { | ||
| 453 | if (port->mapbase == 0xffe00000) | ||
| 454 | return __raw_readb(SCSPTR1)&0x01 ? 1 : 0; /* SCI */ | ||
| 455 | return 1; | ||
| 456 | } | ||
| 457 | #elif defined(__H8300H__) || defined(__H8300S__) | ||
| 458 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 459 | { | ||
| 460 | int ch = (port->mapbase - SMR0) >> 3; | ||
| 461 | return (H8300_SCI_DR(ch) & h8300_sci_pins[ch].rx) ? 1 : 0; | ||
| 462 | } | ||
| 463 | #else /* default case for non-SCI processors */ | ||
| 464 | static inline int sci_rxd_in(struct uart_port *port) | ||
| 465 | { | ||
| 466 | return 1; | ||
| 467 | } | ||
| 468 | #endif | ||
