diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:47:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:47:00 -0400 |
commit | e669830526a0abaf301bf408df69cde33901ac63 (patch) | |
tree | 0b6043375006d1754bbd1ab2370b0a0536546cc9 /drivers | |
parent | ebb067d2f4e2db59b076f9c9cba0375a8ad1e07c (diff) | |
parent | 475d5928b79bb78326a645863d46ff95c5e25e5a (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for 3.17. It contains:
- misc Cavium Octeon, BCM47xx, BCM63xx and Alchemy updates
- MIPS ptrace updates and cleanups
- various fixes that will also go to -stable
- a number of cleanups and small non-critical fixes.
- NUMA support for the Loongson 3.
- more support for MSA
- support for MAAR
- various FP enhancements and fixes"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
MIPS: jz4740: remove unnecessary null test before debugfs_remove
MIPS: Octeon: remove unnecessary null test before debugfs_remove_recursive
MIPS: ZBOOT: implement stack protector in compressed boot phase
MIPS: mipsreg: remove duplicate MIPS_CONF4_FTLBSETS_SHIFT
MIPS: Bonito64: remove a duplicate define
MIPS: Malta: initialise MAARs
MIPS: Initialise MAARs
MIPS: detect presence of MAARs
MIPS: define MAAR register accessors & bits
MIPS: mark MSA experimental
MIPS: Don't build MSA support unless it can be used
MIPS: consistently clear MSA flags when starting & copying threads
MIPS: 16 byte align MSA vector context
MIPS: disable preemption whilst initialising MSA
MIPS: ensure MSA gets disabled during boot
MIPS: fix read_msa_* & write_msa_* functions on non-MSA toolchains
MIPS: fix MSA context for tasks which don't use FP first
MIPS: init upper 64b of vector registers when MSA is first used
MIPS: save/disable MSA in lose_fpu
MIPS: preserve scalar FP CSR when switching vector context
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cpufreq/loongson2_cpufreq.c | 6 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 198 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 29 | ||||
-rw-r--r-- | drivers/net/ethernet/amd/au1000_eth.c | 149 | ||||
-rw-r--r-- | drivers/net/irda/au1k_ir.c | 48 | ||||
-rw-r--r-- | drivers/rtc/rtc-au1xxx.c | 18 | ||||
-rw-r--r-- | drivers/spi/spi-au1550.c | 66 | ||||
-rw-r--r-- | drivers/video/fbdev/au1100fb.c | 39 | ||||
-rw-r--r-- | drivers/video/fbdev/au1100fb.h | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/au1200fb.c | 81 | ||||
-rw-r--r-- | drivers/watchdog/octeon-wdt-main.c | 62 |
11 files changed, 444 insertions, 253 deletions
diff --git a/drivers/cpufreq/loongson2_cpufreq.c b/drivers/cpufreq/loongson2_cpufreq.c index d4add8621944..9fa177206032 100644 --- a/drivers/cpufreq/loongson2_cpufreq.c +++ b/drivers/cpufreq/loongson2_cpufreq.c | |||
@@ -148,9 +148,9 @@ static void loongson2_cpu_wait(void) | |||
148 | u32 cpu_freq; | 148 | u32 cpu_freq; |
149 | 149 | ||
150 | spin_lock_irqsave(&loongson2_wait_lock, flags); | 150 | spin_lock_irqsave(&loongson2_wait_lock, flags); |
151 | cpu_freq = LOONGSON_CHIPCFG0; | 151 | cpu_freq = LOONGSON_CHIPCFG(0); |
152 | LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */ | 152 | LOONGSON_CHIPCFG(0) &= ~0x7; /* Put CPU into wait mode */ |
153 | LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */ | 153 | LOONGSON_CHIPCFG(0) = cpu_freq; /* Restore CPU state */ |
154 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); | 154 | spin_unlock_irqrestore(&loongson2_wait_lock, flags); |
155 | local_irq_enable(); | 155 | local_irq_enable(); |
156 | } | 156 | } |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index f5443a6c4915..9c9f6af29251 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -32,6 +32,7 @@ | |||
32 | * (the low to high transition will not occur). | 32 | * (the low to high transition will not occur). |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/clk.h> | ||
35 | #include <linux/module.h> | 36 | #include <linux/module.h> |
36 | #include <linux/init.h> | 37 | #include <linux/init.h> |
37 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
@@ -90,7 +91,7 @@ struct au1xmmc_host { | |||
90 | struct mmc_request *mrq; | 91 | struct mmc_request *mrq; |
91 | 92 | ||
92 | u32 flags; | 93 | u32 flags; |
93 | u32 iobase; | 94 | void __iomem *iobase; |
94 | u32 clock; | 95 | u32 clock; |
95 | u32 bus_width; | 96 | u32 bus_width; |
96 | u32 power_mode; | 97 | u32 power_mode; |
@@ -118,6 +119,7 @@ struct au1xmmc_host { | |||
118 | struct au1xmmc_platform_data *platdata; | 119 | struct au1xmmc_platform_data *platdata; |
119 | struct platform_device *pdev; | 120 | struct platform_device *pdev; |
120 | struct resource *ioarea; | 121 | struct resource *ioarea; |
122 | struct clk *clk; | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | /* Status flags used by the host structure */ | 125 | /* Status flags used by the host structure */ |
@@ -162,32 +164,33 @@ static inline int has_dbdma(void) | |||
162 | 164 | ||
163 | static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) | 165 | static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) |
164 | { | 166 | { |
165 | u32 val = au_readl(HOST_CONFIG(host)); | 167 | u32 val = __raw_readl(HOST_CONFIG(host)); |
166 | val |= mask; | 168 | val |= mask; |
167 | au_writel(val, HOST_CONFIG(host)); | 169 | __raw_writel(val, HOST_CONFIG(host)); |
168 | au_sync(); | 170 | wmb(); /* drain writebuffer */ |
169 | } | 171 | } |
170 | 172 | ||
171 | static inline void FLUSH_FIFO(struct au1xmmc_host *host) | 173 | static inline void FLUSH_FIFO(struct au1xmmc_host *host) |
172 | { | 174 | { |
173 | u32 val = au_readl(HOST_CONFIG2(host)); | 175 | u32 val = __raw_readl(HOST_CONFIG2(host)); |
174 | 176 | ||
175 | au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); | 177 | __raw_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); |
176 | au_sync_delay(1); | 178 | wmb(); /* drain writebuffer */ |
179 | mdelay(1); | ||
177 | 180 | ||
178 | /* SEND_STOP will turn off clock control - this re-enables it */ | 181 | /* SEND_STOP will turn off clock control - this re-enables it */ |
179 | val &= ~SD_CONFIG2_DF; | 182 | val &= ~SD_CONFIG2_DF; |
180 | 183 | ||
181 | au_writel(val, HOST_CONFIG2(host)); | 184 | __raw_writel(val, HOST_CONFIG2(host)); |
182 | au_sync(); | 185 | wmb(); /* drain writebuffer */ |
183 | } | 186 | } |
184 | 187 | ||
185 | static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask) | 188 | static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask) |
186 | { | 189 | { |
187 | u32 val = au_readl(HOST_CONFIG(host)); | 190 | u32 val = __raw_readl(HOST_CONFIG(host)); |
188 | val &= ~mask; | 191 | val &= ~mask; |
189 | au_writel(val, HOST_CONFIG(host)); | 192 | __raw_writel(val, HOST_CONFIG(host)); |
190 | au_sync(); | 193 | wmb(); /* drain writebuffer */ |
191 | } | 194 | } |
192 | 195 | ||
193 | static inline void SEND_STOP(struct au1xmmc_host *host) | 196 | static inline void SEND_STOP(struct au1xmmc_host *host) |
@@ -197,12 +200,13 @@ static inline void SEND_STOP(struct au1xmmc_host *host) | |||
197 | WARN_ON(host->status != HOST_S_DATA); | 200 | WARN_ON(host->status != HOST_S_DATA); |
198 | host->status = HOST_S_STOP; | 201 | host->status = HOST_S_STOP; |
199 | 202 | ||
200 | config2 = au_readl(HOST_CONFIG2(host)); | 203 | config2 = __raw_readl(HOST_CONFIG2(host)); |
201 | au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); | 204 | __raw_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); |
202 | au_sync(); | 205 | wmb(); /* drain writebuffer */ |
203 | 206 | ||
204 | /* Send the stop command */ | 207 | /* Send the stop command */ |
205 | au_writel(STOP_CMD, HOST_CMD(host)); | 208 | __raw_writel(STOP_CMD, HOST_CMD(host)); |
209 | wmb(); /* drain writebuffer */ | ||
206 | } | 210 | } |
207 | 211 | ||
208 | static void au1xmmc_set_power(struct au1xmmc_host *host, int state) | 212 | static void au1xmmc_set_power(struct au1xmmc_host *host, int state) |
@@ -296,28 +300,28 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
296 | } | 300 | } |
297 | } | 301 | } |
298 | 302 | ||
299 | au_writel(cmd->arg, HOST_CMDARG(host)); | 303 | __raw_writel(cmd->arg, HOST_CMDARG(host)); |
300 | au_sync(); | 304 | wmb(); /* drain writebuffer */ |
301 | 305 | ||
302 | if (wait) | 306 | if (wait) |
303 | IRQ_OFF(host, SD_CONFIG_CR); | 307 | IRQ_OFF(host, SD_CONFIG_CR); |
304 | 308 | ||
305 | au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); | 309 | __raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); |
306 | au_sync(); | 310 | wmb(); /* drain writebuffer */ |
307 | 311 | ||
308 | /* Wait for the command to go on the line */ | 312 | /* Wait for the command to go on the line */ |
309 | while (au_readl(HOST_CMD(host)) & SD_CMD_GO) | 313 | while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO) |
310 | /* nop */; | 314 | /* nop */; |
311 | 315 | ||
312 | /* Wait for the command to come back */ | 316 | /* Wait for the command to come back */ |
313 | if (wait) { | 317 | if (wait) { |
314 | u32 status = au_readl(HOST_STATUS(host)); | 318 | u32 status = __raw_readl(HOST_STATUS(host)); |
315 | 319 | ||
316 | while (!(status & SD_STATUS_CR)) | 320 | while (!(status & SD_STATUS_CR)) |
317 | status = au_readl(HOST_STATUS(host)); | 321 | status = __raw_readl(HOST_STATUS(host)); |
318 | 322 | ||
319 | /* Clear the CR status */ | 323 | /* Clear the CR status */ |
320 | au_writel(SD_STATUS_CR, HOST_STATUS(host)); | 324 | __raw_writel(SD_STATUS_CR, HOST_STATUS(host)); |
321 | 325 | ||
322 | IRQ_ON(host, SD_CONFIG_CR); | 326 | IRQ_ON(host, SD_CONFIG_CR); |
323 | } | 327 | } |
@@ -339,11 +343,11 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | |||
339 | data = mrq->cmd->data; | 343 | data = mrq->cmd->data; |
340 | 344 | ||
341 | if (status == 0) | 345 | if (status == 0) |
342 | status = au_readl(HOST_STATUS(host)); | 346 | status = __raw_readl(HOST_STATUS(host)); |
343 | 347 | ||
344 | /* The transaction is really over when the SD_STATUS_DB bit is clear */ | 348 | /* The transaction is really over when the SD_STATUS_DB bit is clear */ |
345 | while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) | 349 | while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) |
346 | status = au_readl(HOST_STATUS(host)); | 350 | status = __raw_readl(HOST_STATUS(host)); |
347 | 351 | ||
348 | data->error = 0; | 352 | data->error = 0; |
349 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); | 353 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); |
@@ -357,7 +361,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) | |||
357 | data->error = -EILSEQ; | 361 | data->error = -EILSEQ; |
358 | 362 | ||
359 | /* Clear the CRC bits */ | 363 | /* Clear the CRC bits */ |
360 | au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); | 364 | __raw_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); |
361 | 365 | ||
362 | data->bytes_xfered = 0; | 366 | data->bytes_xfered = 0; |
363 | 367 | ||
@@ -380,7 +384,7 @@ static void au1xmmc_tasklet_data(unsigned long param) | |||
380 | { | 384 | { |
381 | struct au1xmmc_host *host = (struct au1xmmc_host *)param; | 385 | struct au1xmmc_host *host = (struct au1xmmc_host *)param; |
382 | 386 | ||
383 | u32 status = au_readl(HOST_STATUS(host)); | 387 | u32 status = __raw_readl(HOST_STATUS(host)); |
384 | au1xmmc_data_complete(host, status); | 388 | au1xmmc_data_complete(host, status); |
385 | } | 389 | } |
386 | 390 | ||
@@ -412,15 +416,15 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) | |||
412 | max = AU1XMMC_MAX_TRANSFER; | 416 | max = AU1XMMC_MAX_TRANSFER; |
413 | 417 | ||
414 | for (count = 0; count < max; count++) { | 418 | for (count = 0; count < max; count++) { |
415 | status = au_readl(HOST_STATUS(host)); | 419 | status = __raw_readl(HOST_STATUS(host)); |
416 | 420 | ||
417 | if (!(status & SD_STATUS_TH)) | 421 | if (!(status & SD_STATUS_TH)) |
418 | break; | 422 | break; |
419 | 423 | ||
420 | val = *sg_ptr++; | 424 | val = *sg_ptr++; |
421 | 425 | ||
422 | au_writel((unsigned long)val, HOST_TXPORT(host)); | 426 | __raw_writel((unsigned long)val, HOST_TXPORT(host)); |
423 | au_sync(); | 427 | wmb(); /* drain writebuffer */ |
424 | } | 428 | } |
425 | 429 | ||
426 | host->pio.len -= count; | 430 | host->pio.len -= count; |
@@ -472,7 +476,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
472 | max = AU1XMMC_MAX_TRANSFER; | 476 | max = AU1XMMC_MAX_TRANSFER; |
473 | 477 | ||
474 | for (count = 0; count < max; count++) { | 478 | for (count = 0; count < max; count++) { |
475 | status = au_readl(HOST_STATUS(host)); | 479 | status = __raw_readl(HOST_STATUS(host)); |
476 | 480 | ||
477 | if (!(status & SD_STATUS_NE)) | 481 | if (!(status & SD_STATUS_NE)) |
478 | break; | 482 | break; |
@@ -494,7 +498,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) | |||
494 | break; | 498 | break; |
495 | } | 499 | } |
496 | 500 | ||
497 | val = au_readl(HOST_RXPORT(host)); | 501 | val = __raw_readl(HOST_RXPORT(host)); |
498 | 502 | ||
499 | if (sg_ptr) | 503 | if (sg_ptr) |
500 | *sg_ptr++ = (unsigned char)(val & 0xFF); | 504 | *sg_ptr++ = (unsigned char)(val & 0xFF); |
@@ -537,10 +541,10 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
537 | 541 | ||
538 | if (cmd->flags & MMC_RSP_PRESENT) { | 542 | if (cmd->flags & MMC_RSP_PRESENT) { |
539 | if (cmd->flags & MMC_RSP_136) { | 543 | if (cmd->flags & MMC_RSP_136) { |
540 | r[0] = au_readl(host->iobase + SD_RESP3); | 544 | r[0] = __raw_readl(host->iobase + SD_RESP3); |
541 | r[1] = au_readl(host->iobase + SD_RESP2); | 545 | r[1] = __raw_readl(host->iobase + SD_RESP2); |
542 | r[2] = au_readl(host->iobase + SD_RESP1); | 546 | r[2] = __raw_readl(host->iobase + SD_RESP1); |
543 | r[3] = au_readl(host->iobase + SD_RESP0); | 547 | r[3] = __raw_readl(host->iobase + SD_RESP0); |
544 | 548 | ||
545 | /* The CRC is omitted from the response, so really | 549 | /* The CRC is omitted from the response, so really |
546 | * we only got 120 bytes, but the engine expects | 550 | * we only got 120 bytes, but the engine expects |
@@ -559,7 +563,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
559 | * that means that the OSR data starts at bit 31, | 563 | * that means that the OSR data starts at bit 31, |
560 | * so we can just read RESP0 and return that. | 564 | * so we can just read RESP0 and return that. |
561 | */ | 565 | */ |
562 | cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | 566 | cmd->resp[0] = __raw_readl(host->iobase + SD_RESP0); |
563 | } | 567 | } |
564 | } | 568 | } |
565 | 569 | ||
@@ -586,7 +590,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
586 | u32 mask = SD_STATUS_DB | SD_STATUS_NE; | 590 | u32 mask = SD_STATUS_DB | SD_STATUS_NE; |
587 | 591 | ||
588 | while((status & mask) != mask) | 592 | while((status & mask) != mask) |
589 | status = au_readl(HOST_STATUS(host)); | 593 | status = __raw_readl(HOST_STATUS(host)); |
590 | } | 594 | } |
591 | 595 | ||
592 | au1xxx_dbdma_start(channel); | 596 | au1xxx_dbdma_start(channel); |
@@ -595,24 +599,17 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
595 | 599 | ||
596 | static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) | 600 | static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) |
597 | { | 601 | { |
598 | unsigned int pbus = get_au1x00_speed(); | 602 | unsigned int pbus = clk_get_rate(host->clk); |
599 | unsigned int divisor; | 603 | unsigned int divisor = ((pbus / rate) / 2) - 1; |
600 | u32 config; | 604 | u32 config; |
601 | 605 | ||
602 | /* From databook: | 606 | config = __raw_readl(HOST_CONFIG(host)); |
603 | * divisor = ((((cpuclock / sbus_divisor) / 2) / mmcclock) / 2) - 1 | ||
604 | */ | ||
605 | pbus /= ((au_readl(SYS_POWERCTRL) & 0x3) + 2); | ||
606 | pbus /= 2; | ||
607 | divisor = ((pbus / rate) / 2) - 1; | ||
608 | |||
609 | config = au_readl(HOST_CONFIG(host)); | ||
610 | 607 | ||
611 | config &= ~(SD_CONFIG_DIV); | 608 | config &= ~(SD_CONFIG_DIV); |
612 | config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE; | 609 | config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE; |
613 | 610 | ||
614 | au_writel(config, HOST_CONFIG(host)); | 611 | __raw_writel(config, HOST_CONFIG(host)); |
615 | au_sync(); | 612 | wmb(); /* drain writebuffer */ |
616 | } | 613 | } |
617 | 614 | ||
618 | static int au1xmmc_prepare_data(struct au1xmmc_host *host, | 615 | static int au1xmmc_prepare_data(struct au1xmmc_host *host, |
@@ -636,7 +633,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, | |||
636 | if (host->dma.len == 0) | 633 | if (host->dma.len == 0) |
637 | return -ETIMEDOUT; | 634 | return -ETIMEDOUT; |
638 | 635 | ||
639 | au_writel(data->blksz - 1, HOST_BLKSIZE(host)); | 636 | __raw_writel(data->blksz - 1, HOST_BLKSIZE(host)); |
640 | 637 | ||
641 | if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) { | 638 | if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) { |
642 | int i; | 639 | int i; |
@@ -723,31 +720,34 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
723 | static void au1xmmc_reset_controller(struct au1xmmc_host *host) | 720 | static void au1xmmc_reset_controller(struct au1xmmc_host *host) |
724 | { | 721 | { |
725 | /* Apply the clock */ | 722 | /* Apply the clock */ |
726 | au_writel(SD_ENABLE_CE, HOST_ENABLE(host)); | 723 | __raw_writel(SD_ENABLE_CE, HOST_ENABLE(host)); |
727 | au_sync_delay(1); | 724 | wmb(); /* drain writebuffer */ |
725 | mdelay(1); | ||
728 | 726 | ||
729 | au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); | 727 | __raw_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); |
730 | au_sync_delay(5); | 728 | wmb(); /* drain writebuffer */ |
729 | mdelay(5); | ||
731 | 730 | ||
732 | au_writel(~0, HOST_STATUS(host)); | 731 | __raw_writel(~0, HOST_STATUS(host)); |
733 | au_sync(); | 732 | wmb(); /* drain writebuffer */ |
734 | 733 | ||
735 | au_writel(0, HOST_BLKSIZE(host)); | 734 | __raw_writel(0, HOST_BLKSIZE(host)); |
736 | au_writel(0x001fffff, HOST_TIMEOUT(host)); | 735 | __raw_writel(0x001fffff, HOST_TIMEOUT(host)); |
737 | au_sync(); | 736 | wmb(); /* drain writebuffer */ |
738 | 737 | ||
739 | au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | 738 | __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); |
740 | au_sync(); | 739 | wmb(); /* drain writebuffer */ |
741 | 740 | ||
742 | au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); | 741 | __raw_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); |
743 | au_sync_delay(1); | 742 | wmb(); /* drain writebuffer */ |
743 | mdelay(1); | ||
744 | 744 | ||
745 | au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); | 745 | __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); |
746 | au_sync(); | 746 | wmb(); /* drain writebuffer */ |
747 | 747 | ||
748 | /* Configure interrupts */ | 748 | /* Configure interrupts */ |
749 | au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); | 749 | __raw_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); |
750 | au_sync(); | 750 | wmb(); /* drain writebuffer */ |
751 | } | 751 | } |
752 | 752 | ||
753 | 753 | ||
@@ -767,7 +767,7 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
767 | host->clock = ios->clock; | 767 | host->clock = ios->clock; |
768 | } | 768 | } |
769 | 769 | ||
770 | config2 = au_readl(HOST_CONFIG2(host)); | 770 | config2 = __raw_readl(HOST_CONFIG2(host)); |
771 | switch (ios->bus_width) { | 771 | switch (ios->bus_width) { |
772 | case MMC_BUS_WIDTH_8: | 772 | case MMC_BUS_WIDTH_8: |
773 | config2 |= SD_CONFIG2_BB; | 773 | config2 |= SD_CONFIG2_BB; |
@@ -780,8 +780,8 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
780 | config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); | 780 | config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); |
781 | break; | 781 | break; |
782 | } | 782 | } |
783 | au_writel(config2, HOST_CONFIG2(host)); | 783 | __raw_writel(config2, HOST_CONFIG2(host)); |
784 | au_sync(); | 784 | wmb(); /* drain writebuffer */ |
785 | } | 785 | } |
786 | 786 | ||
787 | #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) | 787 | #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) |
@@ -793,7 +793,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) | |||
793 | struct au1xmmc_host *host = dev_id; | 793 | struct au1xmmc_host *host = dev_id; |
794 | u32 status; | 794 | u32 status; |
795 | 795 | ||
796 | status = au_readl(HOST_STATUS(host)); | 796 | status = __raw_readl(HOST_STATUS(host)); |
797 | 797 | ||
798 | if (!(status & SD_STATUS_I)) | 798 | if (!(status & SD_STATUS_I)) |
799 | return IRQ_NONE; /* not ours */ | 799 | return IRQ_NONE; /* not ours */ |
@@ -839,8 +839,8 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) | |||
839 | status); | 839 | status); |
840 | } | 840 | } |
841 | 841 | ||
842 | au_writel(status, HOST_STATUS(host)); | 842 | __raw_writel(status, HOST_STATUS(host)); |
843 | au_sync(); | 843 | wmb(); /* drain writebuffer */ |
844 | 844 | ||
845 | return IRQ_HANDLED; | 845 | return IRQ_HANDLED; |
846 | } | 846 | } |
@@ -976,7 +976,7 @@ static int au1xmmc_probe(struct platform_device *pdev) | |||
976 | goto out1; | 976 | goto out1; |
977 | } | 977 | } |
978 | 978 | ||
979 | host->iobase = (unsigned long)ioremap(r->start, 0x3c); | 979 | host->iobase = ioremap(r->start, 0x3c); |
980 | if (!host->iobase) { | 980 | if (!host->iobase) { |
981 | dev_err(&pdev->dev, "cannot remap mmio\n"); | 981 | dev_err(&pdev->dev, "cannot remap mmio\n"); |
982 | goto out2; | 982 | goto out2; |
@@ -1025,6 +1025,16 @@ static int au1xmmc_probe(struct platform_device *pdev) | |||
1025 | goto out3; | 1025 | goto out3; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | host->clk = clk_get(&pdev->dev, ALCHEMY_PERIPH_CLK); | ||
1029 | if (IS_ERR(host->clk)) { | ||
1030 | dev_err(&pdev->dev, "cannot find clock\n"); | ||
1031 | goto out_irq; | ||
1032 | } | ||
1033 | if (clk_prepare_enable(host->clk)) { | ||
1034 | dev_err(&pdev->dev, "cannot enable clock\n"); | ||
1035 | goto out_clk; | ||
1036 | } | ||
1037 | |||
1028 | host->status = HOST_S_IDLE; | 1038 | host->status = HOST_S_IDLE; |
1029 | 1039 | ||
1030 | /* board-specific carddetect setup, if any */ | 1040 | /* board-specific carddetect setup, if any */ |
@@ -1075,7 +1085,7 @@ static int au1xmmc_probe(struct platform_device *pdev) | |||
1075 | 1085 | ||
1076 | platform_set_drvdata(pdev, host); | 1086 | platform_set_drvdata(pdev, host); |
1077 | 1087 | ||
1078 | pr_info(DRIVER_NAME ": MMC Controller %d set up at %8.8X" | 1088 | pr_info(DRIVER_NAME ": MMC Controller %d set up at %p" |
1079 | " (mode=%s)\n", pdev->id, host->iobase, | 1089 | " (mode=%s)\n", pdev->id, host->iobase, |
1080 | host->flags & HOST_F_DMA ? "dma" : "pio"); | 1090 | host->flags & HOST_F_DMA ? "dma" : "pio"); |
1081 | 1091 | ||
@@ -1087,10 +1097,10 @@ out6: | |||
1087 | led_classdev_unregister(host->platdata->led); | 1097 | led_classdev_unregister(host->platdata->led); |
1088 | out5: | 1098 | out5: |
1089 | #endif | 1099 | #endif |
1090 | au_writel(0, HOST_ENABLE(host)); | 1100 | __raw_writel(0, HOST_ENABLE(host)); |
1091 | au_writel(0, HOST_CONFIG(host)); | 1101 | __raw_writel(0, HOST_CONFIG(host)); |
1092 | au_writel(0, HOST_CONFIG2(host)); | 1102 | __raw_writel(0, HOST_CONFIG2(host)); |
1093 | au_sync(); | 1103 | wmb(); /* drain writebuffer */ |
1094 | 1104 | ||
1095 | if (host->flags & HOST_F_DBDMA) | 1105 | if (host->flags & HOST_F_DBDMA) |
1096 | au1xmmc_dbdma_shutdown(host); | 1106 | au1xmmc_dbdma_shutdown(host); |
@@ -1101,7 +1111,10 @@ out5: | |||
1101 | if (host->platdata && host->platdata->cd_setup && | 1111 | if (host->platdata && host->platdata->cd_setup && |
1102 | !(mmc->caps & MMC_CAP_NEEDS_POLL)) | 1112 | !(mmc->caps & MMC_CAP_NEEDS_POLL)) |
1103 | host->platdata->cd_setup(mmc, 0); | 1113 | host->platdata->cd_setup(mmc, 0); |
1104 | 1114 | out_clk: | |
1115 | clk_disable_unprepare(host->clk); | ||
1116 | clk_put(host->clk); | ||
1117 | out_irq: | ||
1105 | free_irq(host->irq, host); | 1118 | free_irq(host->irq, host); |
1106 | out3: | 1119 | out3: |
1107 | iounmap((void *)host->iobase); | 1120 | iounmap((void *)host->iobase); |
@@ -1130,10 +1143,10 @@ static int au1xmmc_remove(struct platform_device *pdev) | |||
1130 | !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) | 1143 | !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) |
1131 | host->platdata->cd_setup(host->mmc, 0); | 1144 | host->platdata->cd_setup(host->mmc, 0); |
1132 | 1145 | ||
1133 | au_writel(0, HOST_ENABLE(host)); | 1146 | __raw_writel(0, HOST_ENABLE(host)); |
1134 | au_writel(0, HOST_CONFIG(host)); | 1147 | __raw_writel(0, HOST_CONFIG(host)); |
1135 | au_writel(0, HOST_CONFIG2(host)); | 1148 | __raw_writel(0, HOST_CONFIG2(host)); |
1136 | au_sync(); | 1149 | wmb(); /* drain writebuffer */ |
1137 | 1150 | ||
1138 | tasklet_kill(&host->data_task); | 1151 | tasklet_kill(&host->data_task); |
1139 | tasklet_kill(&host->finish_task); | 1152 | tasklet_kill(&host->finish_task); |
@@ -1143,6 +1156,9 @@ static int au1xmmc_remove(struct platform_device *pdev) | |||
1143 | 1156 | ||
1144 | au1xmmc_set_power(host, 0); | 1157 | au1xmmc_set_power(host, 0); |
1145 | 1158 | ||
1159 | clk_disable_unprepare(host->clk); | ||
1160 | clk_put(host->clk); | ||
1161 | |||
1146 | free_irq(host->irq, host); | 1162 | free_irq(host->irq, host); |
1147 | iounmap((void *)host->iobase); | 1163 | iounmap((void *)host->iobase); |
1148 | release_resource(host->ioarea); | 1164 | release_resource(host->ioarea); |
@@ -1158,11 +1174,11 @@ static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) | |||
1158 | { | 1174 | { |
1159 | struct au1xmmc_host *host = platform_get_drvdata(pdev); | 1175 | struct au1xmmc_host *host = platform_get_drvdata(pdev); |
1160 | 1176 | ||
1161 | au_writel(0, HOST_CONFIG2(host)); | 1177 | __raw_writel(0, HOST_CONFIG2(host)); |
1162 | au_writel(0, HOST_CONFIG(host)); | 1178 | __raw_writel(0, HOST_CONFIG(host)); |
1163 | au_writel(0xffffffff, HOST_STATUS(host)); | 1179 | __raw_writel(0xffffffff, HOST_STATUS(host)); |
1164 | au_writel(0, HOST_ENABLE(host)); | 1180 | __raw_writel(0, HOST_ENABLE(host)); |
1165 | au_sync(); | 1181 | wmb(); /* drain writebuffer */ |
1166 | 1182 | ||
1167 | return 0; | 1183 | return 0; |
1168 | } | 1184 | } |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index bc5c518828d2..77d6c17b38c2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -41,7 +41,7 @@ static u_char au_read_byte(struct mtd_info *mtd) | |||
41 | { | 41 | { |
42 | struct nand_chip *this = mtd->priv; | 42 | struct nand_chip *this = mtd->priv; |
43 | u_char ret = readb(this->IO_ADDR_R); | 43 | u_char ret = readb(this->IO_ADDR_R); |
44 | au_sync(); | 44 | wmb(); /* drain writebuffer */ |
45 | return ret; | 45 | return ret; |
46 | } | 46 | } |
47 | 47 | ||
@@ -56,7 +56,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) | |||
56 | { | 56 | { |
57 | struct nand_chip *this = mtd->priv; | 57 | struct nand_chip *this = mtd->priv; |
58 | writeb(byte, this->IO_ADDR_W); | 58 | writeb(byte, this->IO_ADDR_W); |
59 | au_sync(); | 59 | wmb(); /* drain writebuffer */ |
60 | } | 60 | } |
61 | 61 | ||
62 | /** | 62 | /** |
@@ -69,7 +69,7 @@ static u_char au_read_byte16(struct mtd_info *mtd) | |||
69 | { | 69 | { |
70 | struct nand_chip *this = mtd->priv; | 70 | struct nand_chip *this = mtd->priv; |
71 | u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); | 71 | u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); |
72 | au_sync(); | 72 | wmb(); /* drain writebuffer */ |
73 | return ret; | 73 | return ret; |
74 | } | 74 | } |
75 | 75 | ||
@@ -84,7 +84,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) | |||
84 | { | 84 | { |
85 | struct nand_chip *this = mtd->priv; | 85 | struct nand_chip *this = mtd->priv; |
86 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); | 86 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); |
87 | au_sync(); | 87 | wmb(); /* drain writebuffer */ |
88 | } | 88 | } |
89 | 89 | ||
90 | /** | 90 | /** |
@@ -97,7 +97,7 @@ static u16 au_read_word(struct mtd_info *mtd) | |||
97 | { | 97 | { |
98 | struct nand_chip *this = mtd->priv; | 98 | struct nand_chip *this = mtd->priv; |
99 | u16 ret = readw(this->IO_ADDR_R); | 99 | u16 ret = readw(this->IO_ADDR_R); |
100 | au_sync(); | 100 | wmb(); /* drain writebuffer */ |
101 | return ret; | 101 | return ret; |
102 | } | 102 | } |
103 | 103 | ||
@@ -116,7 +116,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
116 | 116 | ||
117 | for (i = 0; i < len; i++) { | 117 | for (i = 0; i < len; i++) { |
118 | writeb(buf[i], this->IO_ADDR_W); | 118 | writeb(buf[i], this->IO_ADDR_W); |
119 | au_sync(); | 119 | wmb(); /* drain writebuffer */ |
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
@@ -135,7 +135,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
135 | 135 | ||
136 | for (i = 0; i < len; i++) { | 136 | for (i = 0; i < len; i++) { |
137 | buf[i] = readb(this->IO_ADDR_R); | 137 | buf[i] = readb(this->IO_ADDR_R); |
138 | au_sync(); | 138 | wmb(); /* drain writebuffer */ |
139 | } | 139 | } |
140 | } | 140 | } |
141 | 141 | ||
@@ -156,7 +156,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
156 | 156 | ||
157 | for (i = 0; i < len; i++) { | 157 | for (i = 0; i < len; i++) { |
158 | writew(p[i], this->IO_ADDR_W); | 158 | writew(p[i], this->IO_ADDR_W); |
159 | au_sync(); | 159 | wmb(); /* drain writebuffer */ |
160 | } | 160 | } |
161 | 161 | ||
162 | } | 162 | } |
@@ -178,7 +178,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
178 | 178 | ||
179 | for (i = 0; i < len; i++) { | 179 | for (i = 0; i < len; i++) { |
180 | p[i] = readw(this->IO_ADDR_R); | 180 | p[i] = readw(this->IO_ADDR_R); |
181 | au_sync(); | 181 | wmb(); /* drain writebuffer */ |
182 | } | 182 | } |
183 | } | 183 | } |
184 | 184 | ||
@@ -223,26 +223,23 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | |||
223 | 223 | ||
224 | case NAND_CTL_SETNCE: | 224 | case NAND_CTL_SETNCE: |
225 | /* assert (force assert) chip enable */ | 225 | /* assert (force assert) chip enable */ |
226 | au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL); | 226 | alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL); |
227 | break; | 227 | break; |
228 | 228 | ||
229 | case NAND_CTL_CLRNCE: | 229 | case NAND_CTL_CLRNCE: |
230 | /* deassert chip enable */ | 230 | /* deassert chip enable */ |
231 | au_writel(0, MEM_STNDCTL); | 231 | alchemy_wrsmem(0, AU1000_MEM_STNDCTL); |
232 | break; | 232 | break; |
233 | } | 233 | } |
234 | 234 | ||
235 | this->IO_ADDR_R = this->IO_ADDR_W; | 235 | this->IO_ADDR_R = this->IO_ADDR_W; |
236 | 236 | ||
237 | /* Drain the writebuffer */ | 237 | wmb(); /* Drain the writebuffer */ |
238 | au_sync(); | ||
239 | } | 238 | } |
240 | 239 | ||
241 | int au1550_device_ready(struct mtd_info *mtd) | 240 | int au1550_device_ready(struct mtd_info *mtd) |
242 | { | 241 | { |
243 | int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0; | 242 | return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0; |
244 | au_sync(); | ||
245 | return ret; | ||
246 | } | 243 | } |
247 | 244 | ||
248 | /** | 245 | /** |
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index a78e4c136959..31c48a7ac2b6 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c | |||
@@ -89,6 +89,124 @@ MODULE_DESCRIPTION(DRV_DESC); | |||
89 | MODULE_LICENSE("GPL"); | 89 | MODULE_LICENSE("GPL"); |
90 | MODULE_VERSION(DRV_VERSION); | 90 | MODULE_VERSION(DRV_VERSION); |
91 | 91 | ||
92 | /* AU1000 MAC registers and bits */ | ||
93 | #define MAC_CONTROL 0x0 | ||
94 | # define MAC_RX_ENABLE (1 << 2) | ||
95 | # define MAC_TX_ENABLE (1 << 3) | ||
96 | # define MAC_DEF_CHECK (1 << 5) | ||
97 | # define MAC_SET_BL(X) (((X) & 0x3) << 6) | ||
98 | # define MAC_AUTO_PAD (1 << 8) | ||
99 | # define MAC_DISABLE_RETRY (1 << 10) | ||
100 | # define MAC_DISABLE_BCAST (1 << 11) | ||
101 | # define MAC_LATE_COL (1 << 12) | ||
102 | # define MAC_HASH_MODE (1 << 13) | ||
103 | # define MAC_HASH_ONLY (1 << 15) | ||
104 | # define MAC_PASS_ALL (1 << 16) | ||
105 | # define MAC_INVERSE_FILTER (1 << 17) | ||
106 | # define MAC_PROMISCUOUS (1 << 18) | ||
107 | # define MAC_PASS_ALL_MULTI (1 << 19) | ||
108 | # define MAC_FULL_DUPLEX (1 << 20) | ||
109 | # define MAC_NORMAL_MODE 0 | ||
110 | # define MAC_INT_LOOPBACK (1 << 21) | ||
111 | # define MAC_EXT_LOOPBACK (1 << 22) | ||
112 | # define MAC_DISABLE_RX_OWN (1 << 23) | ||
113 | # define MAC_BIG_ENDIAN (1 << 30) | ||
114 | # define MAC_RX_ALL (1 << 31) | ||
115 | #define MAC_ADDRESS_HIGH 0x4 | ||
116 | #define MAC_ADDRESS_LOW 0x8 | ||
117 | #define MAC_MCAST_HIGH 0xC | ||
118 | #define MAC_MCAST_LOW 0x10 | ||
119 | #define MAC_MII_CNTRL 0x14 | ||
120 | # define MAC_MII_BUSY (1 << 0) | ||
121 | # define MAC_MII_READ 0 | ||
122 | # define MAC_MII_WRITE (1 << 1) | ||
123 | # define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6) | ||
124 | # define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11) | ||
125 | #define MAC_MII_DATA 0x18 | ||
126 | #define MAC_FLOW_CNTRL 0x1C | ||
127 | # define MAC_FLOW_CNTRL_BUSY (1 << 0) | ||
128 | # define MAC_FLOW_CNTRL_ENABLE (1 << 1) | ||
129 | # define MAC_PASS_CONTROL (1 << 2) | ||
130 | # define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16) | ||
131 | #define MAC_VLAN1_TAG 0x20 | ||
132 | #define MAC_VLAN2_TAG 0x24 | ||
133 | |||
134 | /* Ethernet Controller Enable */ | ||
135 | # define MAC_EN_CLOCK_ENABLE (1 << 0) | ||
136 | # define MAC_EN_RESET0 (1 << 1) | ||
137 | # define MAC_EN_TOSS (0 << 2) | ||
138 | # define MAC_EN_CACHEABLE (1 << 3) | ||
139 | # define MAC_EN_RESET1 (1 << 4) | ||
140 | # define MAC_EN_RESET2 (1 << 5) | ||
141 | # define MAC_DMA_RESET (1 << 6) | ||
142 | |||
143 | /* Ethernet Controller DMA Channels */ | ||
144 | /* offsets from MAC_TX_RING_ADDR address */ | ||
145 | #define MAC_TX_BUFF0_STATUS 0x0 | ||
146 | # define TX_FRAME_ABORTED (1 << 0) | ||
147 | # define TX_JAB_TIMEOUT (1 << 1) | ||
148 | # define TX_NO_CARRIER (1 << 2) | ||
149 | # define TX_LOSS_CARRIER (1 << 3) | ||
150 | # define TX_EXC_DEF (1 << 4) | ||
151 | # define TX_LATE_COLL_ABORT (1 << 5) | ||
152 | # define TX_EXC_COLL (1 << 6) | ||
153 | # define TX_UNDERRUN (1 << 7) | ||
154 | # define TX_DEFERRED (1 << 8) | ||
155 | # define TX_LATE_COLL (1 << 9) | ||
156 | # define TX_COLL_CNT_MASK (0xF << 10) | ||
157 | # define TX_PKT_RETRY (1 << 31) | ||
158 | #define MAC_TX_BUFF0_ADDR 0x4 | ||
159 | # define TX_DMA_ENABLE (1 << 0) | ||
160 | # define TX_T_DONE (1 << 1) | ||
161 | # define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | ||
162 | #define MAC_TX_BUFF0_LEN 0x8 | ||
163 | #define MAC_TX_BUFF1_STATUS 0x10 | ||
164 | #define MAC_TX_BUFF1_ADDR 0x14 | ||
165 | #define MAC_TX_BUFF1_LEN 0x18 | ||
166 | #define MAC_TX_BUFF2_STATUS 0x20 | ||
167 | #define MAC_TX_BUFF2_ADDR 0x24 | ||
168 | #define MAC_TX_BUFF2_LEN 0x28 | ||
169 | #define MAC_TX_BUFF3_STATUS 0x30 | ||
170 | #define MAC_TX_BUFF3_ADDR 0x34 | ||
171 | #define MAC_TX_BUFF3_LEN 0x38 | ||
172 | |||
173 | /* offsets from MAC_RX_RING_ADDR */ | ||
174 | #define MAC_RX_BUFF0_STATUS 0x0 | ||
175 | # define RX_FRAME_LEN_MASK 0x3fff | ||
176 | # define RX_WDOG_TIMER (1 << 14) | ||
177 | # define RX_RUNT (1 << 15) | ||
178 | # define RX_OVERLEN (1 << 16) | ||
179 | # define RX_COLL (1 << 17) | ||
180 | # define RX_ETHER (1 << 18) | ||
181 | # define RX_MII_ERROR (1 << 19) | ||
182 | # define RX_DRIBBLING (1 << 20) | ||
183 | # define RX_CRC_ERROR (1 << 21) | ||
184 | # define RX_VLAN1 (1 << 22) | ||
185 | # define RX_VLAN2 (1 << 23) | ||
186 | # define RX_LEN_ERROR (1 << 24) | ||
187 | # define RX_CNTRL_FRAME (1 << 25) | ||
188 | # define RX_U_CNTRL_FRAME (1 << 26) | ||
189 | # define RX_MCAST_FRAME (1 << 27) | ||
190 | # define RX_BCAST_FRAME (1 << 28) | ||
191 | # define RX_FILTER_FAIL (1 << 29) | ||
192 | # define RX_PACKET_FILTER (1 << 30) | ||
193 | # define RX_MISSED_FRAME (1 << 31) | ||
194 | |||
195 | # define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ | ||
196 | RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ | ||
197 | RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) | ||
198 | #define MAC_RX_BUFF0_ADDR 0x4 | ||
199 | # define RX_DMA_ENABLE (1 << 0) | ||
200 | # define RX_T_DONE (1 << 1) | ||
201 | # define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | ||
202 | # define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0) | ||
203 | #define MAC_RX_BUFF1_STATUS 0x10 | ||
204 | #define MAC_RX_BUFF1_ADDR 0x14 | ||
205 | #define MAC_RX_BUFF2_STATUS 0x20 | ||
206 | #define MAC_RX_BUFF2_ADDR 0x24 | ||
207 | #define MAC_RX_BUFF3_STATUS 0x30 | ||
208 | #define MAC_RX_BUFF3_ADDR 0x34 | ||
209 | |||
92 | /* | 210 | /* |
93 | * Theory of operation | 211 | * Theory of operation |
94 | * | 212 | * |
@@ -152,10 +270,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) | |||
152 | 270 | ||
153 | if (force_reset || (!aup->mac_enabled)) { | 271 | if (force_reset || (!aup->mac_enabled)) { |
154 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); | 272 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
155 | au_sync_delay(2); | 273 | wmb(); /* drain writebuffer */ |
274 | mdelay(2); | ||
156 | writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | 275 | writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 |
157 | | MAC_EN_CLOCK_ENABLE), aup->enable); | 276 | | MAC_EN_CLOCK_ENABLE), aup->enable); |
158 | au_sync_delay(2); | 277 | wmb(); /* drain writebuffer */ |
278 | mdelay(2); | ||
159 | 279 | ||
160 | aup->mac_enabled = 1; | 280 | aup->mac_enabled = 1; |
161 | } | 281 | } |
@@ -273,7 +393,8 @@ static void au1000_hard_stop(struct net_device *dev) | |||
273 | reg = readl(&aup->mac->control); | 393 | reg = readl(&aup->mac->control); |
274 | reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); | 394 | reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); |
275 | writel(reg, &aup->mac->control); | 395 | writel(reg, &aup->mac->control); |
276 | au_sync_delay(10); | 396 | wmb(); /* drain writebuffer */ |
397 | mdelay(10); | ||
277 | } | 398 | } |
278 | 399 | ||
279 | static void au1000_enable_rx_tx(struct net_device *dev) | 400 | static void au1000_enable_rx_tx(struct net_device *dev) |
@@ -286,7 +407,8 @@ static void au1000_enable_rx_tx(struct net_device *dev) | |||
286 | reg = readl(&aup->mac->control); | 407 | reg = readl(&aup->mac->control); |
287 | reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); | 408 | reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); |
288 | writel(reg, &aup->mac->control); | 409 | writel(reg, &aup->mac->control); |
289 | au_sync_delay(10); | 410 | wmb(); /* drain writebuffer */ |
411 | mdelay(10); | ||
290 | } | 412 | } |
291 | 413 | ||
292 | static void | 414 | static void |
@@ -336,7 +458,8 @@ au1000_adjust_link(struct net_device *dev) | |||
336 | reg |= MAC_DISABLE_RX_OWN; | 458 | reg |= MAC_DISABLE_RX_OWN; |
337 | } | 459 | } |
338 | writel(reg, &aup->mac->control); | 460 | writel(reg, &aup->mac->control); |
339 | au_sync_delay(1); | 461 | wmb(); /* drain writebuffer */ |
462 | mdelay(1); | ||
340 | 463 | ||
341 | au1000_enable_rx_tx(dev); | 464 | au1000_enable_rx_tx(dev); |
342 | aup->old_duplex = phydev->duplex; | 465 | aup->old_duplex = phydev->duplex; |
@@ -500,9 +623,11 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) | |||
500 | au1000_hard_stop(dev); | 623 | au1000_hard_stop(dev); |
501 | 624 | ||
502 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); | 625 | writel(MAC_EN_CLOCK_ENABLE, aup->enable); |
503 | au_sync_delay(2); | 626 | wmb(); /* drain writebuffer */ |
627 | mdelay(2); | ||
504 | writel(0, aup->enable); | 628 | writel(0, aup->enable); |
505 | au_sync_delay(2); | 629 | wmb(); /* drain writebuffer */ |
630 | mdelay(2); | ||
506 | 631 | ||
507 | aup->tx_full = 0; | 632 | aup->tx_full = 0; |
508 | for (i = 0; i < NUM_RX_DMA; i++) { | 633 | for (i = 0; i < NUM_RX_DMA; i++) { |
@@ -652,7 +777,7 @@ static int au1000_init(struct net_device *dev) | |||
652 | for (i = 0; i < NUM_RX_DMA; i++) | 777 | for (i = 0; i < NUM_RX_DMA; i++) |
653 | aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; | 778 | aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; |
654 | 779 | ||
655 | au_sync(); | 780 | wmb(); /* drain writebuffer */ |
656 | 781 | ||
657 | control = MAC_RX_ENABLE | MAC_TX_ENABLE; | 782 | control = MAC_RX_ENABLE | MAC_TX_ENABLE; |
658 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 783 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
@@ -669,7 +794,7 @@ static int au1000_init(struct net_device *dev) | |||
669 | 794 | ||
670 | writel(control, &aup->mac->control); | 795 | writel(control, &aup->mac->control); |
671 | writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ | 796 | writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ |
672 | au_sync(); | 797 | wmb(); /* drain writebuffer */ |
673 | 798 | ||
674 | spin_unlock_irqrestore(&aup->lock, flags); | 799 | spin_unlock_irqrestore(&aup->lock, flags); |
675 | return 0; | 800 | return 0; |
@@ -760,7 +885,7 @@ static int au1000_rx(struct net_device *dev) | |||
760 | } | 885 | } |
761 | prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); | 886 | prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); |
762 | aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); | 887 | aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); |
763 | au_sync(); | 888 | wmb(); /* drain writebuffer */ |
764 | 889 | ||
765 | /* next descriptor */ | 890 | /* next descriptor */ |
766 | prxd = aup->rx_dma_ring[aup->rx_head]; | 891 | prxd = aup->rx_dma_ring[aup->rx_head]; |
@@ -808,7 +933,7 @@ static void au1000_tx_ack(struct net_device *dev) | |||
808 | au1000_update_tx_stats(dev, ptxd->status); | 933 | au1000_update_tx_stats(dev, ptxd->status); |
809 | ptxd->buff_stat &= ~TX_T_DONE; | 934 | ptxd->buff_stat &= ~TX_T_DONE; |
810 | ptxd->len = 0; | 935 | ptxd->len = 0; |
811 | au_sync(); | 936 | wmb(); /* drain writebuffer */ |
812 | 937 | ||
813 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); | 938 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); |
814 | ptxd = aup->tx_dma_ring[aup->tx_tail]; | 939 | ptxd = aup->tx_dma_ring[aup->tx_tail]; |
@@ -939,7 +1064,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) | |||
939 | ps->tx_bytes += ptxd->len; | 1064 | ps->tx_bytes += ptxd->len; |
940 | 1065 | ||
941 | ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; | 1066 | ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; |
942 | au_sync(); | 1067 | wmb(); /* drain writebuffer */ |
943 | dev_kfree_skb(skb); | 1068 | dev_kfree_skb(skb); |
944 | aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1); | 1069 | aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1); |
945 | return NETDEV_TX_OK; | 1070 | return NETDEV_TX_OK; |
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index 5f91e3e01c04..aab2cf72d025 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * with this program; if not, see <http://www.gnu.org/licenses/>. | 18 | * with this program; if not, see <http://www.gnu.org/licenses/>. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/netdevice.h> | 23 | #include <linux/netdevice.h> |
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
@@ -175,6 +176,7 @@ struct au1k_private { | |||
175 | 176 | ||
176 | struct resource *ioarea; | 177 | struct resource *ioarea; |
177 | struct au1k_irda_platform_data *platdata; | 178 | struct au1k_irda_platform_data *platdata; |
179 | struct clk *irda_clk; | ||
178 | }; | 180 | }; |
179 | 181 | ||
180 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ | 182 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ |
@@ -514,9 +516,39 @@ static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) | |||
514 | static int au1k_init(struct net_device *dev) | 516 | static int au1k_init(struct net_device *dev) |
515 | { | 517 | { |
516 | struct au1k_private *aup = netdev_priv(dev); | 518 | struct au1k_private *aup = netdev_priv(dev); |
517 | u32 enable, ring_address; | 519 | u32 enable, ring_address, phyck; |
520 | struct clk *c; | ||
518 | int i; | 521 | int i; |
519 | 522 | ||
523 | c = clk_get(NULL, "irda_clk"); | ||
524 | if (IS_ERR(c)) | ||
525 | return PTR_ERR(c); | ||
526 | i = clk_prepare_enable(c); | ||
527 | if (i) { | ||
528 | clk_put(c); | ||
529 | return i; | ||
530 | } | ||
531 | |||
532 | switch (clk_get_rate(c)) { | ||
533 | case 40000000: | ||
534 | phyck = IR_PHYCLK_40MHZ; | ||
535 | break; | ||
536 | case 48000000: | ||
537 | phyck = IR_PHYCLK_48MHZ; | ||
538 | break; | ||
539 | case 56000000: | ||
540 | phyck = IR_PHYCLK_56MHZ; | ||
541 | break; | ||
542 | case 64000000: | ||
543 | phyck = IR_PHYCLK_64MHZ; | ||
544 | break; | ||
545 | default: | ||
546 | clk_disable_unprepare(c); | ||
547 | clk_put(c); | ||
548 | return -EINVAL; | ||
549 | } | ||
550 | aup->irda_clk = c; | ||
551 | |||
520 | enable = IR_HC | IR_CE | IR_C; | 552 | enable = IR_HC | IR_CE | IR_C; |
521 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 553 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
522 | enable |= IR_BE; | 554 | enable |= IR_BE; |
@@ -545,7 +577,7 @@ static int au1k_init(struct net_device *dev) | |||
545 | irda_write(aup, IR_RING_SIZE, | 577 | irda_write(aup, IR_RING_SIZE, |
546 | (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); | 578 | (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); |
547 | 579 | ||
548 | irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN); | 580 | irda_write(aup, IR_CONFIG_2, phyck | IR_ONE_PIN); |
549 | irda_write(aup, IR_RING_ADDR_CMPR, 0); | 581 | irda_write(aup, IR_RING_ADDR_CMPR, 0); |
550 | 582 | ||
551 | au1k_irda_set_speed(dev, 9600); | 583 | au1k_irda_set_speed(dev, 9600); |
@@ -619,6 +651,9 @@ static int au1k_irda_stop(struct net_device *dev) | |||
619 | free_irq(aup->irq_tx, dev); | 651 | free_irq(aup->irq_tx, dev); |
620 | free_irq(aup->irq_rx, dev); | 652 | free_irq(aup->irq_rx, dev); |
621 | 653 | ||
654 | clk_disable_unprepare(aup->irda_clk); | ||
655 | clk_put(aup->irda_clk); | ||
656 | |||
622 | return 0; | 657 | return 0; |
623 | } | 658 | } |
624 | 659 | ||
@@ -853,6 +888,7 @@ static int au1k_irda_probe(struct platform_device *pdev) | |||
853 | struct au1k_private *aup; | 888 | struct au1k_private *aup; |
854 | struct net_device *dev; | 889 | struct net_device *dev; |
855 | struct resource *r; | 890 | struct resource *r; |
891 | struct clk *c; | ||
856 | int err; | 892 | int err; |
857 | 893 | ||
858 | dev = alloc_irdadev(sizeof(struct au1k_private)); | 894 | dev = alloc_irdadev(sizeof(struct au1k_private)); |
@@ -886,6 +922,14 @@ static int au1k_irda_probe(struct platform_device *pdev) | |||
886 | if (!aup->ioarea) | 922 | if (!aup->ioarea) |
887 | goto out; | 923 | goto out; |
888 | 924 | ||
925 | /* bail out early if clock doesn't exist */ | ||
926 | c = clk_get(NULL, "irda_clk"); | ||
927 | if (IS_ERR(c)) { | ||
928 | err = PTR_ERR(c); | ||
929 | goto out; | ||
930 | } | ||
931 | clk_put(c); | ||
932 | |||
889 | aup->iobase = ioremap_nocache(r->start, resource_size(r)); | 933 | aup->iobase = ioremap_nocache(r->start, resource_size(r)); |
890 | if (!aup->iobase) | 934 | if (!aup->iobase) |
891 | goto out2; | 935 | goto out2; |
diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index ed526a192ce0..fd25e2374d4e 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c | |||
@@ -32,7 +32,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
32 | { | 32 | { |
33 | unsigned long t; | 33 | unsigned long t; |
34 | 34 | ||
35 | t = au_readl(SYS_TOYREAD); | 35 | t = alchemy_rdsys(AU1000_SYS_TOYREAD); |
36 | 36 | ||
37 | rtc_time_to_tm(t, tm); | 37 | rtc_time_to_tm(t, tm); |
38 | 38 | ||
@@ -45,13 +45,12 @@ static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
45 | 45 | ||
46 | rtc_tm_to_time(tm, &t); | 46 | rtc_tm_to_time(tm, &t); |
47 | 47 | ||
48 | au_writel(t, SYS_TOYWRITE); | 48 | alchemy_wrsys(t, AU1000_SYS_TOYWRITE); |
49 | au_sync(); | ||
50 | 49 | ||
51 | /* wait for the pending register write to succeed. This can | 50 | /* wait for the pending register write to succeed. This can |
52 | * take up to 6 seconds... | 51 | * take up to 6 seconds... |
53 | */ | 52 | */ |
54 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | 53 | while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S) |
55 | msleep(1); | 54 | msleep(1); |
56 | 55 | ||
57 | return 0; | 56 | return 0; |
@@ -68,7 +67,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) | |||
68 | unsigned long t; | 67 | unsigned long t; |
69 | int ret; | 68 | int ret; |
70 | 69 | ||
71 | t = au_readl(SYS_COUNTER_CNTRL); | 70 | t = alchemy_rdsys(AU1000_SYS_CNTRCTRL); |
72 | if (!(t & CNTR_OK)) { | 71 | if (!(t & CNTR_OK)) { |
73 | dev_err(&pdev->dev, "counters not working; aborting.\n"); | 72 | dev_err(&pdev->dev, "counters not working; aborting.\n"); |
74 | ret = -ENODEV; | 73 | ret = -ENODEV; |
@@ -78,10 +77,10 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) | |||
78 | ret = -ETIMEDOUT; | 77 | ret = -ETIMEDOUT; |
79 | 78 | ||
80 | /* set counter0 tickrate to 1Hz if necessary */ | 79 | /* set counter0 tickrate to 1Hz if necessary */ |
81 | if (au_readl(SYS_TOYTRIM) != 32767) { | 80 | if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) { |
82 | /* wait until hardware gives access to TRIM register */ | 81 | /* wait until hardware gives access to TRIM register */ |
83 | t = 0x00100000; | 82 | t = 0x00100000; |
84 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S) && --t) | 83 | while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T0S) && --t) |
85 | msleep(1); | 84 | msleep(1); |
86 | 85 | ||
87 | if (!t) { | 86 | if (!t) { |
@@ -93,12 +92,11 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) | |||
93 | } | 92 | } |
94 | 93 | ||
95 | /* set 1Hz TOY tick rate */ | 94 | /* set 1Hz TOY tick rate */ |
96 | au_writel(32767, SYS_TOYTRIM); | 95 | alchemy_wrsys(32767, AU1000_SYS_TOYTRIM); |
97 | au_sync(); | ||
98 | } | 96 | } |
99 | 97 | ||
100 | /* wait until the hardware allows writes to the counter reg */ | 98 | /* wait until the hardware allows writes to the counter reg */ |
101 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S) | 99 | while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S) |
102 | msleep(1); | 100 | msleep(1); |
103 | 101 | ||
104 | rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx", | 102 | rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx", |
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index fb61464348a1..40c3d43c9292 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c | |||
@@ -141,13 +141,13 @@ static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) | |||
141 | PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO | 141 | PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO |
142 | | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO | 142 | | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO |
143 | | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; | 143 | | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; |
144 | au_sync(); | 144 | wmb(); /* drain writebuffer */ |
145 | 145 | ||
146 | hw->regs->psc_spievent = | 146 | hw->regs->psc_spievent = |
147 | PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO | 147 | PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO |
148 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO | 148 | | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO |
149 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; | 149 | | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; |
150 | au_sync(); | 150 | wmb(); /* drain writebuffer */ |
151 | } | 151 | } |
152 | 152 | ||
153 | static void au1550_spi_reset_fifos(struct au1550_spi *hw) | 153 | static void au1550_spi_reset_fifos(struct au1550_spi *hw) |
@@ -155,10 +155,10 @@ static void au1550_spi_reset_fifos(struct au1550_spi *hw) | |||
155 | u32 pcr; | 155 | u32 pcr; |
156 | 156 | ||
157 | hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; | 157 | hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; |
158 | au_sync(); | 158 | wmb(); /* drain writebuffer */ |
159 | do { | 159 | do { |
160 | pcr = hw->regs->psc_spipcr; | 160 | pcr = hw->regs->psc_spipcr; |
161 | au_sync(); | 161 | wmb(); /* drain writebuffer */ |
162 | } while (pcr != 0); | 162 | } while (pcr != 0); |
163 | } | 163 | } |
164 | 164 | ||
@@ -188,9 +188,9 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) | |||
188 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); | 188 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); |
189 | 189 | ||
190 | cfg = hw->regs->psc_spicfg; | 190 | cfg = hw->regs->psc_spicfg; |
191 | au_sync(); | 191 | wmb(); /* drain writebuffer */ |
192 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; | 192 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; |
193 | au_sync(); | 193 | wmb(); /* drain writebuffer */ |
194 | 194 | ||
195 | if (spi->mode & SPI_CPOL) | 195 | if (spi->mode & SPI_CPOL) |
196 | cfg |= PSC_SPICFG_BI; | 196 | cfg |= PSC_SPICFG_BI; |
@@ -218,10 +218,10 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) | |||
218 | cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); | 218 | cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); |
219 | 219 | ||
220 | hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; | 220 | hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; |
221 | au_sync(); | 221 | wmb(); /* drain writebuffer */ |
222 | do { | 222 | do { |
223 | stat = hw->regs->psc_spistat; | 223 | stat = hw->regs->psc_spistat; |
224 | au_sync(); | 224 | wmb(); /* drain writebuffer */ |
225 | } while ((stat & PSC_SPISTAT_DR) == 0); | 225 | } while ((stat & PSC_SPISTAT_DR) == 0); |
226 | 226 | ||
227 | if (hw->pdata->activate_cs) | 227 | if (hw->pdata->activate_cs) |
@@ -252,9 +252,9 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | |||
252 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); | 252 | au1550_spi_bits_handlers_set(hw, spi->bits_per_word); |
253 | 253 | ||
254 | cfg = hw->regs->psc_spicfg; | 254 | cfg = hw->regs->psc_spicfg; |
255 | au_sync(); | 255 | wmb(); /* drain writebuffer */ |
256 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; | 256 | hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; |
257 | au_sync(); | 257 | wmb(); /* drain writebuffer */ |
258 | 258 | ||
259 | if (hw->usedma && bpw <= 8) | 259 | if (hw->usedma && bpw <= 8) |
260 | cfg &= ~PSC_SPICFG_DD_DISABLE; | 260 | cfg &= ~PSC_SPICFG_DD_DISABLE; |
@@ -268,12 +268,12 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) | |||
268 | cfg |= au1550_spi_baudcfg(hw, hz); | 268 | cfg |= au1550_spi_baudcfg(hw, hz); |
269 | 269 | ||
270 | hw->regs->psc_spicfg = cfg; | 270 | hw->regs->psc_spicfg = cfg; |
271 | au_sync(); | 271 | wmb(); /* drain writebuffer */ |
272 | 272 | ||
273 | if (cfg & PSC_SPICFG_DE_ENABLE) { | 273 | if (cfg & PSC_SPICFG_DE_ENABLE) { |
274 | do { | 274 | do { |
275 | stat = hw->regs->psc_spistat; | 275 | stat = hw->regs->psc_spistat; |
276 | au_sync(); | 276 | wmb(); /* drain writebuffer */ |
277 | } while ((stat & PSC_SPISTAT_DR) == 0); | 277 | } while ((stat & PSC_SPISTAT_DR) == 0); |
278 | } | 278 | } |
279 | 279 | ||
@@ -396,11 +396,11 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) | |||
396 | 396 | ||
397 | /* by default enable nearly all events interrupt */ | 397 | /* by default enable nearly all events interrupt */ |
398 | hw->regs->psc_spimsk = PSC_SPIMSK_SD; | 398 | hw->regs->psc_spimsk = PSC_SPIMSK_SD; |
399 | au_sync(); | 399 | wmb(); /* drain writebuffer */ |
400 | 400 | ||
401 | /* start the transfer */ | 401 | /* start the transfer */ |
402 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; | 402 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
403 | au_sync(); | 403 | wmb(); /* drain writebuffer */ |
404 | 404 | ||
405 | wait_for_completion(&hw->master_done); | 405 | wait_for_completion(&hw->master_done); |
406 | 406 | ||
@@ -429,7 +429,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) | |||
429 | 429 | ||
430 | stat = hw->regs->psc_spistat; | 430 | stat = hw->regs->psc_spistat; |
431 | evnt = hw->regs->psc_spievent; | 431 | evnt = hw->regs->psc_spievent; |
432 | au_sync(); | 432 | wmb(); /* drain writebuffer */ |
433 | if ((stat & PSC_SPISTAT_DI) == 0) { | 433 | if ((stat & PSC_SPISTAT_DI) == 0) { |
434 | dev_err(hw->dev, "Unexpected IRQ!\n"); | 434 | dev_err(hw->dev, "Unexpected IRQ!\n"); |
435 | return IRQ_NONE; | 435 | return IRQ_NONE; |
@@ -484,7 +484,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) | |||
484 | static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ | 484 | static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ |
485 | { \ | 485 | { \ |
486 | u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ | 486 | u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ |
487 | au_sync(); \ | 487 | wmb(); /* drain writebuffer */ \ |
488 | if (hw->rx) { \ | 488 | if (hw->rx) { \ |
489 | *(u##size *)hw->rx = (u##size)fifoword; \ | 489 | *(u##size *)hw->rx = (u##size)fifoword; \ |
490 | hw->rx += (size) / 8; \ | 490 | hw->rx += (size) / 8; \ |
@@ -504,7 +504,7 @@ static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ | |||
504 | if (hw->tx_count >= hw->len) \ | 504 | if (hw->tx_count >= hw->len) \ |
505 | fifoword |= PSC_SPITXRX_LC; \ | 505 | fifoword |= PSC_SPITXRX_LC; \ |
506 | hw->regs->psc_spitxrx = fifoword; \ | 506 | hw->regs->psc_spitxrx = fifoword; \ |
507 | au_sync(); \ | 507 | wmb(); /* drain writebuffer */ \ |
508 | } | 508 | } |
509 | 509 | ||
510 | AU1550_SPI_RX_WORD(8,0xff) | 510 | AU1550_SPI_RX_WORD(8,0xff) |
@@ -539,18 +539,18 @@ static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) | |||
539 | } | 539 | } |
540 | 540 | ||
541 | stat = hw->regs->psc_spistat; | 541 | stat = hw->regs->psc_spistat; |
542 | au_sync(); | 542 | wmb(); /* drain writebuffer */ |
543 | if (stat & PSC_SPISTAT_TF) | 543 | if (stat & PSC_SPISTAT_TF) |
544 | break; | 544 | break; |
545 | } | 545 | } |
546 | 546 | ||
547 | /* enable event interrupts */ | 547 | /* enable event interrupts */ |
548 | hw->regs->psc_spimsk = mask; | 548 | hw->regs->psc_spimsk = mask; |
549 | au_sync(); | 549 | wmb(); /* drain writebuffer */ |
550 | 550 | ||
551 | /* start the transfer */ | 551 | /* start the transfer */ |
552 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; | 552 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
553 | au_sync(); | 553 | wmb(); /* drain writebuffer */ |
554 | 554 | ||
555 | wait_for_completion(&hw->master_done); | 555 | wait_for_completion(&hw->master_done); |
556 | 556 | ||
@@ -564,7 +564,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) | |||
564 | 564 | ||
565 | stat = hw->regs->psc_spistat; | 565 | stat = hw->regs->psc_spistat; |
566 | evnt = hw->regs->psc_spievent; | 566 | evnt = hw->regs->psc_spievent; |
567 | au_sync(); | 567 | wmb(); /* drain writebuffer */ |
568 | if ((stat & PSC_SPISTAT_DI) == 0) { | 568 | if ((stat & PSC_SPISTAT_DI) == 0) { |
569 | dev_err(hw->dev, "Unexpected IRQ!\n"); | 569 | dev_err(hw->dev, "Unexpected IRQ!\n"); |
570 | return IRQ_NONE; | 570 | return IRQ_NONE; |
@@ -594,7 +594,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) | |||
594 | do { | 594 | do { |
595 | busy = 0; | 595 | busy = 0; |
596 | stat = hw->regs->psc_spistat; | 596 | stat = hw->regs->psc_spistat; |
597 | au_sync(); | 597 | wmb(); /* drain writebuffer */ |
598 | 598 | ||
599 | /* | 599 | /* |
600 | * Take care to not let the Rx FIFO overflow. | 600 | * Take care to not let the Rx FIFO overflow. |
@@ -615,7 +615,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) | |||
615 | } while (busy); | 615 | } while (busy); |
616 | 616 | ||
617 | hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR; | 617 | hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR; |
618 | au_sync(); | 618 | wmb(); /* drain writebuffer */ |
619 | 619 | ||
620 | /* | 620 | /* |
621 | * Restart the SPI transmission in case of a transmit underflow. | 621 | * Restart the SPI transmission in case of a transmit underflow. |
@@ -634,9 +634,9 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) | |||
634 | */ | 634 | */ |
635 | if (evnt & PSC_SPIEVNT_TU) { | 635 | if (evnt & PSC_SPIEVNT_TU) { |
636 | hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD; | 636 | hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD; |
637 | au_sync(); | 637 | wmb(); /* drain writebuffer */ |
638 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; | 638 | hw->regs->psc_spipcr = PSC_SPIPCR_MS; |
639 | au_sync(); | 639 | wmb(); /* drain writebuffer */ |
640 | } | 640 | } |
641 | 641 | ||
642 | if (hw->rx_count >= hw->len) { | 642 | if (hw->rx_count >= hw->len) { |
@@ -690,19 +690,19 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) | |||
690 | 690 | ||
691 | /* set up the PSC for SPI mode */ | 691 | /* set up the PSC for SPI mode */ |
692 | hw->regs->psc_ctrl = PSC_CTRL_DISABLE; | 692 | hw->regs->psc_ctrl = PSC_CTRL_DISABLE; |
693 | au_sync(); | 693 | wmb(); /* drain writebuffer */ |
694 | hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; | 694 | hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; |
695 | au_sync(); | 695 | wmb(); /* drain writebuffer */ |
696 | 696 | ||
697 | hw->regs->psc_spicfg = 0; | 697 | hw->regs->psc_spicfg = 0; |
698 | au_sync(); | 698 | wmb(); /* drain writebuffer */ |
699 | 699 | ||
700 | hw->regs->psc_ctrl = PSC_CTRL_ENABLE; | 700 | hw->regs->psc_ctrl = PSC_CTRL_ENABLE; |
701 | au_sync(); | 701 | wmb(); /* drain writebuffer */ |
702 | 702 | ||
703 | do { | 703 | do { |
704 | stat = hw->regs->psc_spistat; | 704 | stat = hw->regs->psc_spistat; |
705 | au_sync(); | 705 | wmb(); /* drain writebuffer */ |
706 | } while ((stat & PSC_SPISTAT_SR) == 0); | 706 | } while ((stat & PSC_SPISTAT_SR) == 0); |
707 | 707 | ||
708 | 708 | ||
@@ -717,16 +717,16 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) | |||
717 | #endif | 717 | #endif |
718 | 718 | ||
719 | hw->regs->psc_spicfg = cfg; | 719 | hw->regs->psc_spicfg = cfg; |
720 | au_sync(); | 720 | wmb(); /* drain writebuffer */ |
721 | 721 | ||
722 | au1550_spi_mask_ack_all(hw); | 722 | au1550_spi_mask_ack_all(hw); |
723 | 723 | ||
724 | hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; | 724 | hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; |
725 | au_sync(); | 725 | wmb(); /* drain writebuffer */ |
726 | 726 | ||
727 | do { | 727 | do { |
728 | stat = hw->regs->psc_spistat; | 728 | stat = hw->regs->psc_spistat; |
729 | au_sync(); | 729 | wmb(); /* drain writebuffer */ |
730 | } while ((stat & PSC_SPISTAT_DR) == 0); | 730 | } while ((stat & PSC_SPISTAT_DR) == 0); |
731 | 731 | ||
732 | au1550_spi_reset_fifos(hw); | 732 | au1550_spi_reset_fifos(hw); |
diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 372d4aea9d1c..0676746ec68c 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c | |||
@@ -41,6 +41,7 @@ | |||
41 | * with this program; if not, write to the Free Software Foundation, Inc., | 41 | * with this program; if not, write to the Free Software Foundation, Inc., |
42 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 42 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
43 | */ | 43 | */ |
44 | #include <linux/clk.h> | ||
44 | #include <linux/module.h> | 45 | #include <linux/module.h> |
45 | #include <linux/kernel.h> | 46 | #include <linux/kernel.h> |
46 | #include <linux/errno.h> | 47 | #include <linux/errno.h> |
@@ -113,7 +114,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) | |||
113 | case VESA_NO_BLANKING: | 114 | case VESA_NO_BLANKING: |
114 | /* Turn on panel */ | 115 | /* Turn on panel */ |
115 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; | 116 | fbdev->regs->lcd_control |= LCD_CONTROL_GO; |
116 | au_sync(); | 117 | wmb(); /* drain writebuffer */ |
117 | break; | 118 | break; |
118 | 119 | ||
119 | case VESA_VSYNC_SUSPEND: | 120 | case VESA_VSYNC_SUSPEND: |
@@ -121,7 +122,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) | |||
121 | case VESA_POWERDOWN: | 122 | case VESA_POWERDOWN: |
122 | /* Turn off panel */ | 123 | /* Turn off panel */ |
123 | fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; | 124 | fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; |
124 | au_sync(); | 125 | wmb(); /* drain writebuffer */ |
125 | break; | 126 | break; |
126 | default: | 127 | default: |
127 | break; | 128 | break; |
@@ -434,7 +435,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
434 | struct au1100fb_device *fbdev = NULL; | 435 | struct au1100fb_device *fbdev = NULL; |
435 | struct resource *regs_res; | 436 | struct resource *regs_res; |
436 | unsigned long page; | 437 | unsigned long page; |
437 | u32 sys_clksrc; | 438 | struct clk *c; |
438 | 439 | ||
439 | /* Allocate new device private */ | 440 | /* Allocate new device private */ |
440 | fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), | 441 | fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), |
@@ -473,6 +474,13 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
473 | print_dbg("Register memory map at %p", fbdev->regs); | 474 | print_dbg("Register memory map at %p", fbdev->regs); |
474 | print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); | 475 | print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); |
475 | 476 | ||
477 | c = clk_get(NULL, "lcd_intclk"); | ||
478 | if (!IS_ERR(c)) { | ||
479 | fbdev->lcdclk = c; | ||
480 | clk_set_rate(c, 48000000); | ||
481 | clk_prepare_enable(c); | ||
482 | } | ||
483 | |||
476 | /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */ | 484 | /* Allocate the framebuffer to the maximum screen size * nbr of video buffers */ |
477 | fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * | 485 | fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * |
478 | (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; | 486 | (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; |
@@ -506,10 +514,6 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
506 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); | 514 | print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); |
507 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); | 515 | print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); |
508 | 516 | ||
509 | /* Setup LCD clock to AUX (48 MHz) */ | ||
510 | sys_clksrc = au_readl(SYS_CLKSRC) & ~(SYS_CS_ML_MASK | SYS_CS_DL | SYS_CS_CL); | ||
511 | au_writel((sys_clksrc | (1 << SYS_CS_ML_BIT)), SYS_CLKSRC); | ||
512 | |||
513 | /* load the panel info into the var struct */ | 517 | /* load the panel info into the var struct */ |
514 | au1100fb_var.bits_per_pixel = fbdev->panel->bpp; | 518 | au1100fb_var.bits_per_pixel = fbdev->panel->bpp; |
515 | au1100fb_var.xres = fbdev->panel->xres; | 519 | au1100fb_var.xres = fbdev->panel->xres; |
@@ -546,6 +550,10 @@ static int au1100fb_drv_probe(struct platform_device *dev) | |||
546 | return 0; | 550 | return 0; |
547 | 551 | ||
548 | failed: | 552 | failed: |
553 | if (fbdev->lcdclk) { | ||
554 | clk_disable_unprepare(fbdev->lcdclk); | ||
555 | clk_put(fbdev->lcdclk); | ||
556 | } | ||
549 | if (fbdev->fb_mem) { | 557 | if (fbdev->fb_mem) { |
550 | dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, | 558 | dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, |
551 | fbdev->fb_phys); | 559 | fbdev->fb_phys); |
@@ -576,11 +584,15 @@ int au1100fb_drv_remove(struct platform_device *dev) | |||
576 | 584 | ||
577 | fb_dealloc_cmap(&fbdev->info.cmap); | 585 | fb_dealloc_cmap(&fbdev->info.cmap); |
578 | 586 | ||
587 | if (fbdev->lcdclk) { | ||
588 | clk_disable_unprepare(fbdev->lcdclk); | ||
589 | clk_put(fbdev->lcdclk); | ||
590 | } | ||
591 | |||
579 | return 0; | 592 | return 0; |
580 | } | 593 | } |
581 | 594 | ||
582 | #ifdef CONFIG_PM | 595 | #ifdef CONFIG_PM |
583 | static u32 sys_clksrc; | ||
584 | static struct au1100fb_regs fbregs; | 596 | static struct au1100fb_regs fbregs; |
585 | 597 | ||
586 | int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) | 598 | int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) |
@@ -590,14 +602,11 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) | |||
590 | if (!fbdev) | 602 | if (!fbdev) |
591 | return 0; | 603 | return 0; |
592 | 604 | ||
593 | /* Save the clock source state */ | ||
594 | sys_clksrc = au_readl(SYS_CLKSRC); | ||
595 | |||
596 | /* Blank the LCD */ | 605 | /* Blank the LCD */ |
597 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); | 606 | au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); |
598 | 607 | ||
599 | /* Stop LCD clocking */ | 608 | if (fbdev->lcdclk) |
600 | au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC); | 609 | clk_disable(fbdev->lcdclk); |
601 | 610 | ||
602 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); | 611 | memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); |
603 | 612 | ||
@@ -613,8 +622,8 @@ int au1100fb_drv_resume(struct platform_device *dev) | |||
613 | 622 | ||
614 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); | 623 | memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); |
615 | 624 | ||
616 | /* Restart LCD clocking */ | 625 | if (fbdev->lcdclk) |
617 | au_writel(sys_clksrc, SYS_CLKSRC); | 626 | clk_enable(fbdev->lcdclk); |
618 | 627 | ||
619 | /* Unblank the LCD */ | 628 | /* Unblank the LCD */ |
620 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); | 629 | au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); |
diff --git a/drivers/video/fbdev/au1100fb.h b/drivers/video/fbdev/au1100fb.h index 12d9642d5465..9af19939a9c6 100644 --- a/drivers/video/fbdev/au1100fb.h +++ b/drivers/video/fbdev/au1100fb.h | |||
@@ -109,6 +109,7 @@ struct au1100fb_device { | |||
109 | size_t fb_len; | 109 | size_t fb_len; |
110 | dma_addr_t fb_phys; | 110 | dma_addr_t fb_phys; |
111 | int panel_idx; | 111 | int panel_idx; |
112 | struct clk *lcdclk; | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | /********************************************************************/ | 115 | /********************************************************************/ |
diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 4cfba78a1458..40494dbdf519 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c | |||
@@ -30,6 +30,7 @@ | |||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 30 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | #include <linux/clk.h> | ||
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
34 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
35 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
@@ -330,9 +331,8 @@ struct panel_settings | |||
330 | uint32 mode_pwmhi; | 331 | uint32 mode_pwmhi; |
331 | uint32 mode_outmask; | 332 | uint32 mode_outmask; |
332 | uint32 mode_fifoctrl; | 333 | uint32 mode_fifoctrl; |
333 | uint32 mode_toyclksrc; | ||
334 | uint32 mode_backlight; | 334 | uint32 mode_backlight; |
335 | uint32 mode_auxpll; | 335 | uint32 lcdclk; |
336 | #define Xres min_xres | 336 | #define Xres min_xres |
337 | #define Yres min_yres | 337 | #define Yres min_yres |
338 | u32 min_xres; /* Minimum horizontal resolution */ | 338 | u32 min_xres; /* Minimum horizontal resolution */ |
@@ -379,9 +379,8 @@ static struct panel_settings known_lcd_panels[] = | |||
379 | .mode_pwmhi = 0x00000000, | 379 | .mode_pwmhi = 0x00000000, |
380 | .mode_outmask = 0x00FFFFFF, | 380 | .mode_outmask = 0x00FFFFFF, |
381 | .mode_fifoctrl = 0x2f2f2f2f, | 381 | .mode_fifoctrl = 0x2f2f2f2f, |
382 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
383 | .mode_backlight = 0x00000000, | 382 | .mode_backlight = 0x00000000, |
384 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 383 | .lcdclk = 96, |
385 | 320, 320, | 384 | 320, 320, |
386 | 240, 240, | 385 | 240, 240, |
387 | }, | 386 | }, |
@@ -407,9 +406,8 @@ static struct panel_settings known_lcd_panels[] = | |||
407 | .mode_pwmhi = 0x00000000, | 406 | .mode_pwmhi = 0x00000000, |
408 | .mode_outmask = 0x00FFFFFF, | 407 | .mode_outmask = 0x00FFFFFF, |
409 | .mode_fifoctrl = 0x2f2f2f2f, | 408 | .mode_fifoctrl = 0x2f2f2f2f, |
410 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
411 | .mode_backlight = 0x00000000, | 409 | .mode_backlight = 0x00000000, |
412 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 410 | .lcdclk = 96, |
413 | 640, 480, | 411 | 640, 480, |
414 | 640, 480, | 412 | 640, 480, |
415 | }, | 413 | }, |
@@ -435,9 +433,8 @@ static struct panel_settings known_lcd_panels[] = | |||
435 | .mode_pwmhi = 0x00000000, | 433 | .mode_pwmhi = 0x00000000, |
436 | .mode_outmask = 0x00FFFFFF, | 434 | .mode_outmask = 0x00FFFFFF, |
437 | .mode_fifoctrl = 0x2f2f2f2f, | 435 | .mode_fifoctrl = 0x2f2f2f2f, |
438 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
439 | .mode_backlight = 0x00000000, | 436 | .mode_backlight = 0x00000000, |
440 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 437 | .lcdclk = 96, |
441 | 800, 800, | 438 | 800, 800, |
442 | 600, 600, | 439 | 600, 600, |
443 | }, | 440 | }, |
@@ -463,9 +460,8 @@ static struct panel_settings known_lcd_panels[] = | |||
463 | .mode_pwmhi = 0x00000000, | 460 | .mode_pwmhi = 0x00000000, |
464 | .mode_outmask = 0x00FFFFFF, | 461 | .mode_outmask = 0x00FFFFFF, |
465 | .mode_fifoctrl = 0x2f2f2f2f, | 462 | .mode_fifoctrl = 0x2f2f2f2f, |
466 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
467 | .mode_backlight = 0x00000000, | 463 | .mode_backlight = 0x00000000, |
468 | .mode_auxpll = 6, /* 72MHz AUXPLL */ | 464 | .lcdclk = 72, |
469 | 1024, 1024, | 465 | 1024, 1024, |
470 | 768, 768, | 466 | 768, 768, |
471 | }, | 467 | }, |
@@ -491,9 +487,8 @@ static struct panel_settings known_lcd_panels[] = | |||
491 | .mode_pwmhi = 0x00000000, | 487 | .mode_pwmhi = 0x00000000, |
492 | .mode_outmask = 0x00FFFFFF, | 488 | .mode_outmask = 0x00FFFFFF, |
493 | .mode_fifoctrl = 0x2f2f2f2f, | 489 | .mode_fifoctrl = 0x2f2f2f2f, |
494 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
495 | .mode_backlight = 0x00000000, | 490 | .mode_backlight = 0x00000000, |
496 | .mode_auxpll = 10, /* 120MHz AUXPLL */ | 491 | .lcdclk = 120, |
497 | 1280, 1280, | 492 | 1280, 1280, |
498 | 1024, 1024, | 493 | 1024, 1024, |
499 | }, | 494 | }, |
@@ -519,9 +514,8 @@ static struct panel_settings known_lcd_panels[] = | |||
519 | .mode_pwmhi = 0x03400000, /* SCB 0x0 */ | 514 | .mode_pwmhi = 0x03400000, /* SCB 0x0 */ |
520 | .mode_outmask = 0x00FFFFFF, | 515 | .mode_outmask = 0x00FFFFFF, |
521 | .mode_fifoctrl = 0x2f2f2f2f, | 516 | .mode_fifoctrl = 0x2f2f2f2f, |
522 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
523 | .mode_backlight = 0x00000000, | 517 | .mode_backlight = 0x00000000, |
524 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 518 | .lcdclk = 96, |
525 | 1024, 1024, | 519 | 1024, 1024, |
526 | 768, 768, | 520 | 768, 768, |
527 | }, | 521 | }, |
@@ -550,9 +544,8 @@ static struct panel_settings known_lcd_panels[] = | |||
550 | .mode_pwmhi = 0x03400000, | 544 | .mode_pwmhi = 0x03400000, |
551 | .mode_outmask = 0x00fcfcfc, | 545 | .mode_outmask = 0x00fcfcfc, |
552 | .mode_fifoctrl = 0x2f2f2f2f, | 546 | .mode_fifoctrl = 0x2f2f2f2f, |
553 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
554 | .mode_backlight = 0x00000000, | 547 | .mode_backlight = 0x00000000, |
555 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 548 | .lcdclk = 96, |
556 | 640, 480, | 549 | 640, 480, |
557 | 640, 480, | 550 | 640, 480, |
558 | }, | 551 | }, |
@@ -581,9 +574,8 @@ static struct panel_settings known_lcd_panels[] = | |||
581 | .mode_pwmhi = 0x03400000, | 574 | .mode_pwmhi = 0x03400000, |
582 | .mode_outmask = 0x00fcfcfc, | 575 | .mode_outmask = 0x00fcfcfc, |
583 | .mode_fifoctrl = 0x2f2f2f2f, | 576 | .mode_fifoctrl = 0x2f2f2f2f, |
584 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
585 | .mode_backlight = 0x00000000, | 577 | .mode_backlight = 0x00000000, |
586 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 578 | .lcdclk = 96, /* 96MHz AUXPLL */ |
587 | 320, 320, | 579 | 320, 320, |
588 | 240, 240, | 580 | 240, 240, |
589 | }, | 581 | }, |
@@ -612,9 +604,8 @@ static struct panel_settings known_lcd_panels[] = | |||
612 | .mode_pwmhi = 0x03400000, | 604 | .mode_pwmhi = 0x03400000, |
613 | .mode_outmask = 0x00fcfcfc, | 605 | .mode_outmask = 0x00fcfcfc, |
614 | .mode_fifoctrl = 0x2f2f2f2f, | 606 | .mode_fifoctrl = 0x2f2f2f2f, |
615 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
616 | .mode_backlight = 0x00000000, | 607 | .mode_backlight = 0x00000000, |
617 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 608 | .lcdclk = 96, |
618 | 856, 856, | 609 | 856, 856, |
619 | 480, 480, | 610 | 480, 480, |
620 | }, | 611 | }, |
@@ -646,9 +637,8 @@ static struct panel_settings known_lcd_panels[] = | |||
646 | .mode_pwmhi = 0x00000000, | 637 | .mode_pwmhi = 0x00000000, |
647 | .mode_outmask = 0x00FFFFFF, | 638 | .mode_outmask = 0x00FFFFFF, |
648 | .mode_fifoctrl = 0x2f2f2f2f, | 639 | .mode_fifoctrl = 0x2f2f2f2f, |
649 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
650 | .mode_backlight = 0x00000000, | 640 | .mode_backlight = 0x00000000, |
651 | .mode_auxpll = (48/12) * 2, | 641 | .lcdclk = 96, |
652 | 800, 800, | 642 | 800, 800, |
653 | 480, 480, | 643 | 480, 480, |
654 | }, | 644 | }, |
@@ -764,7 +754,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, | |||
764 | 754 | ||
765 | /* Disable the window while making changes, then restore WINEN */ | 755 | /* Disable the window while making changes, then restore WINEN */ |
766 | winenable = lcd->winenable & (1 << plane); | 756 | winenable = lcd->winenable & (1 << plane); |
767 | au_sync(); | 757 | wmb(); /* drain writebuffer */ |
768 | lcd->winenable &= ~(1 << plane); | 758 | lcd->winenable &= ~(1 << plane); |
769 | lcd->window[plane].winctrl0 = winctrl0; | 759 | lcd->window[plane].winctrl0 = winctrl0; |
770 | lcd->window[plane].winctrl1 = winctrl1; | 760 | lcd->window[plane].winctrl1 = winctrl1; |
@@ -772,7 +762,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, | |||
772 | lcd->window[plane].winbuf1 = fbdev->fb_phys; | 762 | lcd->window[plane].winbuf1 = fbdev->fb_phys; |
773 | lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ | 763 | lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ |
774 | lcd->winenable |= winenable; | 764 | lcd->winenable |= winenable; |
775 | au_sync(); | 765 | wmb(); /* drain writebuffer */ |
776 | 766 | ||
777 | return 0; | 767 | return 0; |
778 | } | 768 | } |
@@ -788,22 +778,21 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
788 | /* Make sure all windows disabled */ | 778 | /* Make sure all windows disabled */ |
789 | winenable = lcd->winenable; | 779 | winenable = lcd->winenable; |
790 | lcd->winenable = 0; | 780 | lcd->winenable = 0; |
791 | au_sync(); | 781 | wmb(); /* drain writebuffer */ |
792 | /* | 782 | /* |
793 | * Ensure everything is disabled before reconfiguring | 783 | * Ensure everything is disabled before reconfiguring |
794 | */ | 784 | */ |
795 | if (lcd->screen & LCD_SCREEN_SEN) { | 785 | if (lcd->screen & LCD_SCREEN_SEN) { |
796 | /* Wait for vertical sync period */ | 786 | /* Wait for vertical sync period */ |
797 | lcd->intstatus = LCD_INT_SS; | 787 | lcd->intstatus = LCD_INT_SS; |
798 | while ((lcd->intstatus & LCD_INT_SS) == 0) { | 788 | while ((lcd->intstatus & LCD_INT_SS) == 0) |
799 | au_sync(); | 789 | ; |
800 | } | ||
801 | 790 | ||
802 | lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ | 791 | lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ |
803 | 792 | ||
804 | do { | 793 | do { |
805 | lcd->intstatus = lcd->intstatus; /*clear interrupts*/ | 794 | lcd->intstatus = lcd->intstatus; /*clear interrupts*/ |
806 | au_sync(); | 795 | wmb(); /* drain writebuffer */ |
807 | /*wait for controller to shut down*/ | 796 | /*wait for controller to shut down*/ |
808 | } while ((lcd->intstatus & LCD_INT_SD) == 0); | 797 | } while ((lcd->intstatus & LCD_INT_SD) == 0); |
809 | 798 | ||
@@ -829,11 +818,17 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
829 | */ | 818 | */ |
830 | if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) | 819 | if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) |
831 | { | 820 | { |
832 | uint32 sys_clksrc; | 821 | struct clk *c = clk_get(NULL, "lcd_intclk"); |
833 | au_writel(panel->mode_auxpll, SYS_AUXPLL); | 822 | long r, pc = panel->lcdclk * 1000000; |
834 | sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; | 823 | |
835 | sys_clksrc |= panel->mode_toyclksrc; | 824 | if (!IS_ERR(c)) { |
836 | au_writel(sys_clksrc, SYS_CLKSRC); | 825 | r = clk_round_rate(c, pc); |
826 | if ((pc - r) < (pc / 10)) { /* 10% slack */ | ||
827 | clk_set_rate(c, r); | ||
828 | clk_prepare_enable(c); | ||
829 | } | ||
830 | clk_put(c); | ||
831 | } | ||
837 | } | 832 | } |
838 | 833 | ||
839 | /* | 834 | /* |
@@ -847,7 +842,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
847 | lcd->pwmhi = panel->mode_pwmhi; | 842 | lcd->pwmhi = panel->mode_pwmhi; |
848 | lcd->outmask = panel->mode_outmask; | 843 | lcd->outmask = panel->mode_outmask; |
849 | lcd->fifoctrl = panel->mode_fifoctrl; | 844 | lcd->fifoctrl = panel->mode_fifoctrl; |
850 | au_sync(); | 845 | wmb(); /* drain writebuffer */ |
851 | 846 | ||
852 | /* fixme: Check window settings to make sure still valid | 847 | /* fixme: Check window settings to make sure still valid |
853 | * for new geometry */ | 848 | * for new geometry */ |
@@ -863,7 +858,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, | |||
863 | * Re-enable screen now that it is configured | 858 | * Re-enable screen now that it is configured |
864 | */ | 859 | */ |
865 | lcd->screen |= LCD_SCREEN_SEN; | 860 | lcd->screen |= LCD_SCREEN_SEN; |
866 | au_sync(); | 861 | wmb(); /* drain writebuffer */ |
867 | 862 | ||
868 | /* Call init of panel */ | 863 | /* Call init of panel */ |
869 | if (pd->panel_init) | 864 | if (pd->panel_init) |
@@ -956,7 +951,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) | |||
956 | | LCD_WINCTRL2_SCY_1 | 951 | | LCD_WINCTRL2_SCY_1 |
957 | ) ; | 952 | ) ; |
958 | lcd->winenable |= win->w[plane].mode_winenable; | 953 | lcd->winenable |= win->w[plane].mode_winenable; |
959 | au_sync(); | 954 | wmb(); /* drain writebuffer */ |
960 | } | 955 | } |
961 | 956 | ||
962 | 957 | ||
@@ -1270,7 +1265,7 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | |||
1270 | 1265 | ||
1271 | if (pdata->flags & SCREEN_MASK) | 1266 | if (pdata->flags & SCREEN_MASK) |
1272 | lcd->colorkeymsk = pdata->mask; | 1267 | lcd->colorkeymsk = pdata->mask; |
1273 | au_sync(); | 1268 | wmb(); /* drain writebuffer */ |
1274 | } | 1269 | } |
1275 | 1270 | ||
1276 | static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | 1271 | static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) |
@@ -1288,7 +1283,7 @@ static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) | |||
1288 | hi1 = (lcd->pwmhi >> 16) + 1; | 1283 | hi1 = (lcd->pwmhi >> 16) + 1; |
1289 | divider = (lcd->pwmdiv & 0x3FFFF) + 1; | 1284 | divider = (lcd->pwmdiv & 0x3FFFF) + 1; |
1290 | pdata->brightness = ((hi1 << 8) / divider) - 1; | 1285 | pdata->brightness = ((hi1 << 8) / divider) - 1; |
1291 | au_sync(); | 1286 | wmb(); /* drain writebuffer */ |
1292 | } | 1287 | } |
1293 | 1288 | ||
1294 | static void set_window(unsigned int plane, | 1289 | static void set_window(unsigned int plane, |
@@ -1387,7 +1382,7 @@ static void set_window(unsigned int plane, | |||
1387 | val |= (pdata->enable & 1) << plane; | 1382 | val |= (pdata->enable & 1) << plane; |
1388 | lcd->winenable = val; | 1383 | lcd->winenable = val; |
1389 | } | 1384 | } |
1390 | au_sync(); | 1385 | wmb(); /* drain writebuffer */ |
1391 | } | 1386 | } |
1392 | 1387 | ||
1393 | static void get_window(unsigned int plane, | 1388 | static void get_window(unsigned int plane, |
@@ -1414,7 +1409,7 @@ static void get_window(unsigned int plane, | |||
1414 | pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; | 1409 | pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; |
1415 | 1410 | ||
1416 | pdata->enable = (lcd->winenable >> plane) & 1; | 1411 | pdata->enable = (lcd->winenable >> plane) & 1; |
1417 | au_sync(); | 1412 | wmb(); /* drain writebuffer */ |
1418 | } | 1413 | } |
1419 | 1414 | ||
1420 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, | 1415 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, |
@@ -1511,7 +1506,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) | |||
1511 | { | 1506 | { |
1512 | /* Nothing to do for now, just clear any pending interrupt */ | 1507 | /* Nothing to do for now, just clear any pending interrupt */ |
1513 | lcd->intstatus = lcd->intstatus; | 1508 | lcd->intstatus = lcd->intstatus; |
1514 | au_sync(); | 1509 | wmb(); /* drain writebuffer */ |
1515 | 1510 | ||
1516 | return IRQ_HANDLED; | 1511 | return IRQ_HANDLED; |
1517 | } | 1512 | } |
@@ -1809,7 +1804,7 @@ static int au1200fb_drv_suspend(struct device *dev) | |||
1809 | au1200_setpanel(NULL, pd); | 1804 | au1200_setpanel(NULL, pd); |
1810 | 1805 | ||
1811 | lcd->outmask = 0; | 1806 | lcd->outmask = 0; |
1812 | au_sync(); | 1807 | wmb(); /* drain writebuffer */ |
1813 | 1808 | ||
1814 | return 0; | 1809 | return 0; |
1815 | } | 1810 | } |
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 4baf2d788920..8453531545df 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c | |||
@@ -145,35 +145,39 @@ static void __init octeon_wdt_build_stage1(void) | |||
145 | 145 | ||
146 | uasm_i_mfc0(&p, K0, C0_STATUS); | 146 | uasm_i_mfc0(&p, K0, C0_STATUS); |
147 | #ifdef CONFIG_HOTPLUG_CPU | 147 | #ifdef CONFIG_HOTPLUG_CPU |
148 | uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), label_enter_bootloader); | 148 | if (octeon_bootloader_entry_addr) |
149 | uasm_il_bbit0(&p, &r, K0, ilog2(ST0_NMI), | ||
150 | label_enter_bootloader); | ||
149 | #endif | 151 | #endif |
150 | /* Force 64-bit addressing enabled */ | 152 | /* Force 64-bit addressing enabled */ |
151 | uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); | 153 | uasm_i_ori(&p, K0, K0, ST0_UX | ST0_SX | ST0_KX); |
152 | uasm_i_mtc0(&p, K0, C0_STATUS); | 154 | uasm_i_mtc0(&p, K0, C0_STATUS); |
153 | 155 | ||
154 | #ifdef CONFIG_HOTPLUG_CPU | 156 | #ifdef CONFIG_HOTPLUG_CPU |
155 | uasm_i_mfc0(&p, K0, C0_EBASE); | 157 | if (octeon_bootloader_entry_addr) { |
156 | /* Coreid number in K0 */ | 158 | uasm_i_mfc0(&p, K0, C0_EBASE); |
157 | uasm_i_andi(&p, K0, K0, 0xf); | 159 | /* Coreid number in K0 */ |
158 | /* 8 * coreid in bits 16-31 */ | 160 | uasm_i_andi(&p, K0, K0, 0xf); |
159 | uasm_i_dsll_safe(&p, K0, K0, 3 + 16); | 161 | /* 8 * coreid in bits 16-31 */ |
160 | uasm_i_ori(&p, K0, K0, 0x8001); | 162 | uasm_i_dsll_safe(&p, K0, K0, 3 + 16); |
161 | uasm_i_dsll_safe(&p, K0, K0, 16); | 163 | uasm_i_ori(&p, K0, K0, 0x8001); |
162 | uasm_i_ori(&p, K0, K0, 0x0700); | 164 | uasm_i_dsll_safe(&p, K0, K0, 16); |
163 | uasm_i_drotr_safe(&p, K0, K0, 32); | 165 | uasm_i_ori(&p, K0, K0, 0x0700); |
164 | /* | 166 | uasm_i_drotr_safe(&p, K0, K0, 32); |
165 | * Should result in: 0x8001,0700,0000,8*coreid which is | 167 | /* |
166 | * CVMX_CIU_WDOGX(coreid) - 0x0500 | 168 | * Should result in: 0x8001,0700,0000,8*coreid which is |
167 | * | 169 | * CVMX_CIU_WDOGX(coreid) - 0x0500 |
168 | * Now ld K0, CVMX_CIU_WDOGX(coreid) | 170 | * |
169 | */ | 171 | * Now ld K0, CVMX_CIU_WDOGX(coreid) |
170 | uasm_i_ld(&p, K0, 0x500, K0); | 172 | */ |
171 | /* | 173 | uasm_i_ld(&p, K0, 0x500, K0); |
172 | * If bit one set handle the NMI as a watchdog event. | 174 | /* |
173 | * otherwise transfer control to bootloader. | 175 | * If bit one set handle the NMI as a watchdog event. |
174 | */ | 176 | * otherwise transfer control to bootloader. |
175 | uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); | 177 | */ |
176 | uasm_i_nop(&p); | 178 | uasm_il_bbit0(&p, &r, K0, 1, label_enter_bootloader); |
179 | uasm_i_nop(&p); | ||
180 | } | ||
177 | #endif | 181 | #endif |
178 | 182 | ||
179 | /* Clear Dcache so cvmseg works right. */ | 183 | /* Clear Dcache so cvmseg works right. */ |
@@ -194,11 +198,13 @@ static void __init octeon_wdt_build_stage1(void) | |||
194 | uasm_i_dmfc0(&p, K0, C0_DESAVE); | 198 | uasm_i_dmfc0(&p, K0, C0_DESAVE); |
195 | 199 | ||
196 | #ifdef CONFIG_HOTPLUG_CPU | 200 | #ifdef CONFIG_HOTPLUG_CPU |
197 | uasm_build_label(&l, p, label_enter_bootloader); | 201 | if (octeon_bootloader_entry_addr) { |
198 | /* Jump to the bootloader and restore K0 */ | 202 | uasm_build_label(&l, p, label_enter_bootloader); |
199 | UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); | 203 | /* Jump to the bootloader and restore K0 */ |
200 | uasm_i_jr(&p, K0); | 204 | UASM_i_LA(&p, K0, (long)octeon_bootloader_entry_addr); |
201 | uasm_i_dmfc0(&p, K0, C0_DESAVE); | 205 | uasm_i_jr(&p, K0); |
206 | uasm_i_dmfc0(&p, K0, C0_DESAVE); | ||
207 | } | ||
202 | #endif | 208 | #endif |
203 | uasm_resolve_relocs(relocs, labels); | 209 | uasm_resolve_relocs(relocs, labels); |
204 | 210 | ||