diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/busses/Kconfig | 4 | ||||
-rw-r--r-- | drivers/mmc/host/au1xmmc.c | 45 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 298 | ||||
-rw-r--r-- | drivers/net/irda/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/irda/au1000_ircc.h | 125 | ||||
-rw-r--r-- | drivers/net/irda/au1k_ir.c | 1229 | ||||
-rw-r--r-- | drivers/pcmcia/Kconfig | 8 | ||||
-rw-r--r-- | drivers/pcmcia/Makefile | 4 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_generic.c | 545 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_generic.h | 135 | ||||
-rw-r--r-- | drivers/pcmcia/au1000_pb1x00.c | 294 | ||||
-rw-r--r-- | drivers/pcmcia/db1xxx_ss.c | 26 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 4 | ||||
-rw-r--r-- | drivers/tty/serial/Kconfig | 23 | ||||
-rw-r--r-- | drivers/tty/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/tty/serial/ar933x_uart.c | 688 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/host/alchemy-common.c | 277 | ||||
-rw-r--r-- | drivers/usb/host/ehci-ath79.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ohci-au1xxx.c | 13 | ||||
-rw-r--r-- | drivers/video/Kconfig | 8 | ||||
-rw-r--r-- | drivers/video/au1100fb.c | 12 | ||||
-rw-r--r-- | drivers/video/au1200fb.c | 273 | ||||
-rw-r--r-- | drivers/video/console/newport_con.c | 63 |
24 files changed, 2060 insertions, 2027 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a3afac4be734..cbe7a2fb779f 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -299,11 +299,11 @@ config I2C_AT91 | |||
299 | unless your system can cope with those limitations. | 299 | unless your system can cope with those limitations. |
300 | 300 | ||
301 | config I2C_AU1550 | 301 | config I2C_AU1550 |
302 | tristate "Au1550/Au1200 SMBus interface" | 302 | tristate "Au1550/Au1200/Au1300 SMBus interface" |
303 | depends on MIPS_ALCHEMY | 303 | depends on MIPS_ALCHEMY |
304 | help | 304 | help |
305 | If you say yes to this option, support will be included for the | 305 | If you say yes to this option, support will be included for the |
306 | Au1550 and Au1200 SMBus interface. | 306 | Au1550/Au1200/Au1300 SMBus interface. |
307 | 307 | ||
308 | This driver can also be built as a module. If so, the module | 308 | This driver can also be built as a module. If so, the module |
309 | will be called i2c-au1550. | 309 | will be called i2c-au1550. |
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 5d3b9ae64523..dbd0c8a4e98a 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c | |||
@@ -153,6 +153,7 @@ static inline int has_dbdma(void) | |||
153 | { | 153 | { |
154 | switch (alchemy_get_cputype()) { | 154 | switch (alchemy_get_cputype()) { |
155 | case ALCHEMY_CPU_AU1200: | 155 | case ALCHEMY_CPU_AU1200: |
156 | case ALCHEMY_CPU_AU1300: | ||
156 | return 1; | 157 | return 1; |
157 | default: | 158 | default: |
158 | return 0; | 159 | return 0; |
@@ -768,11 +769,15 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
768 | 769 | ||
769 | config2 = au_readl(HOST_CONFIG2(host)); | 770 | config2 = au_readl(HOST_CONFIG2(host)); |
770 | switch (ios->bus_width) { | 771 | switch (ios->bus_width) { |
772 | case MMC_BUS_WIDTH_8: | ||
773 | config2 |= SD_CONFIG2_BB; | ||
774 | break; | ||
771 | case MMC_BUS_WIDTH_4: | 775 | case MMC_BUS_WIDTH_4: |
776 | config2 &= ~SD_CONFIG2_BB; | ||
772 | config2 |= SD_CONFIG2_WB; | 777 | config2 |= SD_CONFIG2_WB; |
773 | break; | 778 | break; |
774 | case MMC_BUS_WIDTH_1: | 779 | case MMC_BUS_WIDTH_1: |
775 | config2 &= ~SD_CONFIG2_WB; | 780 | config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); |
776 | break; | 781 | break; |
777 | } | 782 | } |
778 | au_writel(config2, HOST_CONFIG2(host)); | 783 | au_writel(config2, HOST_CONFIG2(host)); |
@@ -943,7 +948,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
943 | struct mmc_host *mmc; | 948 | struct mmc_host *mmc; |
944 | struct au1xmmc_host *host; | 949 | struct au1xmmc_host *host; |
945 | struct resource *r; | 950 | struct resource *r; |
946 | int ret; | 951 | int ret, iflag; |
947 | 952 | ||
948 | mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); | 953 | mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev); |
949 | if (!mmc) { | 954 | if (!mmc) { |
@@ -982,37 +987,43 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev) | |||
982 | dev_err(&pdev->dev, "no IRQ defined\n"); | 987 | dev_err(&pdev->dev, "no IRQ defined\n"); |
983 | goto out3; | 988 | goto out3; |
984 | } | 989 | } |
985 | |||
986 | host->irq = r->start; | 990 | host->irq = r->start; |
987 | /* IRQ is shared among both SD controllers */ | ||
988 | ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED, | ||
989 | DRIVER_NAME, host); | ||
990 | if (ret) { | ||
991 | dev_err(&pdev->dev, "cannot grab IRQ\n"); | ||
992 | goto out3; | ||
993 | } | ||
994 | 991 | ||
995 | mmc->ops = &au1xmmc_ops; | 992 | mmc->ops = &au1xmmc_ops; |
996 | 993 | ||
997 | mmc->f_min = 450000; | 994 | mmc->f_min = 450000; |
998 | mmc->f_max = 24000000; | 995 | mmc->f_max = 24000000; |
999 | 996 | ||
997 | mmc->max_blk_size = 2048; | ||
998 | mmc->max_blk_count = 512; | ||
999 | |||
1000 | mmc->ocr_avail = AU1XMMC_OCR; | ||
1001 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | ||
1002 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | ||
1003 | |||
1004 | iflag = IRQF_SHARED; /* Au1100/Au1200: one int for both ctrls */ | ||
1005 | |||
1000 | switch (alchemy_get_cputype()) { | 1006 | switch (alchemy_get_cputype()) { |
1001 | case ALCHEMY_CPU_AU1100: | 1007 | case ALCHEMY_CPU_AU1100: |
1002 | mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE; | 1008 | mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE; |
1003 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | ||
1004 | break; | 1009 | break; |
1005 | case ALCHEMY_CPU_AU1200: | 1010 | case ALCHEMY_CPU_AU1200: |
1006 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; | 1011 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; |
1007 | mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; | 1012 | break; |
1013 | case ALCHEMY_CPU_AU1300: | ||
1014 | iflag = 0; /* nothing is shared */ | ||
1015 | mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE; | ||
1016 | mmc->f_max = 52000000; | ||
1017 | if (host->ioarea->start == AU1100_SD0_PHYS_ADDR) | ||
1018 | mmc->caps |= MMC_CAP_8_BIT_DATA; | ||
1008 | break; | 1019 | break; |
1009 | } | 1020 | } |
1010 | 1021 | ||
1011 | mmc->max_blk_size = 2048; | 1022 | ret = request_irq(host->irq, au1xmmc_irq, iflag, DRIVER_NAME, host); |
1012 | mmc->max_blk_count = 512; | 1023 | if (ret) { |
1013 | 1024 | dev_err(&pdev->dev, "cannot grab IRQ\n"); | |
1014 | mmc->ocr_avail = AU1XMMC_OCR; | 1025 | goto out3; |
1015 | mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ; | 1026 | } |
1016 | 1027 | ||
1017 | host->status = HOST_S_IDLE; | 1028 | host->status = HOST_S_IDLE; |
1018 | 1029 | ||
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 7dd3700f2303..73abbc3e093e 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -17,35 +17,19 @@ | |||
17 | #include <linux/mtd/mtd.h> | 17 | #include <linux/mtd/mtd.h> |
18 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/platform_device.h> | ||
20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <asm/mach-au1x00/au1000.h> | ||
23 | #include <asm/mach-au1x00/au1550nd.h> | ||
21 | 24 | ||
22 | #ifdef CONFIG_MIPS_PB1550 | ||
23 | #include <asm/mach-pb1x00/pb1550.h> | ||
24 | #elif defined(CONFIG_MIPS_DB1550) | ||
25 | #include <asm/mach-db1x00/db1x00.h> | ||
26 | #endif | ||
27 | #include <asm/mach-db1x00/bcsr.h> | ||
28 | 25 | ||
29 | /* | 26 | struct au1550nd_ctx { |
30 | * MTD structure for NAND controller | 27 | struct mtd_info info; |
31 | */ | 28 | struct nand_chip chip; |
32 | static struct mtd_info *au1550_mtd = NULL; | ||
33 | static void __iomem *p_nand; | ||
34 | static int nand_width = 1; /* default x8 */ | ||
35 | static void (*au1550_write_byte)(struct mtd_info *, u_char); | ||
36 | 29 | ||
37 | /* | 30 | int cs; |
38 | * Define partitions for flash device | 31 | void __iomem *base; |
39 | */ | 32 | void (*write_byte)(struct mtd_info *, u_char); |
40 | static const struct mtd_partition partition_info[] = { | ||
41 | { | ||
42 | .name = "NAND FS 0", | ||
43 | .offset = 0, | ||
44 | .size = 8 * 1024 * 1024}, | ||
45 | { | ||
46 | .name = "NAND FS 1", | ||
47 | .offset = MTDPART_OFS_APPEND, | ||
48 | .size = MTDPART_SIZ_FULL} | ||
49 | }; | 33 | }; |
50 | 34 | ||
51 | /** | 35 | /** |
@@ -259,24 +243,25 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
259 | 243 | ||
260 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | 244 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) |
261 | { | 245 | { |
262 | register struct nand_chip *this = mtd->priv; | 246 | struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); |
247 | struct nand_chip *this = mtd->priv; | ||
263 | 248 | ||
264 | switch (cmd) { | 249 | switch (cmd) { |
265 | 250 | ||
266 | case NAND_CTL_SETCLE: | 251 | case NAND_CTL_SETCLE: |
267 | this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; | 252 | this->IO_ADDR_W = ctx->base + MEM_STNAND_CMD; |
268 | break; | 253 | break; |
269 | 254 | ||
270 | case NAND_CTL_CLRCLE: | 255 | case NAND_CTL_CLRCLE: |
271 | this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; | 256 | this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA; |
272 | break; | 257 | break; |
273 | 258 | ||
274 | case NAND_CTL_SETALE: | 259 | case NAND_CTL_SETALE: |
275 | this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; | 260 | this->IO_ADDR_W = ctx->base + MEM_STNAND_ADDR; |
276 | break; | 261 | break; |
277 | 262 | ||
278 | case NAND_CTL_CLRALE: | 263 | case NAND_CTL_CLRALE: |
279 | this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; | 264 | this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA; |
280 | /* FIXME: Nobody knows why this is necessary, | 265 | /* FIXME: Nobody knows why this is necessary, |
281 | * but it works only that way */ | 266 | * but it works only that way */ |
282 | udelay(1); | 267 | udelay(1); |
@@ -284,7 +269,7 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | |||
284 | 269 | ||
285 | case NAND_CTL_SETNCE: | 270 | case NAND_CTL_SETNCE: |
286 | /* assert (force assert) chip enable */ | 271 | /* assert (force assert) chip enable */ |
287 | au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL); | 272 | au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL); |
288 | break; | 273 | break; |
289 | 274 | ||
290 | case NAND_CTL_CLRNCE: | 275 | case NAND_CTL_CLRNCE: |
@@ -331,9 +316,10 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip) | |||
331 | */ | 316 | */ |
332 | static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 317 | static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) |
333 | { | 318 | { |
334 | register struct nand_chip *this = mtd->priv; | 319 | struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); |
320 | struct nand_chip *this = mtd->priv; | ||
335 | int ce_override = 0, i; | 321 | int ce_override = 0, i; |
336 | ulong flags; | 322 | unsigned long flags = 0; |
337 | 323 | ||
338 | /* Begin command latch cycle */ | 324 | /* Begin command latch cycle */ |
339 | au1550_hwcontrol(mtd, NAND_CTL_SETCLE); | 325 | au1550_hwcontrol(mtd, NAND_CTL_SETCLE); |
@@ -354,9 +340,9 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
354 | column -= 256; | 340 | column -= 256; |
355 | readcmd = NAND_CMD_READ1; | 341 | readcmd = NAND_CMD_READ1; |
356 | } | 342 | } |
357 | au1550_write_byte(mtd, readcmd); | 343 | ctx->write_byte(mtd, readcmd); |
358 | } | 344 | } |
359 | au1550_write_byte(mtd, command); | 345 | ctx->write_byte(mtd, command); |
360 | 346 | ||
361 | /* Set ALE and clear CLE to start address cycle */ | 347 | /* Set ALE and clear CLE to start address cycle */ |
362 | au1550_hwcontrol(mtd, NAND_CTL_CLRCLE); | 348 | au1550_hwcontrol(mtd, NAND_CTL_CLRCLE); |
@@ -369,10 +355,10 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
369 | /* Adjust columns for 16 bit buswidth */ | 355 | /* Adjust columns for 16 bit buswidth */ |
370 | if (this->options & NAND_BUSWIDTH_16) | 356 | if (this->options & NAND_BUSWIDTH_16) |
371 | column >>= 1; | 357 | column >>= 1; |
372 | au1550_write_byte(mtd, column); | 358 | ctx->write_byte(mtd, column); |
373 | } | 359 | } |
374 | if (page_addr != -1) { | 360 | if (page_addr != -1) { |
375 | au1550_write_byte(mtd, (u8)(page_addr & 0xff)); | 361 | ctx->write_byte(mtd, (u8)(page_addr & 0xff)); |
376 | 362 | ||
377 | if (command == NAND_CMD_READ0 || | 363 | if (command == NAND_CMD_READ0 || |
378 | command == NAND_CMD_READ1 || | 364 | command == NAND_CMD_READ1 || |
@@ -390,11 +376,12 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
390 | au1550_hwcontrol(mtd, NAND_CTL_SETNCE); | 376 | au1550_hwcontrol(mtd, NAND_CTL_SETNCE); |
391 | } | 377 | } |
392 | 378 | ||
393 | au1550_write_byte(mtd, (u8)(page_addr >> 8)); | 379 | ctx->write_byte(mtd, (u8)(page_addr >> 8)); |
394 | 380 | ||
395 | /* One more address cycle for devices > 32MiB */ | 381 | /* One more address cycle for devices > 32MiB */ |
396 | if (this->chipsize > (32 << 20)) | 382 | if (this->chipsize > (32 << 20)) |
397 | au1550_write_byte(mtd, (u8)((page_addr >> 16) & 0x0f)); | 383 | ctx->write_byte(mtd, |
384 | ((page_addr >> 16) & 0x0f)); | ||
398 | } | 385 | } |
399 | /* Latch in address */ | 386 | /* Latch in address */ |
400 | au1550_hwcontrol(mtd, NAND_CTL_CLRALE); | 387 | au1550_hwcontrol(mtd, NAND_CTL_CLRALE); |
@@ -440,121 +427,79 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
440 | while(!this->dev_ready(mtd)); | 427 | while(!this->dev_ready(mtd)); |
441 | } | 428 | } |
442 | 429 | ||
443 | 430 | static int __devinit find_nand_cs(unsigned long nand_base) | |
444 | /* | ||
445 | * Main initialization routine | ||
446 | */ | ||
447 | static int __init au1xxx_nand_init(void) | ||
448 | { | 431 | { |
449 | struct nand_chip *this; | 432 | void __iomem *base = |
450 | u16 boot_swapboot = 0; /* default value */ | 433 | (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); |
451 | int retval; | 434 | unsigned long addr, staddr, start, mask, end; |
452 | u32 mem_staddr; | 435 | int i; |
453 | u32 nand_phys; | ||
454 | |||
455 | /* Allocate memory for MTD device structure and private data */ | ||
456 | au1550_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
457 | if (!au1550_mtd) { | ||
458 | printk("Unable to allocate NAND MTD dev structure.\n"); | ||
459 | return -ENOMEM; | ||
460 | } | ||
461 | |||
462 | /* Get pointer to private data */ | ||
463 | this = (struct nand_chip *)(&au1550_mtd[1]); | ||
464 | |||
465 | /* Link the private data with the MTD structure */ | ||
466 | au1550_mtd->priv = this; | ||
467 | au1550_mtd->owner = THIS_MODULE; | ||
468 | |||
469 | 436 | ||
470 | /* MEM_STNDCTL: disable ints, disable nand boot */ | 437 | for (i = 0; i < 4; i++) { |
471 | au_writel(0, MEM_STNDCTL); | 438 | addr = 0x1000 + (i * 0x10); /* CSx */ |
439 | staddr = __raw_readl(base + addr + 0x08); /* STADDRx */ | ||
440 | /* figure out the decoded range of this CS */ | ||
441 | start = (staddr << 4) & 0xfffc0000; | ||
442 | mask = (staddr << 18) & 0xfffc0000; | ||
443 | end = (start | (start - 1)) & ~(start ^ mask); | ||
444 | if ((nand_base >= start) && (nand_base < end)) | ||
445 | return i; | ||
446 | } | ||
472 | 447 | ||
473 | #ifdef CONFIG_MIPS_PB1550 | 448 | return -ENODEV; |
474 | /* set gpio206 high */ | 449 | } |
475 | gpio_direction_input(206); | ||
476 | 450 | ||
477 | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); | 451 | static int __devinit au1550nd_probe(struct platform_device *pdev) |
452 | { | ||
453 | struct au1550nd_platdata *pd; | ||
454 | struct au1550nd_ctx *ctx; | ||
455 | struct nand_chip *this; | ||
456 | struct resource *r; | ||
457 | int ret, cs; | ||
478 | 458 | ||
479 | switch (boot_swapboot) { | 459 | pd = pdev->dev.platform_data; |
480 | case 0: | 460 | if (!pd) { |
481 | case 2: | 461 | dev_err(&pdev->dev, "missing platform data\n"); |
482 | case 8: | 462 | return -ENODEV; |
483 | case 0xC: | ||
484 | case 0xD: | ||
485 | /* x16 NAND Flash */ | ||
486 | nand_width = 0; | ||
487 | break; | ||
488 | case 1: | ||
489 | case 9: | ||
490 | case 3: | ||
491 | case 0xE: | ||
492 | case 0xF: | ||
493 | /* x8 NAND Flash */ | ||
494 | nand_width = 1; | ||
495 | break; | ||
496 | default: | ||
497 | printk("Pb1550 NAND: bad boot:swap\n"); | ||
498 | retval = -EINVAL; | ||
499 | goto outmem; | ||
500 | } | 463 | } |
501 | #endif | 464 | |
502 | 465 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | |
503 | /* Configure chip-select; normally done by boot code, e.g. YAMON */ | 466 | if (!ctx) { |
504 | #ifdef NAND_STCFG | 467 | dev_err(&pdev->dev, "no memory for NAND context\n"); |
505 | if (NAND_CS == 0) { | 468 | return -ENOMEM; |
506 | au_writel(NAND_STCFG, MEM_STCFG0); | ||
507 | au_writel(NAND_STTIME, MEM_STTIME0); | ||
508 | au_writel(NAND_STADDR, MEM_STADDR0); | ||
509 | } | ||
510 | if (NAND_CS == 1) { | ||
511 | au_writel(NAND_STCFG, MEM_STCFG1); | ||
512 | au_writel(NAND_STTIME, MEM_STTIME1); | ||
513 | au_writel(NAND_STADDR, MEM_STADDR1); | ||
514 | } | 469 | } |
515 | if (NAND_CS == 2) { | 470 | |
516 | au_writel(NAND_STCFG, MEM_STCFG2); | 471 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
517 | au_writel(NAND_STTIME, MEM_STTIME2); | 472 | if (!r) { |
518 | au_writel(NAND_STADDR, MEM_STADDR2); | 473 | dev_err(&pdev->dev, "no NAND memory resource\n"); |
474 | ret = -ENODEV; | ||
475 | goto out1; | ||
519 | } | 476 | } |
520 | if (NAND_CS == 3) { | 477 | if (request_mem_region(r->start, resource_size(r), "au1550-nand")) { |
521 | au_writel(NAND_STCFG, MEM_STCFG3); | 478 | dev_err(&pdev->dev, "cannot claim NAND memory area\n"); |
522 | au_writel(NAND_STTIME, MEM_STTIME3); | 479 | ret = -ENOMEM; |
523 | au_writel(NAND_STADDR, MEM_STADDR3); | 480 | goto out1; |
524 | } | 481 | } |
525 | #endif | 482 | |
526 | 483 | ctx->base = ioremap_nocache(r->start, 0x1000); | |
527 | /* Locate NAND chip-select in order to determine NAND phys address */ | 484 | if (!ctx->base) { |
528 | mem_staddr = 0x00000000; | 485 | dev_err(&pdev->dev, "cannot remap NAND memory area\n"); |
529 | if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0)) | 486 | ret = -ENODEV; |
530 | mem_staddr = au_readl(MEM_STADDR0); | 487 | goto out2; |
531 | else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1)) | ||
532 | mem_staddr = au_readl(MEM_STADDR1); | ||
533 | else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2)) | ||
534 | mem_staddr = au_readl(MEM_STADDR2); | ||
535 | else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3)) | ||
536 | mem_staddr = au_readl(MEM_STADDR3); | ||
537 | |||
538 | if (mem_staddr == 0x00000000) { | ||
539 | printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n"); | ||
540 | kfree(au1550_mtd); | ||
541 | return 1; | ||
542 | } | 488 | } |
543 | nand_phys = (mem_staddr << 4) & 0xFFFC0000; | ||
544 | 489 | ||
545 | p_nand = ioremap(nand_phys, 0x1000); | 490 | this = &ctx->chip; |
491 | ctx->info.priv = this; | ||
492 | ctx->info.owner = THIS_MODULE; | ||
546 | 493 | ||
547 | /* make controller and MTD agree */ | 494 | /* figure out which CS# r->start belongs to */ |
548 | if (NAND_CS == 0) | 495 | cs = find_nand_cs(r->start); |
549 | nand_width = au_readl(MEM_STCFG0) & (1 << 22); | 496 | if (cs < 0) { |
550 | if (NAND_CS == 1) | 497 | dev_err(&pdev->dev, "cannot detect NAND chipselect\n"); |
551 | nand_width = au_readl(MEM_STCFG1) & (1 << 22); | 498 | ret = -ENODEV; |
552 | if (NAND_CS == 2) | 499 | goto out3; |
553 | nand_width = au_readl(MEM_STCFG2) & (1 << 22); | 500 | } |
554 | if (NAND_CS == 3) | 501 | ctx->cs = cs; |
555 | nand_width = au_readl(MEM_STCFG3) & (1 << 22); | ||
556 | 502 | ||
557 | /* Set address of hardware control function */ | ||
558 | this->dev_ready = au1550_device_ready; | 503 | this->dev_ready = au1550_device_ready; |
559 | this->select_chip = au1550_select_chip; | 504 | this->select_chip = au1550_select_chip; |
560 | this->cmdfunc = au1550_command; | 505 | this->cmdfunc = au1550_command; |
@@ -565,54 +510,57 @@ static int __init au1xxx_nand_init(void) | |||
565 | 510 | ||
566 | this->options = NAND_NO_AUTOINCR; | 511 | this->options = NAND_NO_AUTOINCR; |
567 | 512 | ||
568 | if (!nand_width) | 513 | if (pd->devwidth) |
569 | this->options |= NAND_BUSWIDTH_16; | 514 | this->options |= NAND_BUSWIDTH_16; |
570 | 515 | ||
571 | this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte; | 516 | this->read_byte = (pd->devwidth) ? au_read_byte16 : au_read_byte; |
572 | au1550_write_byte = (!nand_width) ? au_write_byte16 : au_write_byte; | 517 | ctx->write_byte = (pd->devwidth) ? au_write_byte16 : au_write_byte; |
573 | this->read_word = au_read_word; | 518 | this->read_word = au_read_word; |
574 | this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf; | 519 | this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf; |
575 | this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf; | 520 | this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf; |
576 | this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf; | 521 | this->verify_buf = (pd->devwidth) ? au_verify_buf16 : au_verify_buf; |
577 | 522 | ||
578 | /* Scan to find existence of the device */ | 523 | ret = nand_scan(&ctx->info, 1); |
579 | if (nand_scan(au1550_mtd, 1)) { | 524 | if (ret) { |
580 | retval = -ENXIO; | 525 | dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); |
581 | goto outio; | 526 | goto out3; |
582 | } | 527 | } |
583 | 528 | ||
584 | /* Register the partitions */ | 529 | mtd_device_register(&ctx->info, pd->parts, pd->num_parts); |
585 | mtd_device_register(au1550_mtd, partition_info, | ||
586 | ARRAY_SIZE(partition_info)); | ||
587 | 530 | ||
588 | return 0; | 531 | return 0; |
589 | 532 | ||
590 | outio: | 533 | out3: |
591 | iounmap(p_nand); | 534 | iounmap(ctx->base); |
592 | 535 | out2: | |
593 | outmem: | 536 | release_mem_region(r->start, resource_size(r)); |
594 | kfree(au1550_mtd); | 537 | out1: |
595 | return retval; | 538 | kfree(ctx); |
539 | return ret; | ||
596 | } | 540 | } |
597 | 541 | ||
598 | module_init(au1xxx_nand_init); | 542 | static int __devexit au1550nd_remove(struct platform_device *pdev) |
599 | |||
600 | /* | ||
601 | * Clean up routine | ||
602 | */ | ||
603 | static void __exit au1550_cleanup(void) | ||
604 | { | 543 | { |
605 | /* Release resources, unregister device */ | 544 | struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); |
606 | nand_release(au1550_mtd); | 545 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
607 | 546 | ||
608 | /* Free the MTD device structure */ | 547 | nand_release(&ctx->info); |
609 | kfree(au1550_mtd); | 548 | iounmap(ctx->base); |
610 | 549 | release_mem_region(r->start, 0x1000); | |
611 | /* Unmap */ | 550 | kfree(ctx); |
612 | iounmap(p_nand); | 551 | return 0; |
613 | } | 552 | } |
614 | 553 | ||
615 | module_exit(au1550_cleanup); | 554 | static struct platform_driver au1550nd_driver = { |
555 | .driver = { | ||
556 | .name = "au1550-nand", | ||
557 | .owner = THIS_MODULE, | ||
558 | }, | ||
559 | .probe = au1550nd_probe, | ||
560 | .remove = __devexit_p(au1550nd_remove), | ||
561 | }; | ||
562 | |||
563 | module_platform_driver(au1550nd_driver); | ||
616 | 564 | ||
617 | MODULE_LICENSE("GPL"); | 565 | MODULE_LICENSE("GPL"); |
618 | MODULE_AUTHOR("Embedded Edge, LLC"); | 566 | MODULE_AUTHOR("Embedded Edge, LLC"); |
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index d423d18b4ad6..e535137eb2d0 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig | |||
@@ -313,8 +313,12 @@ config TOSHIBA_FIR | |||
313 | donauboe. | 313 | donauboe. |
314 | 314 | ||
315 | config AU1000_FIR | 315 | config AU1000_FIR |
316 | tristate "Alchemy Au1000 SIR/FIR" | 316 | tristate "Alchemy IrDA SIR/FIR" |
317 | depends on IRDA && MIPS_ALCHEMY | 317 | depends on IRDA && MIPS_ALCHEMY |
318 | help | ||
319 | Say Y/M here to build suppor the the IrDA peripheral on the | ||
320 | Alchemy Au1000 and Au1100 SoCs. | ||
321 | Say M to build a module; it will be called au1k_ir.ko | ||
318 | 322 | ||
319 | config SMC_IRCC_FIR | 323 | config SMC_IRCC_FIR |
320 | tristate "SMSC IrCC (EXPERIMENTAL)" | 324 | tristate "SMSC IrCC (EXPERIMENTAL)" |
diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h deleted file mode 100644 index c072c09a8d91..000000000000 --- a/drivers/net/irda/au1000_ircc.h +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * Au1000 IrDA driver. | ||
5 | * | ||
6 | * Copyright 2001 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. | ||
8 | * ppopov@mvista.com or source@mvista.com | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
16 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
18 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
21 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #ifndef AU1000_IRCC_H | ||
32 | #define AU1000_IRCC_H | ||
33 | |||
34 | #include <linux/time.h> | ||
35 | |||
36 | #include <linux/spinlock.h> | ||
37 | #include <linux/pm.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | #define NUM_IR_IFF 1 | ||
41 | #define NUM_IR_DESC 64 | ||
42 | #define RING_SIZE_4 0x0 | ||
43 | #define RING_SIZE_16 0x3 | ||
44 | #define RING_SIZE_64 0xF | ||
45 | #define MAX_NUM_IR_DESC 64 | ||
46 | #define MAX_BUF_SIZE 2048 | ||
47 | |||
48 | #define BPS_115200 0 | ||
49 | #define BPS_57600 1 | ||
50 | #define BPS_38400 2 | ||
51 | #define BPS_19200 5 | ||
52 | #define BPS_9600 11 | ||
53 | #define BPS_2400 47 | ||
54 | |||
55 | /* Ring descriptor flags */ | ||
56 | #define AU_OWN (1<<7) /* tx,rx */ | ||
57 | |||
58 | #define IR_DIS_CRC (1<<6) /* tx */ | ||
59 | #define IR_BAD_CRC (1<<5) /* tx */ | ||
60 | #define IR_NEED_PULSE (1<<4) /* tx */ | ||
61 | #define IR_FORCE_UNDER (1<<3) /* tx */ | ||
62 | #define IR_DISABLE_TX (1<<2) /* tx */ | ||
63 | #define IR_HW_UNDER (1<<0) /* tx */ | ||
64 | #define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER) | ||
65 | |||
66 | #define IR_PHY_ERROR (1<<6) /* rx */ | ||
67 | #define IR_CRC_ERROR (1<<5) /* rx */ | ||
68 | #define IR_MAX_LEN (1<<4) /* rx */ | ||
69 | #define IR_FIFO_OVER (1<<3) /* rx */ | ||
70 | #define IR_SIR_ERROR (1<<2) /* rx */ | ||
71 | #define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \ | ||
72 | IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR) | ||
73 | |||
74 | typedef struct db_dest { | ||
75 | struct db_dest *pnext; | ||
76 | volatile u32 *vaddr; | ||
77 | dma_addr_t dma_addr; | ||
78 | } db_dest_t; | ||
79 | |||
80 | |||
81 | typedef struct ring_desc { | ||
82 | u8 count_0; /* 7:0 */ | ||
83 | u8 count_1; /* 12:8 */ | ||
84 | u8 reserved; | ||
85 | u8 flags; | ||
86 | u8 addr_0; /* 7:0 */ | ||
87 | u8 addr_1; /* 15:8 */ | ||
88 | u8 addr_2; /* 23:16 */ | ||
89 | u8 addr_3; /* 31:24 */ | ||
90 | } ring_dest_t; | ||
91 | |||
92 | |||
93 | /* Private data for each instance */ | ||
94 | struct au1k_private { | ||
95 | |||
96 | db_dest_t *pDBfree; | ||
97 | db_dest_t db[2*NUM_IR_DESC]; | ||
98 | volatile ring_dest_t *rx_ring[NUM_IR_DESC]; | ||
99 | volatile ring_dest_t *tx_ring[NUM_IR_DESC]; | ||
100 | db_dest_t *rx_db_inuse[NUM_IR_DESC]; | ||
101 | db_dest_t *tx_db_inuse[NUM_IR_DESC]; | ||
102 | u32 rx_head; | ||
103 | u32 tx_head; | ||
104 | u32 tx_tail; | ||
105 | u32 tx_full; | ||
106 | |||
107 | iobuff_t rx_buff; | ||
108 | |||
109 | struct net_device *netdev; | ||
110 | |||
111 | struct timeval stamp; | ||
112 | struct timeval now; | ||
113 | struct qos_info qos; | ||
114 | struct irlap_cb *irlap; | ||
115 | |||
116 | u8 open; | ||
117 | u32 speed; | ||
118 | u32 newspeed; | ||
119 | |||
120 | u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */ | ||
121 | struct timer_list timer; | ||
122 | |||
123 | spinlock_t lock; /* For serializing operations */ | ||
124 | }; | ||
125 | #endif /* AU1000_IRCC_H */ | ||
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c index a3d696a9456a..fc503aa5288e 100644 --- a/drivers/net/irda/au1k_ir.c +++ b/drivers/net/irda/au1k_ir.c | |||
@@ -18,104 +18,220 @@ | |||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | 18 | * with this program; if not, write to the Free Software Foundation, Inc., |
19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
20 | */ | 20 | */ |
21 | #include <linux/module.h> | 21 | |
22 | #include <linux/types.h> | ||
23 | #include <linux/init.h> | 22 | #include <linux/init.h> |
24 | #include <linux/errno.h> | 23 | #include <linux/module.h> |
25 | #include <linux/netdevice.h> | 24 | #include <linux/netdevice.h> |
26 | #include <linux/slab.h> | ||
27 | #include <linux/rtnetlink.h> | ||
28 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
29 | #include <linux/pm.h> | 26 | #include <linux/platform_device.h> |
30 | #include <linux/bitops.h> | 27 | #include <linux/slab.h> |
31 | 28 | #include <linux/time.h> | |
32 | #include <asm/irq.h> | 29 | #include <linux/types.h> |
33 | #include <asm/io.h> | ||
34 | #include <asm/au1000.h> | ||
35 | #if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) | ||
36 | #include <asm/pb1000.h> | ||
37 | #elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) | ||
38 | #include <asm/db1x00.h> | ||
39 | #include <asm/mach-db1x00/bcsr.h> | ||
40 | #else | ||
41 | #error au1k_ir: unsupported board | ||
42 | #endif | ||
43 | 30 | ||
44 | #include <net/irda/irda.h> | 31 | #include <net/irda/irda.h> |
45 | #include <net/irda/irmod.h> | 32 | #include <net/irda/irmod.h> |
46 | #include <net/irda/wrapper.h> | 33 | #include <net/irda/wrapper.h> |
47 | #include <net/irda/irda_device.h> | 34 | #include <net/irda/irda_device.h> |
48 | #include "au1000_ircc.h" | 35 | #include <asm/mach-au1x00/au1000.h> |
36 | |||
37 | /* registers */ | ||
38 | #define IR_RING_PTR_STATUS 0x00 | ||
39 | #define IR_RING_BASE_ADDR_H 0x04 | ||
40 | #define IR_RING_BASE_ADDR_L 0x08 | ||
41 | #define IR_RING_SIZE 0x0C | ||
42 | #define IR_RING_PROMPT 0x10 | ||
43 | #define IR_RING_ADDR_CMPR 0x14 | ||
44 | #define IR_INT_CLEAR 0x18 | ||
45 | #define IR_CONFIG_1 0x20 | ||
46 | #define IR_SIR_FLAGS 0x24 | ||
47 | #define IR_STATUS 0x28 | ||
48 | #define IR_READ_PHY_CONFIG 0x2C | ||
49 | #define IR_WRITE_PHY_CONFIG 0x30 | ||
50 | #define IR_MAX_PKT_LEN 0x34 | ||
51 | #define IR_RX_BYTE_CNT 0x38 | ||
52 | #define IR_CONFIG_2 0x3C | ||
53 | #define IR_ENABLE 0x40 | ||
54 | |||
55 | /* Config1 */ | ||
56 | #define IR_RX_INVERT_LED (1 << 0) | ||
57 | #define IR_TX_INVERT_LED (1 << 1) | ||
58 | #define IR_ST (1 << 2) | ||
59 | #define IR_SF (1 << 3) | ||
60 | #define IR_SIR (1 << 4) | ||
61 | #define IR_MIR (1 << 5) | ||
62 | #define IR_FIR (1 << 6) | ||
63 | #define IR_16CRC (1 << 7) | ||
64 | #define IR_TD (1 << 8) | ||
65 | #define IR_RX_ALL (1 << 9) | ||
66 | #define IR_DMA_ENABLE (1 << 10) | ||
67 | #define IR_RX_ENABLE (1 << 11) | ||
68 | #define IR_TX_ENABLE (1 << 12) | ||
69 | #define IR_LOOPBACK (1 << 14) | ||
70 | #define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \ | ||
71 | IR_RX_ALL | IR_RX_ENABLE | IR_SF | \ | ||
72 | IR_16CRC) | ||
73 | |||
74 | /* ir_status */ | ||
75 | #define IR_RX_STATUS (1 << 9) | ||
76 | #define IR_TX_STATUS (1 << 10) | ||
77 | #define IR_PHYEN (1 << 15) | ||
78 | |||
79 | /* ir_write_phy_config */ | ||
80 | #define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */ | ||
81 | #define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */ | ||
82 | #define IR_P(x) ((x) & 0x1f) /* preamble bits */ | ||
83 | |||
84 | /* Config2 */ | ||
85 | #define IR_MODE_INV (1 << 0) | ||
86 | #define IR_ONE_PIN (1 << 1) | ||
87 | #define IR_PHYCLK_40MHZ (0 << 2) | ||
88 | #define IR_PHYCLK_48MHZ (1 << 2) | ||
89 | #define IR_PHYCLK_56MHZ (2 << 2) | ||
90 | #define IR_PHYCLK_64MHZ (3 << 2) | ||
91 | #define IR_DP (1 << 4) | ||
92 | #define IR_DA (1 << 5) | ||
93 | #define IR_FLT_HIGH (0 << 6) | ||
94 | #define IR_FLT_MEDHI (1 << 6) | ||
95 | #define IR_FLT_MEDLO (2 << 6) | ||
96 | #define IR_FLT_LO (3 << 6) | ||
97 | #define IR_IEN (1 << 8) | ||
98 | |||
99 | /* ir_enable */ | ||
100 | #define IR_HC (1 << 3) /* divide SBUS clock by 2 */ | ||
101 | #define IR_CE (1 << 2) /* clock enable */ | ||
102 | #define IR_C (1 << 1) /* coherency bit */ | ||
103 | #define IR_BE (1 << 0) /* set in big endian mode */ | ||
104 | |||
105 | #define NUM_IR_DESC 64 | ||
106 | #define RING_SIZE_4 0x0 | ||
107 | #define RING_SIZE_16 0x3 | ||
108 | #define RING_SIZE_64 0xF | ||
109 | #define MAX_NUM_IR_DESC 64 | ||
110 | #define MAX_BUF_SIZE 2048 | ||
111 | |||
112 | /* Ring descriptor flags */ | ||
113 | #define AU_OWN (1 << 7) /* tx,rx */ | ||
114 | #define IR_DIS_CRC (1 << 6) /* tx */ | ||
115 | #define IR_BAD_CRC (1 << 5) /* tx */ | ||
116 | #define IR_NEED_PULSE (1 << 4) /* tx */ | ||
117 | #define IR_FORCE_UNDER (1 << 3) /* tx */ | ||
118 | #define IR_DISABLE_TX (1 << 2) /* tx */ | ||
119 | #define IR_HW_UNDER (1 << 0) /* tx */ | ||
120 | #define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER) | ||
121 | |||
122 | #define IR_PHY_ERROR (1 << 6) /* rx */ | ||
123 | #define IR_CRC_ERROR (1 << 5) /* rx */ | ||
124 | #define IR_MAX_LEN (1 << 4) /* rx */ | ||
125 | #define IR_FIFO_OVER (1 << 3) /* rx */ | ||
126 | #define IR_SIR_ERROR (1 << 2) /* rx */ | ||
127 | #define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \ | ||
128 | IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR) | ||
129 | |||
130 | struct db_dest { | ||
131 | struct db_dest *pnext; | ||
132 | volatile u32 *vaddr; | ||
133 | dma_addr_t dma_addr; | ||
134 | }; | ||
49 | 135 | ||
50 | static int au1k_irda_net_init(struct net_device *); | 136 | struct ring_dest { |
51 | static int au1k_irda_start(struct net_device *); | 137 | u8 count_0; /* 7:0 */ |
52 | static int au1k_irda_stop(struct net_device *dev); | 138 | u8 count_1; /* 12:8 */ |
53 | static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *); | 139 | u8 reserved; |
54 | static int au1k_irda_rx(struct net_device *); | 140 | u8 flags; |
55 | static void au1k_irda_interrupt(int, void *); | 141 | u8 addr_0; /* 7:0 */ |
56 | static void au1k_tx_timeout(struct net_device *); | 142 | u8 addr_1; /* 15:8 */ |
57 | static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int); | 143 | u8 addr_2; /* 23:16 */ |
58 | static int au1k_irda_set_speed(struct net_device *dev, int speed); | 144 | u8 addr_3; /* 31:24 */ |
145 | }; | ||
59 | 146 | ||
60 | static void *dma_alloc(size_t, dma_addr_t *); | 147 | /* Private data for each instance */ |
61 | static void dma_free(void *, size_t); | 148 | struct au1k_private { |
149 | void __iomem *iobase; | ||
150 | int irq_rx, irq_tx; | ||
151 | |||
152 | struct db_dest *pDBfree; | ||
153 | struct db_dest db[2 * NUM_IR_DESC]; | ||
154 | volatile struct ring_dest *rx_ring[NUM_IR_DESC]; | ||
155 | volatile struct ring_dest *tx_ring[NUM_IR_DESC]; | ||
156 | struct db_dest *rx_db_inuse[NUM_IR_DESC]; | ||
157 | struct db_dest *tx_db_inuse[NUM_IR_DESC]; | ||
158 | u32 rx_head; | ||
159 | u32 tx_head; | ||
160 | u32 tx_tail; | ||
161 | u32 tx_full; | ||
162 | |||
163 | iobuff_t rx_buff; | ||
164 | |||
165 | struct net_device *netdev; | ||
166 | struct timeval stamp; | ||
167 | struct timeval now; | ||
168 | struct qos_info qos; | ||
169 | struct irlap_cb *irlap; | ||
170 | |||
171 | u8 open; | ||
172 | u32 speed; | ||
173 | u32 newspeed; | ||
174 | |||
175 | struct timer_list timer; | ||
176 | |||
177 | struct resource *ioarea; | ||
178 | struct au1k_irda_platform_data *platdata; | ||
179 | }; | ||
62 | 180 | ||
63 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ | 181 | static int qos_mtt_bits = 0x07; /* 1 ms or more */ |
64 | static struct net_device *ir_devs[NUM_IR_IFF]; | ||
65 | static char version[] __devinitdata = | ||
66 | "au1k_ircc:1.2 ppopov@mvista.com\n"; | ||
67 | 182 | ||
68 | #define RUN_AT(x) (jiffies + (x)) | 183 | #define RUN_AT(x) (jiffies + (x)) |
69 | 184 | ||
70 | static DEFINE_SPINLOCK(ir_lock); | 185 | static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode) |
186 | { | ||
187 | if (p->platdata && p->platdata->set_phy_mode) | ||
188 | p->platdata->set_phy_mode(mode); | ||
189 | } | ||
71 | 190 | ||
72 | /* | 191 | static inline unsigned long irda_read(struct au1k_private *p, |
73 | * IrDA peripheral bug. You have to read the register | 192 | unsigned long ofs) |
74 | * twice to get the right value. | 193 | { |
75 | */ | 194 | /* |
76 | u32 read_ir_reg(u32 addr) | 195 | * IrDA peripheral bug. You have to read the register |
77 | { | 196 | * twice to get the right value. |
78 | readl(addr); | 197 | */ |
79 | return readl(addr); | 198 | (void)__raw_readl(p->iobase + ofs); |
199 | return __raw_readl(p->iobase + ofs); | ||
80 | } | 200 | } |
81 | 201 | ||
202 | static inline void irda_write(struct au1k_private *p, unsigned long ofs, | ||
203 | unsigned long val) | ||
204 | { | ||
205 | __raw_writel(val, p->iobase + ofs); | ||
206 | wmb(); | ||
207 | } | ||
82 | 208 | ||
83 | /* | 209 | /* |
84 | * Buffer allocation/deallocation routines. The buffer descriptor returned | 210 | * Buffer allocation/deallocation routines. The buffer descriptor returned |
85 | * has the virtual and dma address of a buffer suitable for | 211 | * has the virtual and dma address of a buffer suitable for |
86 | * both, receive and transmit operations. | 212 | * both, receive and transmit operations. |
87 | */ | 213 | */ |
88 | static db_dest_t *GetFreeDB(struct au1k_private *aup) | 214 | static struct db_dest *GetFreeDB(struct au1k_private *aup) |
89 | { | 215 | { |
90 | db_dest_t *pDB; | 216 | struct db_dest *db; |
91 | pDB = aup->pDBfree; | 217 | db = aup->pDBfree; |
92 | |||
93 | if (pDB) { | ||
94 | aup->pDBfree = pDB->pnext; | ||
95 | } | ||
96 | return pDB; | ||
97 | } | ||
98 | 218 | ||
99 | static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB) | 219 | if (db) |
100 | { | 220 | aup->pDBfree = db->pnext; |
101 | db_dest_t *pDBfree = aup->pDBfree; | 221 | return db; |
102 | if (pDBfree) | ||
103 | pDBfree->pnext = pDB; | ||
104 | aup->pDBfree = pDB; | ||
105 | } | 222 | } |
106 | 223 | ||
107 | |||
108 | /* | 224 | /* |
109 | DMA memory allocation, derived from pci_alloc_consistent. | 225 | DMA memory allocation, derived from pci_alloc_consistent. |
110 | However, the Au1000 data cache is coherent (when programmed | 226 | However, the Au1000 data cache is coherent (when programmed |
111 | so), therefore we return KSEG0 address, not KSEG1. | 227 | so), therefore we return KSEG0 address, not KSEG1. |
112 | */ | 228 | */ |
113 | static void *dma_alloc(size_t size, dma_addr_t * dma_handle) | 229 | static void *dma_alloc(size_t size, dma_addr_t *dma_handle) |
114 | { | 230 | { |
115 | void *ret; | 231 | void *ret; |
116 | int gfp = GFP_ATOMIC | GFP_DMA; | 232 | int gfp = GFP_ATOMIC | GFP_DMA; |
117 | 233 | ||
118 | ret = (void *) __get_free_pages(gfp, get_order(size)); | 234 | ret = (void *)__get_free_pages(gfp, get_order(size)); |
119 | 235 | ||
120 | if (ret != NULL) { | 236 | if (ret != NULL) { |
121 | memset(ret, 0, size); | 237 | memset(ret, 0, size); |
@@ -125,7 +241,6 @@ static void *dma_alloc(size_t size, dma_addr_t * dma_handle) | |||
125 | return ret; | 241 | return ret; |
126 | } | 242 | } |
127 | 243 | ||
128 | |||
129 | static void dma_free(void *vaddr, size_t size) | 244 | static void dma_free(void *vaddr, size_t size) |
130 | { | 245 | { |
131 | vaddr = (void *)KSEG0ADDR(vaddr); | 246 | vaddr = (void *)KSEG0ADDR(vaddr); |
@@ -133,206 +248,306 @@ static void dma_free(void *vaddr, size_t size) | |||
133 | } | 248 | } |
134 | 249 | ||
135 | 250 | ||
136 | static void | 251 | static void setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base) |
137 | setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base) | ||
138 | { | 252 | { |
139 | int i; | 253 | int i; |
140 | for (i=0; i<NUM_IR_DESC; i++) { | 254 | for (i = 0; i < NUM_IR_DESC; i++) { |
141 | aup->rx_ring[i] = (volatile ring_dest_t *) | 255 | aup->rx_ring[i] = (volatile struct ring_dest *) |
142 | (rx_base + sizeof(ring_dest_t)*i); | 256 | (rx_base + sizeof(struct ring_dest) * i); |
143 | } | 257 | } |
144 | for (i=0; i<NUM_IR_DESC; i++) { | 258 | for (i = 0; i < NUM_IR_DESC; i++) { |
145 | aup->tx_ring[i] = (volatile ring_dest_t *) | 259 | aup->tx_ring[i] = (volatile struct ring_dest *) |
146 | (tx_base + sizeof(ring_dest_t)*i); | 260 | (tx_base + sizeof(struct ring_dest) * i); |
147 | } | 261 | } |
148 | } | 262 | } |
149 | 263 | ||
150 | static int au1k_irda_init(void) | ||
151 | { | ||
152 | static unsigned version_printed = 0; | ||
153 | struct au1k_private *aup; | ||
154 | struct net_device *dev; | ||
155 | int err; | ||
156 | |||
157 | if (version_printed++ == 0) printk(version); | ||
158 | |||
159 | dev = alloc_irdadev(sizeof(struct au1k_private)); | ||
160 | if (!dev) | ||
161 | return -ENOMEM; | ||
162 | |||
163 | dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */ | ||
164 | err = au1k_irda_net_init(dev); | ||
165 | if (err) | ||
166 | goto out; | ||
167 | err = register_netdev(dev); | ||
168 | if (err) | ||
169 | goto out1; | ||
170 | ir_devs[0] = dev; | ||
171 | printk(KERN_INFO "IrDA: Registered device %s\n", dev->name); | ||
172 | return 0; | ||
173 | |||
174 | out1: | ||
175 | aup = netdev_priv(dev); | ||
176 | dma_free((void *)aup->db[0].vaddr, | ||
177 | MAX_BUF_SIZE * 2*NUM_IR_DESC); | ||
178 | dma_free((void *)aup->rx_ring[0], | ||
179 | 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); | ||
180 | kfree(aup->rx_buff.head); | ||
181 | out: | ||
182 | free_netdev(dev); | ||
183 | return err; | ||
184 | } | ||
185 | |||
186 | static int au1k_irda_init_iobuf(iobuff_t *io, int size) | 264 | static int au1k_irda_init_iobuf(iobuff_t *io, int size) |
187 | { | 265 | { |
188 | io->head = kmalloc(size, GFP_KERNEL); | 266 | io->head = kmalloc(size, GFP_KERNEL); |
189 | if (io->head != NULL) { | 267 | if (io->head != NULL) { |
190 | io->truesize = size; | 268 | io->truesize = size; |
191 | io->in_frame = FALSE; | 269 | io->in_frame = FALSE; |
192 | io->state = OUTSIDE_FRAME; | 270 | io->state = OUTSIDE_FRAME; |
193 | io->data = io->head; | 271 | io->data = io->head; |
194 | } | 272 | } |
195 | return io->head ? 0 : -ENOMEM; | 273 | return io->head ? 0 : -ENOMEM; |
196 | } | 274 | } |
197 | 275 | ||
198 | static const struct net_device_ops au1k_irda_netdev_ops = { | 276 | /* |
199 | .ndo_open = au1k_irda_start, | 277 | * Set the IrDA communications speed. |
200 | .ndo_stop = au1k_irda_stop, | 278 | */ |
201 | .ndo_start_xmit = au1k_irda_hard_xmit, | 279 | static int au1k_irda_set_speed(struct net_device *dev, int speed) |
202 | .ndo_tx_timeout = au1k_tx_timeout, | ||
203 | .ndo_do_ioctl = au1k_irda_ioctl, | ||
204 | }; | ||
205 | |||
206 | static int au1k_irda_net_init(struct net_device *dev) | ||
207 | { | 280 | { |
208 | struct au1k_private *aup = netdev_priv(dev); | 281 | struct au1k_private *aup = netdev_priv(dev); |
209 | int i, retval = 0, err; | 282 | volatile struct ring_dest *ptxd; |
210 | db_dest_t *pDB, *pDBfree; | 283 | unsigned long control; |
211 | dma_addr_t temp; | 284 | int ret = 0, timeout = 10, i; |
212 | 285 | ||
213 | err = au1k_irda_init_iobuf(&aup->rx_buff, 14384); | 286 | if (speed == aup->speed) |
214 | if (err) | 287 | return ret; |
215 | goto out1; | ||
216 | 288 | ||
217 | dev->netdev_ops = &au1k_irda_netdev_ops; | 289 | /* disable PHY first */ |
290 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); | ||
291 | irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN); | ||
218 | 292 | ||
219 | irda_init_max_qos_capabilies(&aup->qos); | 293 | /* disable RX/TX */ |
294 | irda_write(aup, IR_CONFIG_1, | ||
295 | irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE)); | ||
296 | msleep(20); | ||
297 | while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) { | ||
298 | msleep(20); | ||
299 | if (!timeout--) { | ||
300 | printk(KERN_ERR "%s: rx/tx disable timeout\n", | ||
301 | dev->name); | ||
302 | break; | ||
303 | } | ||
304 | } | ||
220 | 305 | ||
221 | /* The only value we must override it the baudrate */ | 306 | /* disable DMA */ |
222 | aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600| | 307 | irda_write(aup, IR_CONFIG_1, |
223 | IR_115200|IR_576000 |(IR_4000000 << 8); | 308 | irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE); |
224 | 309 | msleep(20); | |
225 | aup->qos.min_turn_time.bits = qos_mtt_bits; | ||
226 | irda_qos_bits_to_value(&aup->qos); | ||
227 | 310 | ||
228 | retval = -ENOMEM; | 311 | /* After we disable tx/rx. the index pointers go back to zero. */ |
312 | aup->tx_head = aup->tx_tail = aup->rx_head = 0; | ||
313 | for (i = 0; i < NUM_IR_DESC; i++) { | ||
314 | ptxd = aup->tx_ring[i]; | ||
315 | ptxd->flags = 0; | ||
316 | ptxd->count_0 = 0; | ||
317 | ptxd->count_1 = 0; | ||
318 | } | ||
229 | 319 | ||
230 | /* Tx ring follows rx ring + 512 bytes */ | 320 | for (i = 0; i < NUM_IR_DESC; i++) { |
231 | /* we need a 1k aligned buffer */ | 321 | ptxd = aup->rx_ring[i]; |
232 | aup->rx_ring[0] = (ring_dest_t *) | 322 | ptxd->count_0 = 0; |
233 | dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp); | 323 | ptxd->count_1 = 0; |
234 | if (!aup->rx_ring[0]) | 324 | ptxd->flags = AU_OWN; |
235 | goto out2; | 325 | } |
236 | 326 | ||
237 | /* allocate the data buffers */ | 327 | if (speed == 4000000) |
238 | aup->db[0].vaddr = | 328 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR); |
239 | (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp); | 329 | else |
240 | if (!aup->db[0].vaddr) | 330 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR); |
241 | goto out3; | ||
242 | 331 | ||
243 | setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512); | 332 | switch (speed) { |
333 | case 9600: | ||
334 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12)); | ||
335 | irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); | ||
336 | break; | ||
337 | case 19200: | ||
338 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12)); | ||
339 | irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); | ||
340 | break; | ||
341 | case 38400: | ||
342 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12)); | ||
343 | irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); | ||
344 | break; | ||
345 | case 57600: | ||
346 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12)); | ||
347 | irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); | ||
348 | break; | ||
349 | case 115200: | ||
350 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12)); | ||
351 | irda_write(aup, IR_CONFIG_1, IR_SIR_MODE); | ||
352 | break; | ||
353 | case 4000000: | ||
354 | irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15)); | ||
355 | irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE | | ||
356 | IR_RX_ENABLE); | ||
357 | break; | ||
358 | default: | ||
359 | printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed); | ||
360 | ret = -EINVAL; | ||
361 | break; | ||
362 | } | ||
244 | 363 | ||
245 | pDBfree = NULL; | 364 | aup->speed = speed; |
246 | pDB = aup->db; | 365 | irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN); |
247 | for (i=0; i<(2*NUM_IR_DESC); i++) { | 366 | |
248 | pDB->pnext = pDBfree; | 367 | control = irda_read(aup, IR_STATUS); |
249 | pDBfree = pDB; | 368 | irda_write(aup, IR_RING_PROMPT, 0); |
250 | pDB->vaddr = | 369 | |
251 | (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i); | 370 | if (control & (1 << 14)) { |
252 | pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); | 371 | printk(KERN_ERR "%s: configuration error\n", dev->name); |
253 | pDB++; | 372 | } else { |
373 | if (control & (1 << 11)) | ||
374 | printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); | ||
375 | if (control & (1 << 12)) | ||
376 | printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); | ||
377 | if (control & (1 << 13)) | ||
378 | printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); | ||
379 | if (control & (1 << 10)) | ||
380 | printk(KERN_DEBUG "%s TX enabled\n", dev->name); | ||
381 | if (control & (1 << 9)) | ||
382 | printk(KERN_DEBUG "%s RX enabled\n", dev->name); | ||
254 | } | 383 | } |
255 | aup->pDBfree = pDBfree; | ||
256 | 384 | ||
257 | /* attach a data buffer to each descriptor */ | 385 | return ret; |
258 | for (i=0; i<NUM_IR_DESC; i++) { | 386 | } |
259 | pDB = GetFreeDB(aup); | 387 | |
260 | if (!pDB) goto out; | 388 | static void update_rx_stats(struct net_device *dev, u32 status, u32 count) |
261 | aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); | 389 | { |
262 | aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); | 390 | struct net_device_stats *ps = &dev->stats; |
263 | aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); | 391 | |
264 | aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); | 392 | ps->rx_packets++; |
265 | aup->rx_db_inuse[i] = pDB; | 393 | |
394 | if (status & IR_RX_ERROR) { | ||
395 | ps->rx_errors++; | ||
396 | if (status & (IR_PHY_ERROR | IR_FIFO_OVER)) | ||
397 | ps->rx_missed_errors++; | ||
398 | if (status & IR_MAX_LEN) | ||
399 | ps->rx_length_errors++; | ||
400 | if (status & IR_CRC_ERROR) | ||
401 | ps->rx_crc_errors++; | ||
402 | } else | ||
403 | ps->rx_bytes += count; | ||
404 | } | ||
405 | |||
406 | static void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) | ||
407 | { | ||
408 | struct net_device_stats *ps = &dev->stats; | ||
409 | |||
410 | ps->tx_packets++; | ||
411 | ps->tx_bytes += pkt_len; | ||
412 | |||
413 | if (status & IR_TX_ERROR) { | ||
414 | ps->tx_errors++; | ||
415 | ps->tx_aborted_errors++; | ||
266 | } | 416 | } |
267 | for (i=0; i<NUM_IR_DESC; i++) { | 417 | } |
268 | pDB = GetFreeDB(aup); | 418 | |
269 | if (!pDB) goto out; | 419 | static void au1k_tx_ack(struct net_device *dev) |
270 | aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); | 420 | { |
271 | aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff); | 421 | struct au1k_private *aup = netdev_priv(dev); |
272 | aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff); | 422 | volatile struct ring_dest *ptxd; |
273 | aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff); | 423 | |
274 | aup->tx_ring[i]->count_0 = 0; | 424 | ptxd = aup->tx_ring[aup->tx_tail]; |
275 | aup->tx_ring[i]->count_1 = 0; | 425 | while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) { |
276 | aup->tx_ring[i]->flags = 0; | 426 | update_tx_stats(dev, ptxd->flags, |
277 | aup->tx_db_inuse[i] = pDB; | 427 | (ptxd->count_1 << 8) | ptxd->count_0); |
428 | ptxd->count_0 = 0; | ||
429 | ptxd->count_1 = 0; | ||
430 | wmb(); | ||
431 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1); | ||
432 | ptxd = aup->tx_ring[aup->tx_tail]; | ||
433 | |||
434 | if (aup->tx_full) { | ||
435 | aup->tx_full = 0; | ||
436 | netif_wake_queue(dev); | ||
437 | } | ||
278 | } | 438 | } |
279 | 439 | ||
280 | #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) | 440 | if (aup->tx_tail == aup->tx_head) { |
281 | /* power on */ | 441 | if (aup->newspeed) { |
282 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK, | 442 | au1k_irda_set_speed(dev, aup->newspeed); |
283 | BCSR_RESETS_IRDA_MODE_FULL); | 443 | aup->newspeed = 0; |
284 | #endif | 444 | } else { |
445 | irda_write(aup, IR_CONFIG_1, | ||
446 | irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE); | ||
447 | irda_write(aup, IR_CONFIG_1, | ||
448 | irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE); | ||
449 | irda_write(aup, IR_RING_PROMPT, 0); | ||
450 | } | ||
451 | } | ||
452 | } | ||
285 | 453 | ||
286 | return 0; | 454 | static int au1k_irda_rx(struct net_device *dev) |
455 | { | ||
456 | struct au1k_private *aup = netdev_priv(dev); | ||
457 | volatile struct ring_dest *prxd; | ||
458 | struct sk_buff *skb; | ||
459 | struct db_dest *pDB; | ||
460 | u32 flags, count; | ||
287 | 461 | ||
288 | out3: | 462 | prxd = aup->rx_ring[aup->rx_head]; |
289 | dma_free((void *)aup->rx_ring[0], | 463 | flags = prxd->flags; |
290 | 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); | 464 | |
291 | out2: | 465 | while (!(flags & AU_OWN)) { |
292 | kfree(aup->rx_buff.head); | 466 | pDB = aup->rx_db_inuse[aup->rx_head]; |
293 | out1: | 467 | count = (prxd->count_1 << 8) | prxd->count_0; |
294 | printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval); | 468 | if (!(flags & IR_RX_ERROR)) { |
295 | return retval; | 469 | /* good frame */ |
470 | update_rx_stats(dev, flags, count); | ||
471 | skb = alloc_skb(count + 1, GFP_ATOMIC); | ||
472 | if (skb == NULL) { | ||
473 | dev->stats.rx_dropped++; | ||
474 | continue; | ||
475 | } | ||
476 | skb_reserve(skb, 1); | ||
477 | if (aup->speed == 4000000) | ||
478 | skb_put(skb, count); | ||
479 | else | ||
480 | skb_put(skb, count - 2); | ||
481 | skb_copy_to_linear_data(skb, (void *)pDB->vaddr, | ||
482 | count - 2); | ||
483 | skb->dev = dev; | ||
484 | skb_reset_mac_header(skb); | ||
485 | skb->protocol = htons(ETH_P_IRDA); | ||
486 | netif_rx(skb); | ||
487 | prxd->count_0 = 0; | ||
488 | prxd->count_1 = 0; | ||
489 | } | ||
490 | prxd->flags |= AU_OWN; | ||
491 | aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1); | ||
492 | irda_write(aup, IR_RING_PROMPT, 0); | ||
493 | |||
494 | /* next descriptor */ | ||
495 | prxd = aup->rx_ring[aup->rx_head]; | ||
496 | flags = prxd->flags; | ||
497 | |||
498 | } | ||
499 | return 0; | ||
296 | } | 500 | } |
297 | 501 | ||
502 | static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) | ||
503 | { | ||
504 | struct net_device *dev = dev_id; | ||
505 | struct au1k_private *aup = netdev_priv(dev); | ||
506 | |||
507 | irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */ | ||
508 | |||
509 | au1k_irda_rx(dev); | ||
510 | au1k_tx_ack(dev); | ||
511 | |||
512 | return IRQ_HANDLED; | ||
513 | } | ||
298 | 514 | ||
299 | static int au1k_init(struct net_device *dev) | 515 | static int au1k_init(struct net_device *dev) |
300 | { | 516 | { |
301 | struct au1k_private *aup = netdev_priv(dev); | 517 | struct au1k_private *aup = netdev_priv(dev); |
518 | u32 enable, ring_address; | ||
302 | int i; | 519 | int i; |
303 | u32 control; | ||
304 | u32 ring_address; | ||
305 | 520 | ||
306 | /* bring the device out of reset */ | 521 | enable = IR_HC | IR_CE | IR_C; |
307 | control = 0xe; /* coherent, clock enable, one half system clock */ | ||
308 | |||
309 | #ifndef CONFIG_CPU_LITTLE_ENDIAN | 522 | #ifndef CONFIG_CPU_LITTLE_ENDIAN |
310 | control |= 1; | 523 | enable |= IR_BE; |
311 | #endif | 524 | #endif |
312 | aup->tx_head = 0; | 525 | aup->tx_head = 0; |
313 | aup->tx_tail = 0; | 526 | aup->tx_tail = 0; |
314 | aup->rx_head = 0; | 527 | aup->rx_head = 0; |
315 | 528 | ||
316 | for (i=0; i<NUM_IR_DESC; i++) { | 529 | for (i = 0; i < NUM_IR_DESC; i++) |
317 | aup->rx_ring[i]->flags = AU_OWN; | 530 | aup->rx_ring[i]->flags = AU_OWN; |
318 | } | ||
319 | 531 | ||
320 | writel(control, IR_INTERFACE_CONFIG); | 532 | irda_write(aup, IR_ENABLE, enable); |
321 | au_sync_delay(10); | 533 | msleep(20); |
322 | 534 | ||
323 | writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */ | 535 | /* disable PHY */ |
324 | au_sync_delay(1); | 536 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); |
537 | irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN); | ||
538 | msleep(20); | ||
325 | 539 | ||
326 | writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN); | 540 | irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE); |
327 | 541 | ||
328 | ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]); | 542 | ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]); |
329 | writel(ring_address >> 26, IR_RING_BASE_ADDR_H); | 543 | irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26); |
330 | writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L); | 544 | irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff); |
331 | 545 | ||
332 | writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE); | 546 | irda_write(aup, IR_RING_SIZE, |
547 | (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12)); | ||
333 | 548 | ||
334 | writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */ | 549 | irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN); |
335 | writel(0, IR_RING_ADDR_CMPR); | 550 | irda_write(aup, IR_RING_ADDR_CMPR, 0); |
336 | 551 | ||
337 | au1k_irda_set_speed(dev, 9600); | 552 | au1k_irda_set_speed(dev, 9600); |
338 | return 0; | 553 | return 0; |
@@ -340,25 +555,28 @@ static int au1k_init(struct net_device *dev) | |||
340 | 555 | ||
341 | static int au1k_irda_start(struct net_device *dev) | 556 | static int au1k_irda_start(struct net_device *dev) |
342 | { | 557 | { |
343 | int retval; | ||
344 | char hwname[32]; | ||
345 | struct au1k_private *aup = netdev_priv(dev); | 558 | struct au1k_private *aup = netdev_priv(dev); |
559 | char hwname[32]; | ||
560 | int retval; | ||
346 | 561 | ||
347 | if ((retval = au1k_init(dev))) { | 562 | retval = au1k_init(dev); |
563 | if (retval) { | ||
348 | printk(KERN_ERR "%s: error in au1k_init\n", dev->name); | 564 | printk(KERN_ERR "%s: error in au1k_init\n", dev->name); |
349 | return retval; | 565 | return retval; |
350 | } | 566 | } |
351 | 567 | ||
352 | if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt, | 568 | retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0, |
353 | 0, dev->name, dev))) { | 569 | dev->name, dev); |
354 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | 570 | if (retval) { |
571 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | ||
355 | dev->name, dev->irq); | 572 | dev->name, dev->irq); |
356 | return retval; | 573 | return retval; |
357 | } | 574 | } |
358 | if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt, | 575 | retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0, |
359 | 0, dev->name, dev))) { | 576 | dev->name, dev); |
360 | free_irq(AU1000_IRDA_TX_INT, dev); | 577 | if (retval) { |
361 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | 578 | free_irq(aup->irq_tx, dev); |
579 | printk(KERN_ERR "%s: unable to get IRQ %d\n", | ||
362 | dev->name, dev->irq); | 580 | dev->name, dev->irq); |
363 | return retval; | 581 | return retval; |
364 | } | 582 | } |
@@ -368,9 +586,13 @@ static int au1k_irda_start(struct net_device *dev) | |||
368 | aup->irlap = irlap_open(dev, &aup->qos, hwname); | 586 | aup->irlap = irlap_open(dev, &aup->qos, hwname); |
369 | netif_start_queue(dev); | 587 | netif_start_queue(dev); |
370 | 588 | ||
371 | writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */ | 589 | /* int enable */ |
590 | irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN); | ||
591 | |||
592 | /* power up */ | ||
593 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR); | ||
372 | 594 | ||
373 | aup->timer.expires = RUN_AT((3*HZ)); | 595 | aup->timer.expires = RUN_AT((3 * HZ)); |
374 | aup->timer.data = (unsigned long)dev; | 596 | aup->timer.data = (unsigned long)dev; |
375 | return 0; | 597 | return 0; |
376 | } | 598 | } |
@@ -379,11 +601,12 @@ static int au1k_irda_stop(struct net_device *dev) | |||
379 | { | 601 | { |
380 | struct au1k_private *aup = netdev_priv(dev); | 602 | struct au1k_private *aup = netdev_priv(dev); |
381 | 603 | ||
604 | au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF); | ||
605 | |||
382 | /* disable interrupts */ | 606 | /* disable interrupts */ |
383 | writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2); | 607 | irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN); |
384 | writel(0, IR_CONFIG_1); | 608 | irda_write(aup, IR_CONFIG_1, 0); |
385 | writel(0, IR_INTERFACE_CONFIG); /* disable clock */ | 609 | irda_write(aup, IR_ENABLE, 0); /* disable clock */ |
386 | au_sync(); | ||
387 | 610 | ||
388 | if (aup->irlap) { | 611 | if (aup->irlap) { |
389 | irlap_close(aup->irlap); | 612 | irlap_close(aup->irlap); |
@@ -394,83 +617,12 @@ static int au1k_irda_stop(struct net_device *dev) | |||
394 | del_timer(&aup->timer); | 617 | del_timer(&aup->timer); |
395 | 618 | ||
396 | /* disable the interrupt */ | 619 | /* disable the interrupt */ |
397 | free_irq(AU1000_IRDA_TX_INT, dev); | 620 | free_irq(aup->irq_tx, dev); |
398 | free_irq(AU1000_IRDA_RX_INT, dev); | 621 | free_irq(aup->irq_rx, dev); |
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static void __exit au1k_irda_exit(void) | ||
403 | { | ||
404 | struct net_device *dev = ir_devs[0]; | ||
405 | struct au1k_private *aup = netdev_priv(dev); | ||
406 | 622 | ||
407 | unregister_netdev(dev); | 623 | return 0; |
408 | |||
409 | dma_free((void *)aup->db[0].vaddr, | ||
410 | MAX_BUF_SIZE * 2*NUM_IR_DESC); | ||
411 | dma_free((void *)aup->rx_ring[0], | ||
412 | 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t))); | ||
413 | kfree(aup->rx_buff.head); | ||
414 | free_netdev(dev); | ||
415 | } | ||
416 | |||
417 | |||
418 | static inline void | ||
419 | update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) | ||
420 | { | ||
421 | struct au1k_private *aup = netdev_priv(dev); | ||
422 | struct net_device_stats *ps = &aup->stats; | ||
423 | |||
424 | ps->tx_packets++; | ||
425 | ps->tx_bytes += pkt_len; | ||
426 | |||
427 | if (status & IR_TX_ERROR) { | ||
428 | ps->tx_errors++; | ||
429 | ps->tx_aborted_errors++; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | |||
434 | static void au1k_tx_ack(struct net_device *dev) | ||
435 | { | ||
436 | struct au1k_private *aup = netdev_priv(dev); | ||
437 | volatile ring_dest_t *ptxd; | ||
438 | |||
439 | ptxd = aup->tx_ring[aup->tx_tail]; | ||
440 | while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) { | ||
441 | update_tx_stats(dev, ptxd->flags, | ||
442 | ptxd->count_1<<8 | ptxd->count_0); | ||
443 | ptxd->count_0 = 0; | ||
444 | ptxd->count_1 = 0; | ||
445 | au_sync(); | ||
446 | |||
447 | aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1); | ||
448 | ptxd = aup->tx_ring[aup->tx_tail]; | ||
449 | |||
450 | if (aup->tx_full) { | ||
451 | aup->tx_full = 0; | ||
452 | netif_wake_queue(dev); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | if (aup->tx_tail == aup->tx_head) { | ||
457 | if (aup->newspeed) { | ||
458 | au1k_irda_set_speed(dev, aup->newspeed); | ||
459 | aup->newspeed = 0; | ||
460 | } | ||
461 | else { | ||
462 | writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, | ||
463 | IR_CONFIG_1); | ||
464 | au_sync(); | ||
465 | writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, | ||
466 | IR_CONFIG_1); | ||
467 | writel(0, IR_RING_PROMPT); | ||
468 | au_sync(); | ||
469 | } | ||
470 | } | ||
471 | } | 624 | } |
472 | 625 | ||
473 | |||
474 | /* | 626 | /* |
475 | * Au1000 transmit routine. | 627 | * Au1000 transmit routine. |
476 | */ | 628 | */ |
@@ -478,15 +630,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) | |||
478 | { | 630 | { |
479 | struct au1k_private *aup = netdev_priv(dev); | 631 | struct au1k_private *aup = netdev_priv(dev); |
480 | int speed = irda_get_next_speed(skb); | 632 | int speed = irda_get_next_speed(skb); |
481 | volatile ring_dest_t *ptxd; | 633 | volatile struct ring_dest *ptxd; |
482 | u32 len; | 634 | struct db_dest *pDB; |
483 | 635 | u32 len, flags; | |
484 | u32 flags; | ||
485 | db_dest_t *pDB; | ||
486 | 636 | ||
487 | if (speed != aup->speed && speed != -1) { | 637 | if (speed != aup->speed && speed != -1) |
488 | aup->newspeed = speed; | 638 | aup->newspeed = speed; |
489 | } | ||
490 | 639 | ||
491 | if ((skb->len == 0) && (aup->newspeed)) { | 640 | if ((skb->len == 0) && (aup->newspeed)) { |
492 | if (aup->tx_tail == aup->tx_head) { | 641 | if (aup->tx_tail == aup->tx_head) { |
@@ -504,138 +653,47 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev) | |||
504 | printk(KERN_DEBUG "%s: tx_full\n", dev->name); | 653 | printk(KERN_DEBUG "%s: tx_full\n", dev->name); |
505 | netif_stop_queue(dev); | 654 | netif_stop_queue(dev); |
506 | aup->tx_full = 1; | 655 | aup->tx_full = 1; |
507 | return NETDEV_TX_BUSY; | 656 | return 1; |
508 | } | 657 | } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { |
509 | else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) { | ||
510 | printk(KERN_DEBUG "%s: tx_full\n", dev->name); | 658 | printk(KERN_DEBUG "%s: tx_full\n", dev->name); |
511 | netif_stop_queue(dev); | 659 | netif_stop_queue(dev); |
512 | aup->tx_full = 1; | 660 | aup->tx_full = 1; |
513 | return NETDEV_TX_BUSY; | 661 | return 1; |
514 | } | 662 | } |
515 | 663 | ||
516 | pDB = aup->tx_db_inuse[aup->tx_head]; | 664 | pDB = aup->tx_db_inuse[aup->tx_head]; |
517 | 665 | ||
518 | #if 0 | 666 | #if 0 |
519 | if (read_ir_reg(IR_RX_BYTE_CNT) != 0) { | 667 | if (irda_read(aup, IR_RX_BYTE_CNT) != 0) { |
520 | printk("tx warning: rx byte cnt %x\n", | 668 | printk(KERN_DEBUG "tx warning: rx byte cnt %x\n", |
521 | read_ir_reg(IR_RX_BYTE_CNT)); | 669 | irda_read(aup, IR_RX_BYTE_CNT)); |
522 | } | 670 | } |
523 | #endif | 671 | #endif |
524 | 672 | ||
525 | if (aup->speed == 4000000) { | 673 | if (aup->speed == 4000000) { |
526 | /* FIR */ | 674 | /* FIR */ |
527 | skb_copy_from_linear_data(skb, pDB->vaddr, skb->len); | 675 | skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len); |
528 | ptxd->count_0 = skb->len & 0xff; | 676 | ptxd->count_0 = skb->len & 0xff; |
529 | ptxd->count_1 = (skb->len >> 8) & 0xff; | 677 | ptxd->count_1 = (skb->len >> 8) & 0xff; |
530 | 678 | } else { | |
531 | } | ||
532 | else { | ||
533 | /* SIR */ | 679 | /* SIR */ |
534 | len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE); | 680 | len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE); |
535 | ptxd->count_0 = len & 0xff; | 681 | ptxd->count_0 = len & 0xff; |
536 | ptxd->count_1 = (len >> 8) & 0xff; | 682 | ptxd->count_1 = (len >> 8) & 0xff; |
537 | ptxd->flags |= IR_DIS_CRC; | 683 | ptxd->flags |= IR_DIS_CRC; |
538 | au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c); | ||
539 | } | 684 | } |
540 | ptxd->flags |= AU_OWN; | 685 | ptxd->flags |= AU_OWN; |
541 | au_sync(); | 686 | wmb(); |
542 | 687 | ||
543 | writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); | 688 | irda_write(aup, IR_CONFIG_1, |
544 | writel(0, IR_RING_PROMPT); | 689 | irda_read(aup, IR_CONFIG_1) | IR_TX_ENABLE); |
545 | au_sync(); | 690 | irda_write(aup, IR_RING_PROMPT, 0); |
546 | 691 | ||
547 | dev_kfree_skb(skb); | 692 | dev_kfree_skb(skb); |
548 | aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1); | 693 | aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1); |
549 | return NETDEV_TX_OK; | 694 | return NETDEV_TX_OK; |
550 | } | 695 | } |
551 | 696 | ||
552 | |||
553 | static inline void | ||
554 | update_rx_stats(struct net_device *dev, u32 status, u32 count) | ||
555 | { | ||
556 | struct au1k_private *aup = netdev_priv(dev); | ||
557 | struct net_device_stats *ps = &aup->stats; | ||
558 | |||
559 | ps->rx_packets++; | ||
560 | |||
561 | if (status & IR_RX_ERROR) { | ||
562 | ps->rx_errors++; | ||
563 | if (status & (IR_PHY_ERROR|IR_FIFO_OVER)) | ||
564 | ps->rx_missed_errors++; | ||
565 | if (status & IR_MAX_LEN) | ||
566 | ps->rx_length_errors++; | ||
567 | if (status & IR_CRC_ERROR) | ||
568 | ps->rx_crc_errors++; | ||
569 | } | ||
570 | else | ||
571 | ps->rx_bytes += count; | ||
572 | } | ||
573 | |||
574 | /* | ||
575 | * Au1000 receive routine. | ||
576 | */ | ||
577 | static int au1k_irda_rx(struct net_device *dev) | ||
578 | { | ||
579 | struct au1k_private *aup = netdev_priv(dev); | ||
580 | struct sk_buff *skb; | ||
581 | volatile ring_dest_t *prxd; | ||
582 | u32 flags, count; | ||
583 | db_dest_t *pDB; | ||
584 | |||
585 | prxd = aup->rx_ring[aup->rx_head]; | ||
586 | flags = prxd->flags; | ||
587 | |||
588 | while (!(flags & AU_OWN)) { | ||
589 | pDB = aup->rx_db_inuse[aup->rx_head]; | ||
590 | count = prxd->count_1<<8 | prxd->count_0; | ||
591 | if (!(flags & IR_RX_ERROR)) { | ||
592 | /* good frame */ | ||
593 | update_rx_stats(dev, flags, count); | ||
594 | skb=alloc_skb(count+1,GFP_ATOMIC); | ||
595 | if (skb == NULL) { | ||
596 | aup->netdev->stats.rx_dropped++; | ||
597 | continue; | ||
598 | } | ||
599 | skb_reserve(skb, 1); | ||
600 | if (aup->speed == 4000000) | ||
601 | skb_put(skb, count); | ||
602 | else | ||
603 | skb_put(skb, count-2); | ||
604 | skb_copy_to_linear_data(skb, pDB->vaddr, count - 2); | ||
605 | skb->dev = dev; | ||
606 | skb_reset_mac_header(skb); | ||
607 | skb->protocol = htons(ETH_P_IRDA); | ||
608 | netif_rx(skb); | ||
609 | prxd->count_0 = 0; | ||
610 | prxd->count_1 = 0; | ||
611 | } | ||
612 | prxd->flags |= AU_OWN; | ||
613 | aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1); | ||
614 | writel(0, IR_RING_PROMPT); | ||
615 | au_sync(); | ||
616 | |||
617 | /* next descriptor */ | ||
618 | prxd = aup->rx_ring[aup->rx_head]; | ||
619 | flags = prxd->flags; | ||
620 | |||
621 | } | ||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | |||
626 | static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id) | ||
627 | { | ||
628 | struct net_device *dev = dev_id; | ||
629 | |||
630 | writel(0, IR_INT_CLEAR); /* ack irda interrupts */ | ||
631 | |||
632 | au1k_irda_rx(dev); | ||
633 | au1k_tx_ack(dev); | ||
634 | |||
635 | return IRQ_HANDLED; | ||
636 | } | ||
637 | |||
638 | |||
639 | /* | 697 | /* |
640 | * The Tx ring has been full longer than the watchdog timeout | 698 | * The Tx ring has been full longer than the watchdog timeout |
641 | * value. The transmitter must be hung? | 699 | * value. The transmitter must be hung? |
@@ -653,142 +711,7 @@ static void au1k_tx_timeout(struct net_device *dev) | |||
653 | netif_wake_queue(dev); | 711 | netif_wake_queue(dev); |
654 | } | 712 | } |
655 | 713 | ||
656 | 714 | static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) | |
657 | /* | ||
658 | * Set the IrDA communications speed. | ||
659 | */ | ||
660 | static int | ||
661 | au1k_irda_set_speed(struct net_device *dev, int speed) | ||
662 | { | ||
663 | unsigned long flags; | ||
664 | struct au1k_private *aup = netdev_priv(dev); | ||
665 | u32 control; | ||
666 | int ret = 0, timeout = 10, i; | ||
667 | volatile ring_dest_t *ptxd; | ||
668 | #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) | ||
669 | unsigned long irda_resets; | ||
670 | #endif | ||
671 | |||
672 | if (speed == aup->speed) | ||
673 | return ret; | ||
674 | |||
675 | spin_lock_irqsave(&ir_lock, flags); | ||
676 | |||
677 | /* disable PHY first */ | ||
678 | writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); | ||
679 | |||
680 | /* disable RX/TX */ | ||
681 | writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), | ||
682 | IR_CONFIG_1); | ||
683 | au_sync_delay(1); | ||
684 | while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) { | ||
685 | mdelay(1); | ||
686 | if (!timeout--) { | ||
687 | printk(KERN_ERR "%s: rx/tx disable timeout\n", | ||
688 | dev->name); | ||
689 | break; | ||
690 | } | ||
691 | } | ||
692 | |||
693 | /* disable DMA */ | ||
694 | writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1); | ||
695 | au_sync_delay(1); | ||
696 | |||
697 | /* | ||
698 | * After we disable tx/rx. the index pointers | ||
699 | * go back to zero. | ||
700 | */ | ||
701 | aup->tx_head = aup->tx_tail = aup->rx_head = 0; | ||
702 | for (i=0; i<NUM_IR_DESC; i++) { | ||
703 | ptxd = aup->tx_ring[i]; | ||
704 | ptxd->flags = 0; | ||
705 | ptxd->count_0 = 0; | ||
706 | ptxd->count_1 = 0; | ||
707 | } | ||
708 | |||
709 | for (i=0; i<NUM_IR_DESC; i++) { | ||
710 | ptxd = aup->rx_ring[i]; | ||
711 | ptxd->count_0 = 0; | ||
712 | ptxd->count_1 = 0; | ||
713 | ptxd->flags = AU_OWN; | ||
714 | } | ||
715 | |||
716 | if (speed == 4000000) { | ||
717 | #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) | ||
718 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL); | ||
719 | #else /* Pb1000 and Pb1100 */ | ||
720 | writel(1<<13, CPLD_AUX1); | ||
721 | #endif | ||
722 | } | ||
723 | else { | ||
724 | #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) | ||
725 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0); | ||
726 | #else /* Pb1000 and Pb1100 */ | ||
727 | writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1); | ||
728 | #endif | ||
729 | } | ||
730 | |||
731 | switch (speed) { | ||
732 | case 9600: | ||
733 | writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); | ||
734 | writel(IR_SIR_MODE, IR_CONFIG_1); | ||
735 | break; | ||
736 | case 19200: | ||
737 | writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); | ||
738 | writel(IR_SIR_MODE, IR_CONFIG_1); | ||
739 | break; | ||
740 | case 38400: | ||
741 | writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); | ||
742 | writel(IR_SIR_MODE, IR_CONFIG_1); | ||
743 | break; | ||
744 | case 57600: | ||
745 | writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); | ||
746 | writel(IR_SIR_MODE, IR_CONFIG_1); | ||
747 | break; | ||
748 | case 115200: | ||
749 | writel(12<<5, IR_WRITE_PHY_CONFIG); | ||
750 | writel(IR_SIR_MODE, IR_CONFIG_1); | ||
751 | break; | ||
752 | case 4000000: | ||
753 | writel(0xF, IR_WRITE_PHY_CONFIG); | ||
754 | writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); | ||
755 | break; | ||
756 | default: | ||
757 | printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed); | ||
758 | ret = -EINVAL; | ||
759 | break; | ||
760 | } | ||
761 | |||
762 | aup->speed = speed; | ||
763 | writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE); | ||
764 | au_sync(); | ||
765 | |||
766 | control = read_ir_reg(IR_ENABLE); | ||
767 | writel(0, IR_RING_PROMPT); | ||
768 | au_sync(); | ||
769 | |||
770 | if (control & (1<<14)) { | ||
771 | printk(KERN_ERR "%s: configuration error\n", dev->name); | ||
772 | } | ||
773 | else { | ||
774 | if (control & (1<<11)) | ||
775 | printk(KERN_DEBUG "%s Valid SIR config\n", dev->name); | ||
776 | if (control & (1<<12)) | ||
777 | printk(KERN_DEBUG "%s Valid MIR config\n", dev->name); | ||
778 | if (control & (1<<13)) | ||
779 | printk(KERN_DEBUG "%s Valid FIR config\n", dev->name); | ||
780 | if (control & (1<<10)) | ||
781 | printk(KERN_DEBUG "%s TX enabled\n", dev->name); | ||
782 | if (control & (1<<9)) | ||
783 | printk(KERN_DEBUG "%s RX enabled\n", dev->name); | ||
784 | } | ||
785 | |||
786 | spin_unlock_irqrestore(&ir_lock, flags); | ||
787 | return ret; | ||
788 | } | ||
789 | |||
790 | static int | ||
791 | au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) | ||
792 | { | 715 | { |
793 | struct if_irda_req *rq = (struct if_irda_req *)ifreq; | 716 | struct if_irda_req *rq = (struct if_irda_req *)ifreq; |
794 | struct au1k_private *aup = netdev_priv(dev); | 717 | struct au1k_private *aup = netdev_priv(dev); |
@@ -829,8 +752,218 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd) | |||
829 | return ret; | 752 | return ret; |
830 | } | 753 | } |
831 | 754 | ||
755 | static const struct net_device_ops au1k_irda_netdev_ops = { | ||
756 | .ndo_open = au1k_irda_start, | ||
757 | .ndo_stop = au1k_irda_stop, | ||
758 | .ndo_start_xmit = au1k_irda_hard_xmit, | ||
759 | .ndo_tx_timeout = au1k_tx_timeout, | ||
760 | .ndo_do_ioctl = au1k_irda_ioctl, | ||
761 | }; | ||
762 | |||
763 | static int __devinit au1k_irda_net_init(struct net_device *dev) | ||
764 | { | ||
765 | struct au1k_private *aup = netdev_priv(dev); | ||
766 | struct db_dest *pDB, *pDBfree; | ||
767 | int i, err, retval = 0; | ||
768 | dma_addr_t temp; | ||
769 | |||
770 | err = au1k_irda_init_iobuf(&aup->rx_buff, 14384); | ||
771 | if (err) | ||
772 | goto out1; | ||
773 | |||
774 | dev->netdev_ops = &au1k_irda_netdev_ops; | ||
775 | |||
776 | irda_init_max_qos_capabilies(&aup->qos); | ||
777 | |||
778 | /* The only value we must override it the baudrate */ | ||
779 | aup->qos.baud_rate.bits = IR_9600 | IR_19200 | IR_38400 | | ||
780 | IR_57600 | IR_115200 | IR_576000 | (IR_4000000 << 8); | ||
781 | |||
782 | aup->qos.min_turn_time.bits = qos_mtt_bits; | ||
783 | irda_qos_bits_to_value(&aup->qos); | ||
784 | |||
785 | retval = -ENOMEM; | ||
786 | |||
787 | /* Tx ring follows rx ring + 512 bytes */ | ||
788 | /* we need a 1k aligned buffer */ | ||
789 | aup->rx_ring[0] = (struct ring_dest *) | ||
790 | dma_alloc(2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)), | ||
791 | &temp); | ||
792 | if (!aup->rx_ring[0]) | ||
793 | goto out2; | ||
794 | |||
795 | /* allocate the data buffers */ | ||
796 | aup->db[0].vaddr = | ||
797 | (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp); | ||
798 | if (!aup->db[0].vaddr) | ||
799 | goto out3; | ||
800 | |||
801 | setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512); | ||
802 | |||
803 | pDBfree = NULL; | ||
804 | pDB = aup->db; | ||
805 | for (i = 0; i < (2 * NUM_IR_DESC); i++) { | ||
806 | pDB->pnext = pDBfree; | ||
807 | pDBfree = pDB; | ||
808 | pDB->vaddr = | ||
809 | (u32 *)((unsigned)aup->db[0].vaddr + (MAX_BUF_SIZE * i)); | ||
810 | pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr); | ||
811 | pDB++; | ||
812 | } | ||
813 | aup->pDBfree = pDBfree; | ||
814 | |||
815 | /* attach a data buffer to each descriptor */ | ||
816 | for (i = 0; i < NUM_IR_DESC; i++) { | ||
817 | pDB = GetFreeDB(aup); | ||
818 | if (!pDB) | ||
819 | goto out3; | ||
820 | aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); | ||
821 | aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff); | ||
822 | aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff); | ||
823 | aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff); | ||
824 | aup->rx_db_inuse[i] = pDB; | ||
825 | } | ||
826 | for (i = 0; i < NUM_IR_DESC; i++) { | ||
827 | pDB = GetFreeDB(aup); | ||
828 | if (!pDB) | ||
829 | goto out3; | ||
830 | aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff); | ||
831 | aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff); | ||
832 | aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff); | ||
833 | aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff); | ||
834 | aup->tx_ring[i]->count_0 = 0; | ||
835 | aup->tx_ring[i]->count_1 = 0; | ||
836 | aup->tx_ring[i]->flags = 0; | ||
837 | aup->tx_db_inuse[i] = pDB; | ||
838 | } | ||
839 | |||
840 | return 0; | ||
841 | |||
842 | out3: | ||
843 | dma_free((void *)aup->rx_ring[0], | ||
844 | 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); | ||
845 | out2: | ||
846 | kfree(aup->rx_buff.head); | ||
847 | out1: | ||
848 | printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval); | ||
849 | return retval; | ||
850 | } | ||
851 | |||
852 | static int __devinit au1k_irda_probe(struct platform_device *pdev) | ||
853 | { | ||
854 | struct au1k_private *aup; | ||
855 | struct net_device *dev; | ||
856 | struct resource *r; | ||
857 | int err; | ||
858 | |||
859 | dev = alloc_irdadev(sizeof(struct au1k_private)); | ||
860 | if (!dev) | ||
861 | return -ENOMEM; | ||
862 | |||
863 | aup = netdev_priv(dev); | ||
864 | |||
865 | aup->platdata = pdev->dev.platform_data; | ||
866 | |||
867 | err = -EINVAL; | ||
868 | r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
869 | if (!r) | ||
870 | goto out; | ||
871 | |||
872 | aup->irq_tx = r->start; | ||
873 | |||
874 | r = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | ||
875 | if (!r) | ||
876 | goto out; | ||
877 | |||
878 | aup->irq_rx = r->start; | ||
879 | |||
880 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
881 | if (!r) | ||
882 | goto out; | ||
883 | |||
884 | err = -EBUSY; | ||
885 | aup->ioarea = request_mem_region(r->start, r->end - r->start + 1, | ||
886 | pdev->name); | ||
887 | if (!aup->ioarea) | ||
888 | goto out; | ||
889 | |||
890 | aup->iobase = ioremap_nocache(r->start, r->end - r->start + 1); | ||
891 | if (!aup->iobase) | ||
892 | goto out2; | ||
893 | |||
894 | dev->irq = aup->irq_rx; | ||
895 | |||
896 | err = au1k_irda_net_init(dev); | ||
897 | if (err) | ||
898 | goto out3; | ||
899 | err = register_netdev(dev); | ||
900 | if (err) | ||
901 | goto out4; | ||
902 | |||
903 | platform_set_drvdata(pdev, dev); | ||
904 | |||
905 | printk(KERN_INFO "IrDA: Registered device %s\n", dev->name); | ||
906 | return 0; | ||
907 | |||
908 | out4: | ||
909 | dma_free((void *)aup->db[0].vaddr, | ||
910 | MAX_BUF_SIZE * 2 * NUM_IR_DESC); | ||
911 | dma_free((void *)aup->rx_ring[0], | ||
912 | 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); | ||
913 | kfree(aup->rx_buff.head); | ||
914 | out3: | ||
915 | iounmap(aup->iobase); | ||
916 | out2: | ||
917 | release_resource(aup->ioarea); | ||
918 | kfree(aup->ioarea); | ||
919 | out: | ||
920 | free_netdev(dev); | ||
921 | return err; | ||
922 | } | ||
923 | |||
924 | static int __devexit au1k_irda_remove(struct platform_device *pdev) | ||
925 | { | ||
926 | struct net_device *dev = platform_get_drvdata(pdev); | ||
927 | struct au1k_private *aup = netdev_priv(dev); | ||
928 | |||
929 | unregister_netdev(dev); | ||
930 | |||
931 | dma_free((void *)aup->db[0].vaddr, | ||
932 | MAX_BUF_SIZE * 2 * NUM_IR_DESC); | ||
933 | dma_free((void *)aup->rx_ring[0], | ||
934 | 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest))); | ||
935 | kfree(aup->rx_buff.head); | ||
936 | |||
937 | iounmap(aup->iobase); | ||
938 | release_resource(aup->ioarea); | ||
939 | kfree(aup->ioarea); | ||
940 | |||
941 | free_netdev(dev); | ||
942 | |||
943 | return 0; | ||
944 | } | ||
945 | |||
946 | static struct platform_driver au1k_irda_driver = { | ||
947 | .driver = { | ||
948 | .name = "au1000-irda", | ||
949 | .owner = THIS_MODULE, | ||
950 | }, | ||
951 | .probe = au1k_irda_probe, | ||
952 | .remove = __devexit_p(au1k_irda_remove), | ||
953 | }; | ||
954 | |||
955 | static int __init au1k_irda_load(void) | ||
956 | { | ||
957 | return platform_driver_register(&au1k_irda_driver); | ||
958 | } | ||
959 | |||
960 | static void __exit au1k_irda_unload(void) | ||
961 | { | ||
962 | return platform_driver_unregister(&au1k_irda_driver); | ||
963 | } | ||
964 | |||
832 | MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>"); | 965 | MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>"); |
833 | MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); | 966 | MODULE_DESCRIPTION("Au1000 IrDA Device Driver"); |
834 | 967 | ||
835 | module_init(au1k_irda_init); | 968 | module_init(au1k_irda_load); |
836 | module_exit(au1k_irda_exit); | 969 | module_exit(au1k_irda_unload); |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 6e318ce41136..f9e3fb3a285b 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -155,18 +155,14 @@ config PCMCIA_M8XX | |||
155 | 155 | ||
156 | This driver is also available as a module called m8xx_pcmcia. | 156 | This driver is also available as a module called m8xx_pcmcia. |
157 | 157 | ||
158 | config PCMCIA_AU1X00 | ||
159 | tristate "Au1x00 pcmcia support" | ||
160 | depends on MIPS_ALCHEMY && PCMCIA | ||
161 | |||
162 | config PCMCIA_ALCHEMY_DEVBOARD | 158 | config PCMCIA_ALCHEMY_DEVBOARD |
163 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" | 159 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" |
164 | depends on MIPS_ALCHEMY && PCMCIA | 160 | depends on MIPS_ALCHEMY && PCMCIA |
165 | select 64BIT_PHYS_ADDR | 161 | select 64BIT_PHYS_ADDR |
166 | help | 162 | help |
167 | Enable this driver of you want PCMCIA support on your Alchemy | 163 | Enable this driver of you want PCMCIA support on your Alchemy |
168 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board. | 164 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 |
169 | NOT suitable for the PB1000! | 165 | board. NOT suitable for the PB1000! |
170 | 166 | ||
171 | This driver is also available as a module called db1xxx_ss.ko | 167 | This driver is also available as a module called db1xxx_ss.ko |
172 | 168 | ||
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile index 29935ea921df..ec543a4ff2e4 100644 --- a/drivers/pcmcia/Makefile +++ b/drivers/pcmcia/Makefile | |||
@@ -29,7 +29,6 @@ obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o | |||
29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o | 29 | obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o |
30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o | 30 | obj-$(CONFIG_M32R_PCC) += m32r_pcc.o |
31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o | 31 | obj-$(CONFIG_M32R_CFC) += m32r_cfc.o |
32 | obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o | ||
33 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o | 32 | obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o |
34 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o | 33 | obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o |
35 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o | 34 | obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o |
@@ -39,9 +38,6 @@ obj-$(CONFIG_AT91_CF) += at91_cf.o | |||
39 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o | 38 | obj-$(CONFIG_ELECTRA_CF) += electra_cf.o |
40 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o | 39 | obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o |
41 | 40 | ||
42 | au1x00_ss-y += au1000_generic.o | ||
43 | au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o | ||
44 | |||
45 | sa1111_cs-y += sa1111_generic.o | 41 | sa1111_cs-y += sa1111_generic.o |
46 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o | 42 | sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o |
47 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o | 43 | sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o |
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c deleted file mode 100644 index 95dd7c62741f..000000000000 --- a/drivers/pcmcia/au1000_generic.c +++ /dev/null | |||
@@ -1,545 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Alchemy Semi Au1000 pcmcia driver | ||
4 | * | ||
5 | * Copyright 2001-2003 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * ppopov@embeddedalley.com or source@mvista.com | ||
8 | * | ||
9 | * Copyright 2004 Pete Popov, Embedded Alley Solutions, Inc. | ||
10 | * Updated the driver to 2.6. Followed the sa11xx API and largely | ||
11 | * copied many of the hardware independent functions. | ||
12 | * | ||
13 | * ######################################################################## | ||
14 | * | ||
15 | * This program is free software; you can distribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License (Version 2) as | ||
17 | * published by the Free Software Foundation. | ||
18 | * | ||
19 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
20 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
21 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
22 | * for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
27 | * | ||
28 | * ######################################################################## | ||
29 | * | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/moduleparam.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/cpufreq.h> | ||
37 | #include <linux/ioport.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/timer.h> | ||
40 | #include <linux/mm.h> | ||
41 | #include <linux/notifier.h> | ||
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/mutex.h> | ||
45 | #include <linux/platform_device.h> | ||
46 | #include <linux/slab.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | #include <asm/irq.h> | ||
50 | #include <asm/system.h> | ||
51 | |||
52 | #include <asm/mach-au1x00/au1000.h> | ||
53 | #include "au1000_generic.h" | ||
54 | |||
55 | MODULE_LICENSE("GPL"); | ||
56 | MODULE_AUTHOR("Pete Popov <ppopov@embeddedalley.com>"); | ||
57 | MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller"); | ||
58 | |||
59 | #if 0 | ||
60 | #define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args) | ||
61 | #else | ||
62 | #define debug(x,args...) | ||
63 | #endif | ||
64 | |||
65 | #define MAP_SIZE 0x100000 | ||
66 | extern struct au1000_pcmcia_socket au1000_pcmcia_socket[]; | ||
67 | #define PCMCIA_SOCKET(x) (au1000_pcmcia_socket + (x)) | ||
68 | #define to_au1000_socket(x) container_of(x, struct au1000_pcmcia_socket, socket) | ||
69 | |||
70 | /* Some boards like to support CF cards as IDE root devices, so they | ||
71 | * grab pcmcia sockets directly. | ||
72 | */ | ||
73 | u32 *pcmcia_base_vaddrs[2]; | ||
74 | extern const unsigned long mips_io_port_base; | ||
75 | |||
76 | static DEFINE_MUTEX(pcmcia_sockets_lock); | ||
77 | |||
78 | static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = { | ||
79 | au1x_board_init, | ||
80 | }; | ||
81 | |||
82 | static int | ||
83 | au1x00_pcmcia_skt_state(struct au1000_pcmcia_socket *skt) | ||
84 | { | ||
85 | struct pcmcia_state state; | ||
86 | unsigned int stat; | ||
87 | |||
88 | memset(&state, 0, sizeof(struct pcmcia_state)); | ||
89 | |||
90 | skt->ops->socket_state(skt, &state); | ||
91 | |||
92 | stat = state.detect ? SS_DETECT : 0; | ||
93 | stat |= state.ready ? SS_READY : 0; | ||
94 | stat |= state.wrprot ? SS_WRPROT : 0; | ||
95 | stat |= state.vs_3v ? SS_3VCARD : 0; | ||
96 | stat |= state.vs_Xv ? SS_XVCARD : 0; | ||
97 | stat |= skt->cs_state.Vcc ? SS_POWERON : 0; | ||
98 | |||
99 | if (skt->cs_state.flags & SS_IOCARD) | ||
100 | stat |= state.bvd1 ? SS_STSCHG : 0; | ||
101 | else { | ||
102 | if (state.bvd1 == 0) | ||
103 | stat |= SS_BATDEAD; | ||
104 | else if (state.bvd2 == 0) | ||
105 | stat |= SS_BATWARN; | ||
106 | } | ||
107 | return stat; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * au100_pcmcia_config_skt | ||
112 | * | ||
113 | * Convert PCMCIA socket state to our socket configure structure. | ||
114 | */ | ||
115 | static int | ||
116 | au1x00_pcmcia_config_skt(struct au1000_pcmcia_socket *skt, socket_state_t *state) | ||
117 | { | ||
118 | int ret; | ||
119 | |||
120 | ret = skt->ops->configure_socket(skt, state); | ||
121 | if (ret == 0) { | ||
122 | skt->cs_state = *state; | ||
123 | } | ||
124 | |||
125 | if (ret < 0) | ||
126 | debug("unable to configure socket %d\n", skt->nr); | ||
127 | |||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | /* au1x00_pcmcia_sock_init() | ||
132 | * | ||
133 | * (Re-)Initialise the socket, turning on status interrupts | ||
134 | * and PCMCIA bus. This must wait for power to stabilise | ||
135 | * so that the card status signals report correctly. | ||
136 | * | ||
137 | * Returns: 0 | ||
138 | */ | ||
139 | static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock) | ||
140 | { | ||
141 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
142 | |||
143 | debug("initializing socket %u\n", skt->nr); | ||
144 | |||
145 | skt->ops->socket_init(skt); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * au1x00_pcmcia_suspend() | ||
151 | * | ||
152 | * Remove power on the socket, disable IRQs from the card. | ||
153 | * Turn off status interrupts, and disable the PCMCIA bus. | ||
154 | * | ||
155 | * Returns: 0 | ||
156 | */ | ||
157 | static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock) | ||
158 | { | ||
159 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
160 | |||
161 | debug("suspending socket %u\n", skt->nr); | ||
162 | |||
163 | skt->ops->socket_suspend(skt); | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static DEFINE_SPINLOCK(status_lock); | ||
169 | |||
170 | /* | ||
171 | * au1x00_check_status() | ||
172 | */ | ||
173 | static void au1x00_check_status(struct au1000_pcmcia_socket *skt) | ||
174 | { | ||
175 | unsigned int events; | ||
176 | |||
177 | debug("entering PCMCIA monitoring thread\n"); | ||
178 | |||
179 | do { | ||
180 | unsigned int status; | ||
181 | unsigned long flags; | ||
182 | |||
183 | status = au1x00_pcmcia_skt_state(skt); | ||
184 | |||
185 | spin_lock_irqsave(&status_lock, flags); | ||
186 | events = (status ^ skt->status) & skt->cs_state.csc_mask; | ||
187 | skt->status = status; | ||
188 | spin_unlock_irqrestore(&status_lock, flags); | ||
189 | |||
190 | debug("events: %s%s%s%s%s%s\n", | ||
191 | events == 0 ? "<NONE>" : "", | ||
192 | events & SS_DETECT ? "DETECT " : "", | ||
193 | events & SS_READY ? "READY " : "", | ||
194 | events & SS_BATDEAD ? "BATDEAD " : "", | ||
195 | events & SS_BATWARN ? "BATWARN " : "", | ||
196 | events & SS_STSCHG ? "STSCHG " : ""); | ||
197 | |||
198 | if (events) | ||
199 | pcmcia_parse_events(&skt->socket, events); | ||
200 | } while (events); | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * au1x00_pcmcia_poll_event() | ||
205 | * Let's poll for events in addition to IRQs since IRQ only is unreliable... | ||
206 | */ | ||
207 | static void au1x00_pcmcia_poll_event(unsigned long dummy) | ||
208 | { | ||
209 | struct au1000_pcmcia_socket *skt = (struct au1000_pcmcia_socket *)dummy; | ||
210 | debug("polling for events\n"); | ||
211 | |||
212 | mod_timer(&skt->poll_timer, jiffies + AU1000_PCMCIA_POLL_PERIOD); | ||
213 | |||
214 | au1x00_check_status(skt); | ||
215 | } | ||
216 | |||
217 | /* au1x00_pcmcia_get_status() | ||
218 | * | ||
219 | * From the sa11xx_core.c: | ||
220 | * Implements the get_status() operation for the in-kernel PCMCIA | ||
221 | * service (formerly SS_GetStatus in Card Services). Essentially just | ||
222 | * fills in bits in `status' according to internal driver state or | ||
223 | * the value of the voltage detect chipselect register. | ||
224 | * | ||
225 | * As a debugging note, during card startup, the PCMCIA core issues | ||
226 | * three set_socket() commands in a row the first with RESET deasserted, | ||
227 | * the second with RESET asserted, and the last with RESET deasserted | ||
228 | * again. Following the third set_socket(), a get_status() command will | ||
229 | * be issued. The kernel is looking for the SS_READY flag (see | ||
230 | * setup_socket(), reset_socket(), and unreset_socket() in cs.c). | ||
231 | * | ||
232 | * Returns: 0 | ||
233 | */ | ||
234 | static int | ||
235 | au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status) | ||
236 | { | ||
237 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
238 | |||
239 | skt->status = au1x00_pcmcia_skt_state(skt); | ||
240 | *status = skt->status; | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* au1x00_pcmcia_set_socket() | ||
246 | * Implements the set_socket() operation for the in-kernel PCMCIA | ||
247 | * service (formerly SS_SetSocket in Card Services). We more or | ||
248 | * less punt all of this work and let the kernel handle the details | ||
249 | * of power configuration, reset, &c. We also record the value of | ||
250 | * `state' in order to regurgitate it to the PCMCIA core later. | ||
251 | * | ||
252 | * Returns: 0 | ||
253 | */ | ||
254 | static int | ||
255 | au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state) | ||
256 | { | ||
257 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
258 | |||
259 | debug("for sock %u\n", skt->nr); | ||
260 | |||
261 | debug("\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n", | ||
262 | (state->csc_mask==0)?"<NONE>":"", | ||
263 | (state->csc_mask&SS_DETECT)?"DETECT ":"", | ||
264 | (state->csc_mask&SS_READY)?"READY ":"", | ||
265 | (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", | ||
266 | (state->csc_mask&SS_BATWARN)?"BATWARN ":"", | ||
267 | (state->csc_mask&SS_STSCHG)?"STSCHG ":"", | ||
268 | (state->flags==0)?"<NONE>":"", | ||
269 | (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", | ||
270 | (state->flags&SS_IOCARD)?"IOCARD ":"", | ||
271 | (state->flags&SS_RESET)?"RESET ":"", | ||
272 | (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", | ||
273 | (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":""); | ||
274 | debug("\tVcc %d Vpp %d irq %d\n", | ||
275 | state->Vcc, state->Vpp, state->io_irq); | ||
276 | |||
277 | return au1x00_pcmcia_config_skt(skt, state); | ||
278 | } | ||
279 | |||
280 | int | ||
281 | au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map) | ||
282 | { | ||
283 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
284 | unsigned int speed; | ||
285 | |||
286 | if(map->map>=MAX_IO_WIN){ | ||
287 | debug("map (%d) out of range\n", map->map); | ||
288 | return -1; | ||
289 | } | ||
290 | |||
291 | if(map->flags&MAP_ACTIVE){ | ||
292 | speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED; | ||
293 | skt->spd_io[map->map] = speed; | ||
294 | } | ||
295 | |||
296 | map->start=(unsigned int)(u32)skt->virt_io; | ||
297 | map->stop=map->start+MAP_SIZE; | ||
298 | return 0; | ||
299 | |||
300 | } /* au1x00_pcmcia_set_io_map() */ | ||
301 | |||
302 | |||
303 | static int | ||
304 | au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) | ||
305 | { | ||
306 | struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); | ||
307 | unsigned short speed = map->speed; | ||
308 | |||
309 | if(map->map>=MAX_WIN){ | ||
310 | debug("map (%d) out of range\n", map->map); | ||
311 | return -1; | ||
312 | } | ||
313 | |||
314 | if (map->flags & MAP_ATTRIB) { | ||
315 | skt->spd_attr[map->map] = speed; | ||
316 | skt->spd_mem[map->map] = 0; | ||
317 | } else { | ||
318 | skt->spd_attr[map->map] = 0; | ||
319 | skt->spd_mem[map->map] = speed; | ||
320 | } | ||
321 | |||
322 | if (map->flags & MAP_ATTRIB) { | ||
323 | map->static_start = skt->phys_attr + map->card_start; | ||
324 | } | ||
325 | else { | ||
326 | map->static_start = skt->phys_mem + map->card_start; | ||
327 | } | ||
328 | |||
329 | debug("set_mem_map %d start %08lx card_start %08x\n", | ||
330 | map->map, map->static_start, map->card_start); | ||
331 | return 0; | ||
332 | |||
333 | } /* au1x00_pcmcia_set_mem_map() */ | ||
334 | |||
335 | static struct pccard_operations au1x00_pcmcia_operations = { | ||
336 | .init = au1x00_pcmcia_sock_init, | ||
337 | .suspend = au1x00_pcmcia_suspend, | ||
338 | .get_status = au1x00_pcmcia_get_status, | ||
339 | .set_socket = au1x00_pcmcia_set_socket, | ||
340 | .set_io_map = au1x00_pcmcia_set_io_map, | ||
341 | .set_mem_map = au1x00_pcmcia_set_mem_map, | ||
342 | }; | ||
343 | |||
344 | static const char *skt_names[] = { | ||
345 | "PCMCIA socket 0", | ||
346 | "PCMCIA socket 1", | ||
347 | }; | ||
348 | |||
349 | struct skt_dev_info { | ||
350 | int nskt; | ||
351 | }; | ||
352 | |||
353 | int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr) | ||
354 | { | ||
355 | struct skt_dev_info *sinfo; | ||
356 | struct au1000_pcmcia_socket *skt; | ||
357 | int ret, i; | ||
358 | |||
359 | sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL); | ||
360 | if (!sinfo) { | ||
361 | ret = -ENOMEM; | ||
362 | goto out; | ||
363 | } | ||
364 | |||
365 | sinfo->nskt = nr; | ||
366 | |||
367 | /* | ||
368 | * Initialise the per-socket structure. | ||
369 | */ | ||
370 | for (i = 0; i < nr; i++) { | ||
371 | skt = PCMCIA_SOCKET(i); | ||
372 | memset(skt, 0, sizeof(*skt)); | ||
373 | |||
374 | skt->socket.resource_ops = &pccard_static_ops; | ||
375 | skt->socket.ops = &au1x00_pcmcia_operations; | ||
376 | skt->socket.owner = ops->owner; | ||
377 | skt->socket.dev.parent = dev; | ||
378 | |||
379 | init_timer(&skt->poll_timer); | ||
380 | skt->poll_timer.function = au1x00_pcmcia_poll_event; | ||
381 | skt->poll_timer.data = (unsigned long)skt; | ||
382 | skt->poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD; | ||
383 | |||
384 | skt->nr = first + i; | ||
385 | skt->irq = 255; | ||
386 | skt->dev = dev; | ||
387 | skt->ops = ops; | ||
388 | |||
389 | skt->res_skt.name = skt_names[skt->nr]; | ||
390 | skt->res_io.name = "io"; | ||
391 | skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
392 | skt->res_mem.name = "memory"; | ||
393 | skt->res_mem.flags = IORESOURCE_MEM; | ||
394 | skt->res_attr.name = "attribute"; | ||
395 | skt->res_attr.flags = IORESOURCE_MEM; | ||
396 | |||
397 | /* | ||
398 | * PCMCIA client drivers use the inb/outb macros to access the | ||
399 | * IO registers. Since mips_io_port_base is added to the | ||
400 | * access address of the mips implementation of inb/outb, | ||
401 | * we need to subtract it here because we want to access the | ||
402 | * I/O or MEM address directly, without going through this | ||
403 | * "mips_io_port_base" mechanism. | ||
404 | */ | ||
405 | if (i == 0) { | ||
406 | skt->virt_io = (void *) | ||
407 | (ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) - | ||
408 | (u32)mips_io_port_base); | ||
409 | skt->phys_attr = AU1X_SOCK0_PHYS_ATTR; | ||
410 | skt->phys_mem = AU1X_SOCK0_PHYS_MEM; | ||
411 | } | ||
412 | else { | ||
413 | skt->virt_io = (void *) | ||
414 | (ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) - | ||
415 | (u32)mips_io_port_base); | ||
416 | skt->phys_attr = AU1X_SOCK1_PHYS_ATTR; | ||
417 | skt->phys_mem = AU1X_SOCK1_PHYS_MEM; | ||
418 | } | ||
419 | pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io; | ||
420 | ret = ops->hw_init(skt); | ||
421 | |||
422 | skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD; | ||
423 | skt->socket.irq_mask = 0; | ||
424 | skt->socket.map_size = MAP_SIZE; | ||
425 | skt->socket.pci_irq = skt->irq; | ||
426 | skt->socket.io_offset = (unsigned long)skt->virt_io; | ||
427 | |||
428 | skt->status = au1x00_pcmcia_skt_state(skt); | ||
429 | |||
430 | ret = pcmcia_register_socket(&skt->socket); | ||
431 | if (ret) | ||
432 | goto out_err; | ||
433 | |||
434 | WARN_ON(skt->socket.sock != i); | ||
435 | |||
436 | add_timer(&skt->poll_timer); | ||
437 | } | ||
438 | |||
439 | dev_set_drvdata(dev, sinfo); | ||
440 | return 0; | ||
441 | |||
442 | |||
443 | out_err: | ||
444 | ops->hw_shutdown(skt); | ||
445 | while (i-- > 0) { | ||
446 | skt = PCMCIA_SOCKET(i); | ||
447 | |||
448 | del_timer_sync(&skt->poll_timer); | ||
449 | pcmcia_unregister_socket(&skt->socket); | ||
450 | if (i == 0) { | ||
451 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
452 | skt->virt_io = NULL; | ||
453 | } | ||
454 | #ifndef CONFIG_MIPS_XXS1500 | ||
455 | else { | ||
456 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
457 | skt->virt_io = NULL; | ||
458 | } | ||
459 | #endif | ||
460 | ops->hw_shutdown(skt); | ||
461 | |||
462 | } | ||
463 | kfree(sinfo); | ||
464 | out: | ||
465 | return ret; | ||
466 | } | ||
467 | |||
468 | int au1x00_drv_pcmcia_remove(struct platform_device *dev) | ||
469 | { | ||
470 | struct skt_dev_info *sinfo = platform_get_drvdata(dev); | ||
471 | int i; | ||
472 | |||
473 | mutex_lock(&pcmcia_sockets_lock); | ||
474 | platform_set_drvdata(dev, NULL); | ||
475 | |||
476 | for (i = 0; i < sinfo->nskt; i++) { | ||
477 | struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i); | ||
478 | |||
479 | del_timer_sync(&skt->poll_timer); | ||
480 | pcmcia_unregister_socket(&skt->socket); | ||
481 | skt->ops->hw_shutdown(skt); | ||
482 | au1x00_pcmcia_config_skt(skt, &dead_socket); | ||
483 | iounmap(skt->virt_io + (u32)mips_io_port_base); | ||
484 | skt->virt_io = NULL; | ||
485 | } | ||
486 | |||
487 | kfree(sinfo); | ||
488 | mutex_unlock(&pcmcia_sockets_lock); | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | |||
493 | /* | ||
494 | * PCMCIA "Driver" API | ||
495 | */ | ||
496 | |||
497 | static int au1x00_drv_pcmcia_probe(struct platform_device *dev) | ||
498 | { | ||
499 | int i, ret = -ENODEV; | ||
500 | |||
501 | mutex_lock(&pcmcia_sockets_lock); | ||
502 | for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) { | ||
503 | ret = au1x00_pcmcia_hw_init[i](&dev->dev); | ||
504 | if (ret == 0) | ||
505 | break; | ||
506 | } | ||
507 | mutex_unlock(&pcmcia_sockets_lock); | ||
508 | return ret; | ||
509 | } | ||
510 | |||
511 | static struct platform_driver au1x00_pcmcia_driver = { | ||
512 | .driver = { | ||
513 | .name = "au1x00-pcmcia", | ||
514 | .owner = THIS_MODULE, | ||
515 | }, | ||
516 | .probe = au1x00_drv_pcmcia_probe, | ||
517 | .remove = au1x00_drv_pcmcia_remove, | ||
518 | }; | ||
519 | |||
520 | |||
521 | /* au1x00_pcmcia_init() | ||
522 | * | ||
523 | * This routine performs low-level PCMCIA initialization and then | ||
524 | * registers this socket driver with Card Services. | ||
525 | * | ||
526 | * Returns: 0 on success, -ve error code on failure | ||
527 | */ | ||
528 | static int __init au1x00_pcmcia_init(void) | ||
529 | { | ||
530 | int error = 0; | ||
531 | error = platform_driver_register(&au1x00_pcmcia_driver); | ||
532 | return error; | ||
533 | } | ||
534 | |||
535 | /* au1x00_pcmcia_exit() | ||
536 | * Invokes the low-level kernel service to free IRQs associated with this | ||
537 | * socket controller and reset GPIO edge detection. | ||
538 | */ | ||
539 | static void __exit au1x00_pcmcia_exit(void) | ||
540 | { | ||
541 | platform_driver_unregister(&au1x00_pcmcia_driver); | ||
542 | } | ||
543 | |||
544 | module_init(au1x00_pcmcia_init); | ||
545 | module_exit(au1x00_pcmcia_exit); | ||
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h deleted file mode 100644 index 5c36bda2963b..000000000000 --- a/drivers/pcmcia/au1000_generic.h +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /* | ||
2 | * Alchemy Semi Au1000 pcmcia driver include file | ||
3 | * | ||
4 | * Copyright 2001 MontaVista Software Inc. | ||
5 | * Author: MontaVista Software, Inc. | ||
6 | * ppopov@mvista.com or source@mvista.com | ||
7 | * | ||
8 | * This program is free software; you can distribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License (Version 2) as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
15 | * for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along | ||
18 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
20 | */ | ||
21 | #ifndef __ASM_AU1000_PCMCIA_H | ||
22 | #define __ASM_AU1000_PCMCIA_H | ||
23 | |||
24 | /* include the world */ | ||
25 | |||
26 | #include <pcmcia/ss.h> | ||
27 | #include <pcmcia/cistpl.h> | ||
28 | #include "cs_internal.h" | ||
29 | |||
30 | #define AU1000_PCMCIA_POLL_PERIOD (2*HZ) | ||
31 | #define AU1000_PCMCIA_IO_SPEED (255) | ||
32 | #define AU1000_PCMCIA_MEM_SPEED (300) | ||
33 | |||
34 | #define AU1X_SOCK0_IO 0xF00000000ULL | ||
35 | #define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL | ||
36 | #define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL | ||
37 | |||
38 | /* pcmcia socket 1 needs external glue logic so the memory map | ||
39 | * differs from board to board. | ||
40 | */ | ||
41 | #if defined(CONFIG_MIPS_PB1000) | ||
42 | #define AU1X_SOCK1_IO 0xF08000000ULL | ||
43 | #define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL | ||
44 | #define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL | ||
45 | #endif | ||
46 | |||
47 | struct pcmcia_state { | ||
48 | unsigned detect: 1, | ||
49 | ready: 1, | ||
50 | wrprot: 1, | ||
51 | bvd1: 1, | ||
52 | bvd2: 1, | ||
53 | vs_3v: 1, | ||
54 | vs_Xv: 1; | ||
55 | }; | ||
56 | |||
57 | struct pcmcia_configure { | ||
58 | unsigned sock: 8, | ||
59 | vcc: 8, | ||
60 | vpp: 8, | ||
61 | output: 1, | ||
62 | speaker: 1, | ||
63 | reset: 1; | ||
64 | }; | ||
65 | |||
66 | struct pcmcia_irqs { | ||
67 | int sock; | ||
68 | int irq; | ||
69 | const char *str; | ||
70 | }; | ||
71 | |||
72 | |||
73 | struct au1000_pcmcia_socket { | ||
74 | struct pcmcia_socket socket; | ||
75 | |||
76 | /* | ||
77 | * Info from low level handler | ||
78 | */ | ||
79 | struct device *dev; | ||
80 | unsigned int nr; | ||
81 | unsigned int irq; | ||
82 | |||
83 | /* | ||
84 | * Core PCMCIA state | ||
85 | */ | ||
86 | struct pcmcia_low_level *ops; | ||
87 | |||
88 | unsigned int status; | ||
89 | socket_state_t cs_state; | ||
90 | |||
91 | unsigned short spd_io[MAX_IO_WIN]; | ||
92 | unsigned short spd_mem[MAX_WIN]; | ||
93 | unsigned short spd_attr[MAX_WIN]; | ||
94 | |||
95 | struct resource res_skt; | ||
96 | struct resource res_io; | ||
97 | struct resource res_mem; | ||
98 | struct resource res_attr; | ||
99 | |||
100 | void * virt_io; | ||
101 | unsigned int phys_io; | ||
102 | unsigned int phys_attr; | ||
103 | unsigned int phys_mem; | ||
104 | unsigned short speed_io, speed_attr, speed_mem; | ||
105 | |||
106 | unsigned int irq_state; | ||
107 | |||
108 | struct timer_list poll_timer; | ||
109 | }; | ||
110 | |||
111 | struct pcmcia_low_level { | ||
112 | struct module *owner; | ||
113 | |||
114 | int (*hw_init)(struct au1000_pcmcia_socket *); | ||
115 | void (*hw_shutdown)(struct au1000_pcmcia_socket *); | ||
116 | |||
117 | void (*socket_state)(struct au1000_pcmcia_socket *, struct pcmcia_state *); | ||
118 | int (*configure_socket)(struct au1000_pcmcia_socket *, struct socket_state_t *); | ||
119 | |||
120 | /* | ||
121 | * Enable card status IRQs on (re-)initialisation. This can | ||
122 | * be called at initialisation, power management event, or | ||
123 | * pcmcia event. | ||
124 | */ | ||
125 | void (*socket_init)(struct au1000_pcmcia_socket *); | ||
126 | |||
127 | /* | ||
128 | * Disable card status IRQs and PCMCIA bus on suspend. | ||
129 | */ | ||
130 | void (*socket_suspend)(struct au1000_pcmcia_socket *); | ||
131 | }; | ||
132 | |||
133 | extern int au1x_board_init(struct device *dev); | ||
134 | |||
135 | #endif /* __ASM_AU1000_PCMCIA_H */ | ||
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c deleted file mode 100644 index b2396647a165..000000000000 --- a/drivers/pcmcia/au1000_pb1x00.c +++ /dev/null | |||
@@ -1,294 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Alchemy Semi Pb1000 boards specific pcmcia routines. | ||
4 | * | ||
5 | * Copyright 2002 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * ppopov@mvista.com or source@mvista.com | ||
8 | * | ||
9 | * ######################################################################## | ||
10 | * | ||
11 | * This program is free software; you can distribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License (Version 2) as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
16 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
18 | * for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
23 | */ | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/ioport.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/proc_fs.h> | ||
32 | #include <linux/types.h> | ||
33 | |||
34 | #include <pcmcia/ss.h> | ||
35 | #include <pcmcia/cistpl.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/system.h> | ||
40 | |||
41 | #include <asm/au1000.h> | ||
42 | #include <asm/au1000_pcmcia.h> | ||
43 | |||
44 | #define debug(fmt, arg...) do { } while (0) | ||
45 | |||
46 | #include <asm/pb1000.h> | ||
47 | #define PCMCIA_IRQ AU1000_GPIO_15 | ||
48 | |||
49 | static int pb1x00_pcmcia_init(struct pcmcia_init *init) | ||
50 | { | ||
51 | u16 pcr; | ||
52 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
53 | |||
54 | au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */ | ||
55 | au_sync_delay(100); | ||
56 | au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */ | ||
57 | au_sync(); | ||
58 | |||
59 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
60 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
61 | au_writel(pcr, PB1000_PCR); | ||
62 | au_sync_delay(20); | ||
63 | |||
64 | return PCMCIA_NUM_SOCKS; | ||
65 | } | ||
66 | |||
67 | static int pb1x00_pcmcia_shutdown(void) | ||
68 | { | ||
69 | u16 pcr; | ||
70 | pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST; | ||
71 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0); | ||
72 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1); | ||
73 | au_writel(pcr, PB1000_PCR); | ||
74 | au_sync_delay(20); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int | ||
79 | pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) | ||
80 | { | ||
81 | u32 inserted0, inserted1; | ||
82 | u16 vs0, vs1; | ||
83 | |||
84 | vs0 = vs1 = (u16)au_readl(PB1000_ACR1); | ||
85 | inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2)); | ||
86 | inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2)); | ||
87 | vs0 = (vs0 >> 4) & 0x3; | ||
88 | vs1 = (vs1 >> 12) & 0x3; | ||
89 | |||
90 | state->ready = 0; | ||
91 | state->vs_Xv = 0; | ||
92 | state->vs_3v = 0; | ||
93 | state->detect = 0; | ||
94 | |||
95 | if (sock == 0) { | ||
96 | if (inserted0) { | ||
97 | switch (vs0) { | ||
98 | case 0: | ||
99 | case 2: | ||
100 | state->vs_3v=1; | ||
101 | break; | ||
102 | case 3: /* 5V */ | ||
103 | break; | ||
104 | default: | ||
105 | /* return without setting 'detect' */ | ||
106 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
107 | vs0); | ||
108 | return 0; | ||
109 | } | ||
110 | state->detect = 1; | ||
111 | } | ||
112 | } | ||
113 | else { | ||
114 | if (inserted1) { | ||
115 | switch (vs1) { | ||
116 | case 0: | ||
117 | case 2: | ||
118 | state->vs_3v=1; | ||
119 | break; | ||
120 | case 3: /* 5V */ | ||
121 | break; | ||
122 | default: | ||
123 | /* return without setting 'detect' */ | ||
124 | printk(KERN_ERR "pb1x00 bad VS (%d)\n", | ||
125 | vs1); | ||
126 | return 0; | ||
127 | } | ||
128 | state->detect = 1; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | if (state->detect) { | ||
133 | state->ready = 1; | ||
134 | } | ||
135 | |||
136 | state->bvd1=1; | ||
137 | state->bvd2=1; | ||
138 | state->wrprot=0; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | |||
143 | static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info) | ||
144 | { | ||
145 | |||
146 | if(info->sock > PCMCIA_MAX_SOCK) return -1; | ||
147 | |||
148 | /* | ||
149 | * Even in the case of the Pb1000, both sockets are connected | ||
150 | * to the same irq line. | ||
151 | */ | ||
152 | info->irq = PCMCIA_IRQ; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | |||
158 | static int | ||
159 | pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure) | ||
160 | { | ||
161 | u16 pcr; | ||
162 | |||
163 | if(configure->sock > PCMCIA_MAX_SOCK) return -1; | ||
164 | |||
165 | pcr = au_readl(PB1000_PCR); | ||
166 | |||
167 | if (configure->sock == 0) { | ||
168 | pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 | | ||
169 | PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1); | ||
170 | } | ||
171 | else { | ||
172 | pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 | | ||
173 | PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1); | ||
174 | } | ||
175 | |||
176 | pcr &= ~PCR_SLOT_0_RST; | ||
177 | debug("Vcc %dV Vpp %dV, pcr %x\n", | ||
178 | configure->vcc, configure->vpp, pcr); | ||
179 | switch(configure->vcc){ | ||
180 | case 0: /* Vcc 0 */ | ||
181 | switch(configure->vpp) { | ||
182 | case 0: | ||
183 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND, | ||
184 | configure->sock); | ||
185 | break; | ||
186 | case 12: | ||
187 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V, | ||
188 | configure->sock); | ||
189 | break; | ||
190 | case 50: | ||
191 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V, | ||
192 | configure->sock); | ||
193 | break; | ||
194 | case 33: | ||
195 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V, | ||
196 | configure->sock); | ||
197 | break; | ||
198 | default: | ||
199 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
200 | configure->sock); | ||
201 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
202 | __func__, | ||
203 | configure->vcc, | ||
204 | configure->vpp); | ||
205 | break; | ||
206 | } | ||
207 | break; | ||
208 | case 50: /* Vcc 5V */ | ||
209 | switch(configure->vpp) { | ||
210 | case 0: | ||
211 | pcr |= SET_VCC_VPP(VCC_5V,VPP_GND, | ||
212 | configure->sock); | ||
213 | break; | ||
214 | case 50: | ||
215 | pcr |= SET_VCC_VPP(VCC_5V,VPP_5V, | ||
216 | configure->sock); | ||
217 | break; | ||
218 | case 12: | ||
219 | pcr |= SET_VCC_VPP(VCC_5V,VPP_12V, | ||
220 | configure->sock); | ||
221 | break; | ||
222 | case 33: | ||
223 | pcr |= SET_VCC_VPP(VCC_5V,VPP_3V, | ||
224 | configure->sock); | ||
225 | break; | ||
226 | default: | ||
227 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
228 | configure->sock); | ||
229 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
230 | __func__, | ||
231 | configure->vcc, | ||
232 | configure->vpp); | ||
233 | break; | ||
234 | } | ||
235 | break; | ||
236 | case 33: /* Vcc 3.3V */ | ||
237 | switch(configure->vpp) { | ||
238 | case 0: | ||
239 | pcr |= SET_VCC_VPP(VCC_3V,VPP_GND, | ||
240 | configure->sock); | ||
241 | break; | ||
242 | case 50: | ||
243 | pcr |= SET_VCC_VPP(VCC_3V,VPP_5V, | ||
244 | configure->sock); | ||
245 | break; | ||
246 | case 12: | ||
247 | pcr |= SET_VCC_VPP(VCC_3V,VPP_12V, | ||
248 | configure->sock); | ||
249 | break; | ||
250 | case 33: | ||
251 | pcr |= SET_VCC_VPP(VCC_3V,VPP_3V, | ||
252 | configure->sock); | ||
253 | break; | ||
254 | default: | ||
255 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ, | ||
256 | configure->sock); | ||
257 | printk("%s: bad Vcc/Vpp (%d:%d)\n", | ||
258 | __func__, | ||
259 | configure->vcc, | ||
260 | configure->vpp); | ||
261 | break; | ||
262 | } | ||
263 | break; | ||
264 | default: /* what's this ? */ | ||
265 | pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock); | ||
266 | printk(KERN_ERR "%s: bad Vcc %d\n", | ||
267 | __func__, configure->vcc); | ||
268 | break; | ||
269 | } | ||
270 | |||
271 | if (configure->sock == 0) { | ||
272 | pcr &= ~(PCR_SLOT_0_RST); | ||
273 | if (configure->reset) | ||
274 | pcr |= PCR_SLOT_0_RST; | ||
275 | } | ||
276 | else { | ||
277 | pcr &= ~(PCR_SLOT_1_RST); | ||
278 | if (configure->reset) | ||
279 | pcr |= PCR_SLOT_1_RST; | ||
280 | } | ||
281 | au_writel(pcr, PB1000_PCR); | ||
282 | au_sync_delay(300); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | |||
288 | struct pcmcia_low_level pb1x00_pcmcia_ops = { | ||
289 | pb1x00_pcmcia_init, | ||
290 | pb1x00_pcmcia_shutdown, | ||
291 | pb1x00_pcmcia_socket_state, | ||
292 | pb1x00_pcmcia_get_irq_info, | ||
293 | pb1x00_pcmcia_configure_socket | ||
294 | }; | ||
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 3e49df6d5e3b..5b7c22784aff 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | /* This is a fairly generic PCMCIA socket driver suitable for the | 8 | /* This is a fairly generic PCMCIA socket driver suitable for the |
9 | * following Alchemy Development boards: | 9 | * following Alchemy Development boards: |
10 | * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200. | 10 | * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200, Db1300 |
11 | * | 11 | * |
12 | * The Db1000 is used as a reference: Per-socket card-, carddetect- and | 12 | * The Db1000 is used as a reference: Per-socket card-, carddetect- and |
13 | * statuschange IRQs connected to SoC GPIOs, control and status register | 13 | * statuschange IRQs connected to SoC GPIOs, control and status register |
@@ -18,6 +18,7 @@ | |||
18 | * - Pb1100/Pb1500: single socket only; voltage key bits VS are | 18 | * - Pb1100/Pb1500: single socket only; voltage key bits VS are |
19 | * at STATUS[5:4] (instead of STATUS[1:0]). | 19 | * at STATUS[5:4] (instead of STATUS[1:0]). |
20 | * - Au1200-based: additional card-eject irqs, irqs not gpios! | 20 | * - Au1200-based: additional card-eject irqs, irqs not gpios! |
21 | * - Db1300: Db1200-like, no pwr ctrl, single socket (#1). | ||
21 | */ | 22 | */ |
22 | 23 | ||
23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
@@ -59,11 +60,17 @@ struct db1x_pcmcia_sock { | |||
59 | #define BOARD_TYPE_DEFAULT 0 /* most boards */ | 60 | #define BOARD_TYPE_DEFAULT 0 /* most boards */ |
60 | #define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */ | 61 | #define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */ |
61 | #define BOARD_TYPE_PB1100 2 /* VS bits slightly different */ | 62 | #define BOARD_TYPE_PB1100 2 /* VS bits slightly different */ |
63 | #define BOARD_TYPE_DB1300 3 /* no power control */ | ||
62 | int board_type; | 64 | int board_type; |
63 | }; | 65 | }; |
64 | 66 | ||
65 | #define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket) | 67 | #define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket) |
66 | 68 | ||
69 | static int db1300_card_inserted(struct db1x_pcmcia_sock *sock) | ||
70 | { | ||
71 | return bcsr_read(BCSR_SIGSTAT) & (1 << 8); | ||
72 | } | ||
73 | |||
67 | /* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */ | 74 | /* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */ |
68 | static int db1200_card_inserted(struct db1x_pcmcia_sock *sock) | 75 | static int db1200_card_inserted(struct db1x_pcmcia_sock *sock) |
69 | { | 76 | { |
@@ -84,6 +91,8 @@ static int db1x_card_inserted(struct db1x_pcmcia_sock *sock) | |||
84 | switch (sock->board_type) { | 91 | switch (sock->board_type) { |
85 | case BOARD_TYPE_DB1200: | 92 | case BOARD_TYPE_DB1200: |
86 | return db1200_card_inserted(sock); | 93 | return db1200_card_inserted(sock); |
94 | case BOARD_TYPE_DB1300: | ||
95 | return db1300_card_inserted(sock); | ||
87 | default: | 96 | default: |
88 | return db1000_card_inserted(sock); | 97 | return db1000_card_inserted(sock); |
89 | } | 98 | } |
@@ -160,7 +169,8 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) | |||
160 | * ejection handler have been registered and the currently | 169 | * ejection handler have been registered and the currently |
161 | * active one disabled. | 170 | * active one disabled. |
162 | */ | 171 | */ |
163 | if (sock->board_type == BOARD_TYPE_DB1200) { | 172 | if ((sock->board_type == BOARD_TYPE_DB1200) || |
173 | (sock->board_type == BOARD_TYPE_DB1300)) { | ||
164 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, | 174 | ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, |
165 | IRQF_DISABLED, "pcmcia_insert", sock); | 175 | IRQF_DISABLED, "pcmcia_insert", sock); |
166 | if (ret) | 176 | if (ret) |
@@ -174,7 +184,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock) | |||
174 | } | 184 | } |
175 | 185 | ||
176 | /* enable the currently silent one */ | 186 | /* enable the currently silent one */ |
177 | if (db1200_card_inserted(sock)) | 187 | if (db1x_card_inserted(sock)) |
178 | enable_irq(sock->eject_irq); | 188 | enable_irq(sock->eject_irq); |
179 | else | 189 | else |
180 | enable_irq(sock->insert_irq); | 190 | enable_irq(sock->insert_irq); |
@@ -270,7 +280,8 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt, | |||
270 | } | 280 | } |
271 | 281 | ||
272 | /* create new voltage code */ | 282 | /* create new voltage code */ |
273 | cr_set |= ((v << 2) | p) << (sock->nr * 8); | 283 | if (sock->board_type != BOARD_TYPE_DB1300) |
284 | cr_set |= ((v << 2) | p) << (sock->nr * 8); | ||
274 | 285 | ||
275 | changed = state->flags ^ sock->old_flags; | 286 | changed = state->flags ^ sock->old_flags; |
276 | 287 | ||
@@ -343,6 +354,10 @@ static int db1x_pcmcia_get_status(struct pcmcia_socket *skt, | |||
343 | /* if Vcc is not zero, we have applied power to a card */ | 354 | /* if Vcc is not zero, we have applied power to a card */ |
344 | status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0; | 355 | status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0; |
345 | 356 | ||
357 | /* DB1300: power always on, but don't tell when no card present */ | ||
358 | if ((sock->board_type == BOARD_TYPE_DB1300) && (status & SS_DETECT)) | ||
359 | status = SS_POWERON | SS_3VCARD | SS_DETECT; | ||
360 | |||
346 | /* reset de-asserted? then we're ready */ | 361 | /* reset de-asserted? then we're ready */ |
347 | status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET; | 362 | status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET; |
348 | 363 | ||
@@ -419,6 +434,9 @@ static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev) | |||
419 | case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200: | 434 | case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200: |
420 | sock->board_type = BOARD_TYPE_DB1200; | 435 | sock->board_type = BOARD_TYPE_DB1200; |
421 | break; | 436 | break; |
437 | case BCSR_WHOAMI_DB1300: | ||
438 | sock->board_type = BOARD_TYPE_DB1300; | ||
439 | break; | ||
422 | default: | 440 | default: |
423 | printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); | 441 | printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid); |
424 | ret = -ENODEV; | 442 | ret = -ENODEV; |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1fd73df5416..369e092bf3d5 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -87,12 +87,12 @@ config SPI_BFIN_SPORT | |||
87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. | 87 | Enable support for a SPI bus via the Blackfin SPORT peripheral. |
88 | 88 | ||
89 | config SPI_AU1550 | 89 | config SPI_AU1550 |
90 | tristate "Au1550/Au12x0 SPI Controller" | 90 | tristate "Au1550/Au1200/Au1300 SPI Controller" |
91 | depends on MIPS_ALCHEMY && EXPERIMENTAL | 91 | depends on MIPS_ALCHEMY && EXPERIMENTAL |
92 | select SPI_BITBANG | 92 | select SPI_BITBANG |
93 | help | 93 | help |
94 | If you say yes to this option, support will be included for the | 94 | If you say yes to this option, support will be included for the |
95 | Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). | 95 | PSC SPI controller found on Au1550, Au1200 and Au1300 series. |
96 | 96 | ||
97 | config SPI_BITBANG | 97 | config SPI_BITBANG |
98 | tristate "Utilities for Bitbanging SPI masters" | 98 | tristate "Utilities for Bitbanging SPI masters" |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 925a1e547a83..95a0f5fe7d42 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1610,4 +1610,27 @@ config SERIAL_XILINX_PS_UART_CONSOLE | |||
1610 | help | 1610 | help |
1611 | Enable a Xilinx PS UART port to be the system console. | 1611 | Enable a Xilinx PS UART port to be the system console. |
1612 | 1612 | ||
1613 | config SERIAL_AR933X | ||
1614 | bool "AR933X serial port support" | ||
1615 | depends on SOC_AR933X | ||
1616 | select SERIAL_CORE | ||
1617 | help | ||
1618 | If you have an Atheros AR933X SOC based board and want to use the | ||
1619 | built-in UART of the SoC, say Y to this option. | ||
1620 | |||
1621 | config SERIAL_AR933X_CONSOLE | ||
1622 | bool "Console on AR933X serial port" | ||
1623 | depends on SERIAL_AR933X=y | ||
1624 | select SERIAL_CORE_CONSOLE | ||
1625 | help | ||
1626 | Enable a built-in UART port of the AR933X to be the system console. | ||
1627 | |||
1628 | config SERIAL_AR933X_NR_UARTS | ||
1629 | int "Maximum number of AR933X serial ports" | ||
1630 | depends on SERIAL_AR933X | ||
1631 | default "2" | ||
1632 | help | ||
1633 | Set this to the number of serial ports you want the driver | ||
1634 | to support. | ||
1635 | |||
1613 | endmenu | 1636 | endmenu |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index e10cf5b54b6d..76811cc58591 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -94,3 +94,4 @@ obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o | |||
94 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o | 94 | obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o |
95 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o | 95 | obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o |
96 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o | 96 | obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o |
97 | obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o | ||
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c new file mode 100644 index 000000000000..e4f60e2b87f3 --- /dev/null +++ b/drivers/tty/serial/ar933x_uart.c | |||
@@ -0,0 +1,688 @@ | |||
1 | /* | ||
2 | * Atheros AR933X SoC built-in UART driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * | ||
6 | * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/console.h> | ||
17 | #include <linux/sysrq.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/tty.h> | ||
21 | #include <linux/tty_flip.h> | ||
22 | #include <linux/serial_core.h> | ||
23 | #include <linux/serial.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/irq.h> | ||
27 | |||
28 | #include <asm/mach-ath79/ar933x_uart.h> | ||
29 | #include <asm/mach-ath79/ar933x_uart_platform.h> | ||
30 | |||
31 | #define DRIVER_NAME "ar933x-uart" | ||
32 | |||
33 | #define AR933X_DUMMY_STATUS_RD 0x01 | ||
34 | |||
35 | static struct uart_driver ar933x_uart_driver; | ||
36 | |||
37 | struct ar933x_uart_port { | ||
38 | struct uart_port port; | ||
39 | unsigned int ier; /* shadow Interrupt Enable Register */ | ||
40 | }; | ||
41 | |||
42 | static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, | ||
43 | int offset) | ||
44 | { | ||
45 | return readl(up->port.membase + offset); | ||
46 | } | ||
47 | |||
48 | static inline void ar933x_uart_write(struct ar933x_uart_port *up, | ||
49 | int offset, unsigned int value) | ||
50 | { | ||
51 | writel(value, up->port.membase + offset); | ||
52 | } | ||
53 | |||
54 | static inline void ar933x_uart_rmw(struct ar933x_uart_port *up, | ||
55 | unsigned int offset, | ||
56 | unsigned int mask, | ||
57 | unsigned int val) | ||
58 | { | ||
59 | unsigned int t; | ||
60 | |||
61 | t = ar933x_uart_read(up, offset); | ||
62 | t &= ~mask; | ||
63 | t |= val; | ||
64 | ar933x_uart_write(up, offset, t); | ||
65 | } | ||
66 | |||
67 | static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up, | ||
68 | unsigned int offset, | ||
69 | unsigned int val) | ||
70 | { | ||
71 | ar933x_uart_rmw(up, offset, 0, val); | ||
72 | } | ||
73 | |||
74 | static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up, | ||
75 | unsigned int offset, | ||
76 | unsigned int val) | ||
77 | { | ||
78 | ar933x_uart_rmw(up, offset, val, 0); | ||
79 | } | ||
80 | |||
81 | static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up) | ||
82 | { | ||
83 | up->ier |= AR933X_UART_INT_TX_EMPTY; | ||
84 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | ||
85 | } | ||
86 | |||
87 | static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up) | ||
88 | { | ||
89 | up->ier &= ~AR933X_UART_INT_TX_EMPTY; | ||
90 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | ||
91 | } | ||
92 | |||
93 | static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch) | ||
94 | { | ||
95 | unsigned int rdata; | ||
96 | |||
97 | rdata = ch & AR933X_UART_DATA_TX_RX_MASK; | ||
98 | rdata |= AR933X_UART_DATA_TX_CSR; | ||
99 | ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata); | ||
100 | } | ||
101 | |||
102 | static unsigned int ar933x_uart_tx_empty(struct uart_port *port) | ||
103 | { | ||
104 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
105 | unsigned long flags; | ||
106 | unsigned int rdata; | ||
107 | |||
108 | spin_lock_irqsave(&up->port.lock, flags); | ||
109 | rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); | ||
110 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
111 | |||
112 | return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT; | ||
113 | } | ||
114 | |||
115 | static unsigned int ar933x_uart_get_mctrl(struct uart_port *port) | ||
116 | { | ||
117 | return TIOCM_CAR; | ||
118 | } | ||
119 | |||
120 | static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
121 | { | ||
122 | } | ||
123 | |||
124 | static void ar933x_uart_start_tx(struct uart_port *port) | ||
125 | { | ||
126 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
127 | |||
128 | ar933x_uart_start_tx_interrupt(up); | ||
129 | } | ||
130 | |||
131 | static void ar933x_uart_stop_tx(struct uart_port *port) | ||
132 | { | ||
133 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
134 | |||
135 | ar933x_uart_stop_tx_interrupt(up); | ||
136 | } | ||
137 | |||
138 | static void ar933x_uart_stop_rx(struct uart_port *port) | ||
139 | { | ||
140 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
141 | |||
142 | up->ier &= ~AR933X_UART_INT_RX_VALID; | ||
143 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | ||
144 | } | ||
145 | |||
146 | static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) | ||
147 | { | ||
148 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
149 | unsigned long flags; | ||
150 | |||
151 | spin_lock_irqsave(&up->port.lock, flags); | ||
152 | if (break_state == -1) | ||
153 | ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, | ||
154 | AR933X_UART_CS_TX_BREAK); | ||
155 | else | ||
156 | ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, | ||
157 | AR933X_UART_CS_TX_BREAK); | ||
158 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
159 | } | ||
160 | |||
161 | static void ar933x_uart_enable_ms(struct uart_port *port) | ||
162 | { | ||
163 | } | ||
164 | |||
165 | static void ar933x_uart_set_termios(struct uart_port *port, | ||
166 | struct ktermios *new, | ||
167 | struct ktermios *old) | ||
168 | { | ||
169 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
170 | unsigned int cs; | ||
171 | unsigned long flags; | ||
172 | unsigned int baud, scale; | ||
173 | |||
174 | /* Only CS8 is supported */ | ||
175 | new->c_cflag &= ~CSIZE; | ||
176 | new->c_cflag |= CS8; | ||
177 | |||
178 | /* Only one stop bit is supported */ | ||
179 | new->c_cflag &= ~CSTOPB; | ||
180 | |||
181 | cs = 0; | ||
182 | if (new->c_cflag & PARENB) { | ||
183 | if (!(new->c_cflag & PARODD)) | ||
184 | cs |= AR933X_UART_CS_PARITY_EVEN; | ||
185 | else | ||
186 | cs |= AR933X_UART_CS_PARITY_ODD; | ||
187 | } else { | ||
188 | cs |= AR933X_UART_CS_PARITY_NONE; | ||
189 | } | ||
190 | |||
191 | /* Mark/space parity is not supported */ | ||
192 | new->c_cflag &= ~CMSPAR; | ||
193 | |||
194 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16); | ||
195 | scale = (port->uartclk / (16 * baud)) - 1; | ||
196 | |||
197 | /* | ||
198 | * Ok, we're now changing the port state. Do it with | ||
199 | * interrupts disabled. | ||
200 | */ | ||
201 | spin_lock_irqsave(&up->port.lock, flags); | ||
202 | |||
203 | /* Update the per-port timeout. */ | ||
204 | uart_update_timeout(port, new->c_cflag, baud); | ||
205 | |||
206 | up->port.ignore_status_mask = 0; | ||
207 | |||
208 | /* ignore all characters if CREAD is not set */ | ||
209 | if ((new->c_cflag & CREAD) == 0) | ||
210 | up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD; | ||
211 | |||
212 | ar933x_uart_write(up, AR933X_UART_CLOCK_REG, | ||
213 | scale << AR933X_UART_CLOCK_SCALE_S | 8192); | ||
214 | |||
215 | /* setup configuration register */ | ||
216 | ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs); | ||
217 | |||
218 | /* enable host interrupt */ | ||
219 | ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, | ||
220 | AR933X_UART_CS_HOST_INT_EN); | ||
221 | |||
222 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
223 | |||
224 | if (tty_termios_baud_rate(new)) | ||
225 | tty_termios_encode_baud_rate(new, baud, baud); | ||
226 | } | ||
227 | |||
228 | static void ar933x_uart_rx_chars(struct ar933x_uart_port *up) | ||
229 | { | ||
230 | struct tty_struct *tty; | ||
231 | int max_count = 256; | ||
232 | |||
233 | tty = tty_port_tty_get(&up->port.state->port); | ||
234 | do { | ||
235 | unsigned int rdata; | ||
236 | unsigned char ch; | ||
237 | |||
238 | rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); | ||
239 | if ((rdata & AR933X_UART_DATA_RX_CSR) == 0) | ||
240 | break; | ||
241 | |||
242 | /* remove the character from the FIFO */ | ||
243 | ar933x_uart_write(up, AR933X_UART_DATA_REG, | ||
244 | AR933X_UART_DATA_RX_CSR); | ||
245 | |||
246 | if (!tty) { | ||
247 | /* discard the data if no tty available */ | ||
248 | continue; | ||
249 | } | ||
250 | |||
251 | up->port.icount.rx++; | ||
252 | ch = rdata & AR933X_UART_DATA_TX_RX_MASK; | ||
253 | |||
254 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
255 | continue; | ||
256 | |||
257 | if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0) | ||
258 | tty_insert_flip_char(tty, ch, TTY_NORMAL); | ||
259 | } while (max_count-- > 0); | ||
260 | |||
261 | if (tty) { | ||
262 | tty_flip_buffer_push(tty); | ||
263 | tty_kref_put(tty); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) | ||
268 | { | ||
269 | struct circ_buf *xmit = &up->port.state->xmit; | ||
270 | int count; | ||
271 | |||
272 | if (uart_tx_stopped(&up->port)) | ||
273 | return; | ||
274 | |||
275 | count = up->port.fifosize; | ||
276 | do { | ||
277 | unsigned int rdata; | ||
278 | |||
279 | rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG); | ||
280 | if ((rdata & AR933X_UART_DATA_TX_CSR) == 0) | ||
281 | break; | ||
282 | |||
283 | if (up->port.x_char) { | ||
284 | ar933x_uart_putc(up, up->port.x_char); | ||
285 | up->port.icount.tx++; | ||
286 | up->port.x_char = 0; | ||
287 | continue; | ||
288 | } | ||
289 | |||
290 | if (uart_circ_empty(xmit)) | ||
291 | break; | ||
292 | |||
293 | ar933x_uart_putc(up, xmit->buf[xmit->tail]); | ||
294 | |||
295 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
296 | up->port.icount.tx++; | ||
297 | } while (--count > 0); | ||
298 | |||
299 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
300 | uart_write_wakeup(&up->port); | ||
301 | |||
302 | if (!uart_circ_empty(xmit)) | ||
303 | ar933x_uart_start_tx_interrupt(up); | ||
304 | } | ||
305 | |||
306 | static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id) | ||
307 | { | ||
308 | struct ar933x_uart_port *up = dev_id; | ||
309 | unsigned int status; | ||
310 | |||
311 | status = ar933x_uart_read(up, AR933X_UART_CS_REG); | ||
312 | if ((status & AR933X_UART_CS_HOST_INT) == 0) | ||
313 | return IRQ_NONE; | ||
314 | |||
315 | spin_lock(&up->port.lock); | ||
316 | |||
317 | status = ar933x_uart_read(up, AR933X_UART_INT_REG); | ||
318 | status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG); | ||
319 | |||
320 | if (status & AR933X_UART_INT_RX_VALID) { | ||
321 | ar933x_uart_write(up, AR933X_UART_INT_REG, | ||
322 | AR933X_UART_INT_RX_VALID); | ||
323 | ar933x_uart_rx_chars(up); | ||
324 | } | ||
325 | |||
326 | if (status & AR933X_UART_INT_TX_EMPTY) { | ||
327 | ar933x_uart_write(up, AR933X_UART_INT_REG, | ||
328 | AR933X_UART_INT_TX_EMPTY); | ||
329 | ar933x_uart_stop_tx_interrupt(up); | ||
330 | ar933x_uart_tx_chars(up); | ||
331 | } | ||
332 | |||
333 | spin_unlock(&up->port.lock); | ||
334 | |||
335 | return IRQ_HANDLED; | ||
336 | } | ||
337 | |||
338 | static int ar933x_uart_startup(struct uart_port *port) | ||
339 | { | ||
340 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
341 | unsigned long flags; | ||
342 | int ret; | ||
343 | |||
344 | ret = request_irq(up->port.irq, ar933x_uart_interrupt, | ||
345 | up->port.irqflags, dev_name(up->port.dev), up); | ||
346 | if (ret) | ||
347 | return ret; | ||
348 | |||
349 | spin_lock_irqsave(&up->port.lock, flags); | ||
350 | |||
351 | /* Enable HOST interrupts */ | ||
352 | ar933x_uart_rmw_set(up, AR933X_UART_CS_REG, | ||
353 | AR933X_UART_CS_HOST_INT_EN); | ||
354 | |||
355 | /* Enable RX interrupts */ | ||
356 | up->ier = AR933X_UART_INT_RX_VALID; | ||
357 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | ||
358 | |||
359 | spin_unlock_irqrestore(&up->port.lock, flags); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static void ar933x_uart_shutdown(struct uart_port *port) | ||
365 | { | ||
366 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
367 | |||
368 | /* Disable all interrupts */ | ||
369 | up->ier = 0; | ||
370 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); | ||
371 | |||
372 | /* Disable break condition */ | ||
373 | ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG, | ||
374 | AR933X_UART_CS_TX_BREAK); | ||
375 | |||
376 | free_irq(up->port.irq, up); | ||
377 | } | ||
378 | |||
379 | static const char *ar933x_uart_type(struct uart_port *port) | ||
380 | { | ||
381 | return (port->type == PORT_AR933X) ? "AR933X UART" : NULL; | ||
382 | } | ||
383 | |||
384 | static void ar933x_uart_release_port(struct uart_port *port) | ||
385 | { | ||
386 | /* Nothing to release ... */ | ||
387 | } | ||
388 | |||
389 | static int ar933x_uart_request_port(struct uart_port *port) | ||
390 | { | ||
391 | /* UARTs always present */ | ||
392 | return 0; | ||
393 | } | ||
394 | |||
395 | static void ar933x_uart_config_port(struct uart_port *port, int flags) | ||
396 | { | ||
397 | if (flags & UART_CONFIG_TYPE) | ||
398 | port->type = PORT_AR933X; | ||
399 | } | ||
400 | |||
401 | static int ar933x_uart_verify_port(struct uart_port *port, | ||
402 | struct serial_struct *ser) | ||
403 | { | ||
404 | if (ser->type != PORT_UNKNOWN && | ||
405 | ser->type != PORT_AR933X) | ||
406 | return -EINVAL; | ||
407 | |||
408 | if (ser->irq < 0 || ser->irq >= NR_IRQS) | ||
409 | return -EINVAL; | ||
410 | |||
411 | if (ser->baud_base < 28800) | ||
412 | return -EINVAL; | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static struct uart_ops ar933x_uart_ops = { | ||
418 | .tx_empty = ar933x_uart_tx_empty, | ||
419 | .set_mctrl = ar933x_uart_set_mctrl, | ||
420 | .get_mctrl = ar933x_uart_get_mctrl, | ||
421 | .stop_tx = ar933x_uart_stop_tx, | ||
422 | .start_tx = ar933x_uart_start_tx, | ||
423 | .stop_rx = ar933x_uart_stop_rx, | ||
424 | .enable_ms = ar933x_uart_enable_ms, | ||
425 | .break_ctl = ar933x_uart_break_ctl, | ||
426 | .startup = ar933x_uart_startup, | ||
427 | .shutdown = ar933x_uart_shutdown, | ||
428 | .set_termios = ar933x_uart_set_termios, | ||
429 | .type = ar933x_uart_type, | ||
430 | .release_port = ar933x_uart_release_port, | ||
431 | .request_port = ar933x_uart_request_port, | ||
432 | .config_port = ar933x_uart_config_port, | ||
433 | .verify_port = ar933x_uart_verify_port, | ||
434 | }; | ||
435 | |||
436 | #ifdef CONFIG_SERIAL_AR933X_CONSOLE | ||
437 | |||
438 | static struct ar933x_uart_port * | ||
439 | ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; | ||
440 | |||
441 | static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up) | ||
442 | { | ||
443 | unsigned int status; | ||
444 | unsigned int timeout = 60000; | ||
445 | |||
446 | /* Wait up to 60ms for the character(s) to be sent. */ | ||
447 | do { | ||
448 | status = ar933x_uart_read(up, AR933X_UART_DATA_REG); | ||
449 | if (--timeout == 0) | ||
450 | break; | ||
451 | udelay(1); | ||
452 | } while ((status & AR933X_UART_DATA_TX_CSR) == 0); | ||
453 | } | ||
454 | |||
455 | static void ar933x_uart_console_putchar(struct uart_port *port, int ch) | ||
456 | { | ||
457 | struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; | ||
458 | |||
459 | ar933x_uart_wait_xmitr(up); | ||
460 | ar933x_uart_putc(up, ch); | ||
461 | } | ||
462 | |||
463 | static void ar933x_uart_console_write(struct console *co, const char *s, | ||
464 | unsigned int count) | ||
465 | { | ||
466 | struct ar933x_uart_port *up = ar933x_console_ports[co->index]; | ||
467 | unsigned long flags; | ||
468 | unsigned int int_en; | ||
469 | int locked = 1; | ||
470 | |||
471 | local_irq_save(flags); | ||
472 | |||
473 | if (up->port.sysrq) | ||
474 | locked = 0; | ||
475 | else if (oops_in_progress) | ||
476 | locked = spin_trylock(&up->port.lock); | ||
477 | else | ||
478 | spin_lock(&up->port.lock); | ||
479 | |||
480 | /* | ||
481 | * First save the IER then disable the interrupts | ||
482 | */ | ||
483 | int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG); | ||
484 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0); | ||
485 | |||
486 | uart_console_write(&up->port, s, count, ar933x_uart_console_putchar); | ||
487 | |||
488 | /* | ||
489 | * Finally, wait for transmitter to become empty | ||
490 | * and restore the IER | ||
491 | */ | ||
492 | ar933x_uart_wait_xmitr(up); | ||
493 | ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en); | ||
494 | |||
495 | ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS); | ||
496 | |||
497 | if (locked) | ||
498 | spin_unlock(&up->port.lock); | ||
499 | |||
500 | local_irq_restore(flags); | ||
501 | } | ||
502 | |||
503 | static int ar933x_uart_console_setup(struct console *co, char *options) | ||
504 | { | ||
505 | struct ar933x_uart_port *up; | ||
506 | int baud = 115200; | ||
507 | int bits = 8; | ||
508 | int parity = 'n'; | ||
509 | int flow = 'n'; | ||
510 | |||
511 | if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS) | ||
512 | return -EINVAL; | ||
513 | |||
514 | up = ar933x_console_ports[co->index]; | ||
515 | if (!up) | ||
516 | return -ENODEV; | ||
517 | |||
518 | if (options) | ||
519 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
520 | |||
521 | return uart_set_options(&up->port, co, baud, parity, bits, flow); | ||
522 | } | ||
523 | |||
524 | static struct console ar933x_uart_console = { | ||
525 | .name = "ttyATH", | ||
526 | .write = ar933x_uart_console_write, | ||
527 | .device = uart_console_device, | ||
528 | .setup = ar933x_uart_console_setup, | ||
529 | .flags = CON_PRINTBUFFER, | ||
530 | .index = -1, | ||
531 | .data = &ar933x_uart_driver, | ||
532 | }; | ||
533 | |||
534 | static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) | ||
535 | { | ||
536 | ar933x_console_ports[up->port.line] = up; | ||
537 | } | ||
538 | |||
539 | #define AR933X_SERIAL_CONSOLE (&ar933x_uart_console) | ||
540 | |||
541 | #else | ||
542 | |||
543 | static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {} | ||
544 | |||
545 | #define AR933X_SERIAL_CONSOLE NULL | ||
546 | |||
547 | #endif /* CONFIG_SERIAL_AR933X_CONSOLE */ | ||
548 | |||
549 | static struct uart_driver ar933x_uart_driver = { | ||
550 | .owner = THIS_MODULE, | ||
551 | .driver_name = DRIVER_NAME, | ||
552 | .dev_name = "ttyATH", | ||
553 | .nr = CONFIG_SERIAL_AR933X_NR_UARTS, | ||
554 | .cons = AR933X_SERIAL_CONSOLE, | ||
555 | }; | ||
556 | |||
557 | static int __devinit ar933x_uart_probe(struct platform_device *pdev) | ||
558 | { | ||
559 | struct ar933x_uart_platform_data *pdata; | ||
560 | struct ar933x_uart_port *up; | ||
561 | struct uart_port *port; | ||
562 | struct resource *mem_res; | ||
563 | struct resource *irq_res; | ||
564 | int id; | ||
565 | int ret; | ||
566 | |||
567 | pdata = pdev->dev.platform_data; | ||
568 | if (!pdata) | ||
569 | return -EINVAL; | ||
570 | |||
571 | id = pdev->id; | ||
572 | if (id == -1) | ||
573 | id = 0; | ||
574 | |||
575 | if (id > CONFIG_SERIAL_AR933X_NR_UARTS) | ||
576 | return -EINVAL; | ||
577 | |||
578 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
579 | if (!mem_res) { | ||
580 | dev_err(&pdev->dev, "no MEM resource\n"); | ||
581 | return -EINVAL; | ||
582 | } | ||
583 | |||
584 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
585 | if (!irq_res) { | ||
586 | dev_err(&pdev->dev, "no IRQ resource\n"); | ||
587 | return -EINVAL; | ||
588 | } | ||
589 | |||
590 | up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL); | ||
591 | if (!up) | ||
592 | return -ENOMEM; | ||
593 | |||
594 | port = &up->port; | ||
595 | port->mapbase = mem_res->start; | ||
596 | |||
597 | port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE); | ||
598 | if (!port->membase) { | ||
599 | ret = -ENOMEM; | ||
600 | goto err_free_up; | ||
601 | } | ||
602 | |||
603 | port->line = id; | ||
604 | port->irq = irq_res->start; | ||
605 | port->dev = &pdev->dev; | ||
606 | port->type = PORT_AR933X; | ||
607 | port->iotype = UPIO_MEM32; | ||
608 | port->uartclk = pdata->uartclk; | ||
609 | |||
610 | port->regshift = 2; | ||
611 | port->fifosize = AR933X_UART_FIFO_SIZE; | ||
612 | port->ops = &ar933x_uart_ops; | ||
613 | |||
614 | ar933x_uart_add_console_port(up); | ||
615 | |||
616 | ret = uart_add_one_port(&ar933x_uart_driver, &up->port); | ||
617 | if (ret) | ||
618 | goto err_unmap; | ||
619 | |||
620 | platform_set_drvdata(pdev, up); | ||
621 | return 0; | ||
622 | |||
623 | err_unmap: | ||
624 | iounmap(up->port.membase); | ||
625 | err_free_up: | ||
626 | kfree(up); | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | static int __devexit ar933x_uart_remove(struct platform_device *pdev) | ||
631 | { | ||
632 | struct ar933x_uart_port *up; | ||
633 | |||
634 | up = platform_get_drvdata(pdev); | ||
635 | platform_set_drvdata(pdev, NULL); | ||
636 | |||
637 | if (up) { | ||
638 | uart_remove_one_port(&ar933x_uart_driver, &up->port); | ||
639 | iounmap(up->port.membase); | ||
640 | kfree(up); | ||
641 | } | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static struct platform_driver ar933x_uart_platform_driver = { | ||
647 | .probe = ar933x_uart_probe, | ||
648 | .remove = __devexit_p(ar933x_uart_remove), | ||
649 | .driver = { | ||
650 | .name = DRIVER_NAME, | ||
651 | .owner = THIS_MODULE, | ||
652 | }, | ||
653 | }; | ||
654 | |||
655 | static int __init ar933x_uart_init(void) | ||
656 | { | ||
657 | int ret; | ||
658 | |||
659 | ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS; | ||
660 | ret = uart_register_driver(&ar933x_uart_driver); | ||
661 | if (ret) | ||
662 | goto err_out; | ||
663 | |||
664 | ret = platform_driver_register(&ar933x_uart_platform_driver); | ||
665 | if (ret) | ||
666 | goto err_unregister_uart_driver; | ||
667 | |||
668 | return 0; | ||
669 | |||
670 | err_unregister_uart_driver: | ||
671 | uart_unregister_driver(&ar933x_uart_driver); | ||
672 | err_out: | ||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | static void __exit ar933x_uart_exit(void) | ||
677 | { | ||
678 | platform_driver_unregister(&ar933x_uart_platform_driver); | ||
679 | uart_unregister_driver(&ar933x_uart_driver); | ||
680 | } | ||
681 | |||
682 | module_init(ar933x_uart_init); | ||
683 | module_exit(ar933x_uart_exit); | ||
684 | |||
685 | MODULE_DESCRIPTION("Atheros AR933X UART driver"); | ||
686 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||
687 | MODULE_LICENSE("GPL v2"); | ||
688 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 060e0e2b1ae6..8b094b4f6531 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -210,7 +210,7 @@ config USB_CNS3XXX_EHCI | |||
210 | 210 | ||
211 | config USB_EHCI_ATH79 | 211 | config USB_EHCI_ATH79 |
212 | bool "EHCI support for AR7XXX/AR9XXX SoCs" | 212 | bool "EHCI support for AR7XXX/AR9XXX SoCs" |
213 | depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X) | 213 | depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X || SOC_AR933X) |
214 | select USB_EHCI_ROOT_HUB_TT | 214 | select USB_EHCI_ROOT_HUB_TT |
215 | default y | 215 | default y |
216 | ---help--- | 216 | ---help--- |
diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c index b4192c964d0d..936af8359fb2 100644 --- a/drivers/usb/host/alchemy-common.c +++ b/drivers/usb/host/alchemy-common.c | |||
@@ -52,9 +52,263 @@ | |||
52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ | 52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ |
53 | USBCFG_OME) | 53 | USBCFG_OME) |
54 | 54 | ||
55 | /* Au1300 USB config registers */ | ||
56 | #define USB_DWC_CTRL1 0x00 | ||
57 | #define USB_DWC_CTRL2 0x04 | ||
58 | #define USB_VBUS_TIMER 0x10 | ||
59 | #define USB_SBUS_CTRL 0x14 | ||
60 | #define USB_MSR_ERR 0x18 | ||
61 | #define USB_DWC_CTRL3 0x1C | ||
62 | #define USB_DWC_CTRL4 0x20 | ||
63 | #define USB_OTG_STATUS 0x28 | ||
64 | #define USB_DWC_CTRL5 0x2C | ||
65 | #define USB_DWC_CTRL6 0x30 | ||
66 | #define USB_DWC_CTRL7 0x34 | ||
67 | #define USB_PHY_STATUS 0xC0 | ||
68 | #define USB_INT_STATUS 0xC4 | ||
69 | #define USB_INT_ENABLE 0xC8 | ||
70 | |||
71 | #define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ | ||
72 | #define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ | ||
73 | #define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ | ||
74 | |||
75 | #define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ | ||
76 | #define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ | ||
77 | #define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ | ||
78 | |||
79 | #define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) | ||
80 | #define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) | ||
81 | #define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) | ||
82 | #define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) | ||
83 | |||
84 | #define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ | ||
85 | |||
86 | #define USB_INTEN_FORCE 0x20 | ||
87 | #define USB_INTEN_PHY 0x10 | ||
88 | #define USB_INTEN_UDC 0x08 | ||
89 | #define USB_INTEN_EHCI 0x04 | ||
90 | #define USB_INTEN_OHCI1 0x02 | ||
91 | #define USB_INTEN_OHCI0 0x01 | ||
55 | 92 | ||
56 | static DEFINE_SPINLOCK(alchemy_usb_lock); | 93 | static DEFINE_SPINLOCK(alchemy_usb_lock); |
57 | 94 | ||
95 | static inline void __au1300_usb_phyctl(void __iomem *base, int enable) | ||
96 | { | ||
97 | unsigned long r, s; | ||
98 | |||
99 | r = __raw_readl(base + USB_DWC_CTRL2); | ||
100 | s = __raw_readl(base + USB_DWC_CTRL3); | ||
101 | |||
102 | s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | | ||
103 | USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; | ||
104 | |||
105 | if (enable) { | ||
106 | /* simply enable all PHYs */ | ||
107 | r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
108 | USB_DWC_CTRL2_PHYRS; | ||
109 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
110 | wmb(); | ||
111 | } else if (!s) { | ||
112 | /* no USB block active, do disable all PHYs */ | ||
113 | r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
114 | USB_DWC_CTRL2_PHYRS); | ||
115 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
116 | wmb(); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) | ||
121 | { | ||
122 | unsigned long r; | ||
123 | |||
124 | if (enable) { | ||
125 | __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ | ||
126 | wmb(); | ||
127 | |||
128 | r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ | ||
129 | r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
130 | : USB_DWC_CTRL3_OHCI1_CKEN; | ||
131 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
132 | wmb(); | ||
133 | |||
134 | __au1300_usb_phyctl(base, enable); /* power up the PHYs */ | ||
135 | |||
136 | r = __raw_readl(base + USB_INT_ENABLE); | ||
137 | r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; | ||
138 | __raw_writel(r, base + USB_INT_ENABLE); | ||
139 | wmb(); | ||
140 | |||
141 | /* reset the OHCI start clock bit */ | ||
142 | __raw_writel(0, base + USB_DWC_CTRL7); | ||
143 | wmb(); | ||
144 | } else { | ||
145 | r = __raw_readl(base + USB_INT_ENABLE); | ||
146 | r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); | ||
147 | __raw_writel(r, base + USB_INT_ENABLE); | ||
148 | wmb(); | ||
149 | |||
150 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
151 | r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
152 | : USB_DWC_CTRL3_OHCI1_CKEN); | ||
153 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
154 | wmb(); | ||
155 | |||
156 | __au1300_usb_phyctl(base, enable); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static inline void __au1300_ehci_control(void __iomem *base, int enable) | ||
161 | { | ||
162 | unsigned long r; | ||
163 | |||
164 | if (enable) { | ||
165 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
166 | r |= USB_DWC_CTRL3_EHCI0_CKEN; | ||
167 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
168 | wmb(); | ||
169 | |||
170 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
171 | r |= USB_DWC_CTRL1_HSTRS; | ||
172 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
173 | wmb(); | ||
174 | |||
175 | __au1300_usb_phyctl(base, enable); | ||
176 | |||
177 | r = __raw_readl(base + USB_INT_ENABLE); | ||
178 | r |= USB_INTEN_EHCI; | ||
179 | __raw_writel(r, base + USB_INT_ENABLE); | ||
180 | wmb(); | ||
181 | } else { | ||
182 | r = __raw_readl(base + USB_INT_ENABLE); | ||
183 | r &= ~USB_INTEN_EHCI; | ||
184 | __raw_writel(r, base + USB_INT_ENABLE); | ||
185 | wmb(); | ||
186 | |||
187 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
188 | r &= ~USB_DWC_CTRL1_HSTRS; | ||
189 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
190 | wmb(); | ||
191 | |||
192 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
193 | r &= ~USB_DWC_CTRL3_EHCI0_CKEN; | ||
194 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
195 | wmb(); | ||
196 | |||
197 | __au1300_usb_phyctl(base, enable); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static inline void __au1300_udc_control(void __iomem *base, int enable) | ||
202 | { | ||
203 | unsigned long r; | ||
204 | |||
205 | if (enable) { | ||
206 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
207 | r |= USB_DWC_CTRL1_DCRS; | ||
208 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
209 | wmb(); | ||
210 | |||
211 | __au1300_usb_phyctl(base, enable); | ||
212 | |||
213 | r = __raw_readl(base + USB_INT_ENABLE); | ||
214 | r |= USB_INTEN_UDC; | ||
215 | __raw_writel(r, base + USB_INT_ENABLE); | ||
216 | wmb(); | ||
217 | } else { | ||
218 | r = __raw_readl(base + USB_INT_ENABLE); | ||
219 | r &= ~USB_INTEN_UDC; | ||
220 | __raw_writel(r, base + USB_INT_ENABLE); | ||
221 | wmb(); | ||
222 | |||
223 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
224 | r &= ~USB_DWC_CTRL1_DCRS; | ||
225 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
226 | wmb(); | ||
227 | |||
228 | __au1300_usb_phyctl(base, enable); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static inline void __au1300_otg_control(void __iomem *base, int enable) | ||
233 | { | ||
234 | unsigned long r; | ||
235 | if (enable) { | ||
236 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
237 | r |= USB_DWC_CTRL3_OTG0_CKEN; | ||
238 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
239 | wmb(); | ||
240 | |||
241 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
242 | r &= ~USB_DWC_CTRL1_OTGD; | ||
243 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
244 | wmb(); | ||
245 | |||
246 | __au1300_usb_phyctl(base, enable); | ||
247 | } else { | ||
248 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
249 | r |= USB_DWC_CTRL1_OTGD; | ||
250 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
251 | wmb(); | ||
252 | |||
253 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
254 | r &= ~USB_DWC_CTRL3_OTG0_CKEN; | ||
255 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
256 | wmb(); | ||
257 | |||
258 | __au1300_usb_phyctl(base, enable); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static inline int au1300_usb_control(int block, int enable) | ||
263 | { | ||
264 | void __iomem *base = | ||
265 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
266 | int ret = 0; | ||
267 | |||
268 | switch (block) { | ||
269 | case ALCHEMY_USB_OHCI0: | ||
270 | __au1300_ohci_control(base, enable, 0); | ||
271 | break; | ||
272 | case ALCHEMY_USB_OHCI1: | ||
273 | __au1300_ohci_control(base, enable, 1); | ||
274 | break; | ||
275 | case ALCHEMY_USB_EHCI0: | ||
276 | __au1300_ehci_control(base, enable); | ||
277 | break; | ||
278 | case ALCHEMY_USB_UDC0: | ||
279 | __au1300_udc_control(base, enable); | ||
280 | break; | ||
281 | case ALCHEMY_USB_OTG0: | ||
282 | __au1300_otg_control(base, enable); | ||
283 | break; | ||
284 | default: | ||
285 | ret = -ENODEV; | ||
286 | } | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static inline void au1300_usb_init(void) | ||
291 | { | ||
292 | void __iomem *base = | ||
293 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
294 | |||
295 | /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 | ||
296 | * here at all: Port 2 routing (EHCI or UDC) must be set either | ||
297 | * by boot firmware or platform init code; I can't autodetect | ||
298 | * a sane setting. | ||
299 | */ | ||
300 | __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ | ||
301 | wmb(); | ||
302 | __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ | ||
303 | wmb(); | ||
304 | __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ | ||
305 | wmb(); | ||
306 | __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ | ||
307 | wmb(); | ||
308 | /* set coherent access bit */ | ||
309 | __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); | ||
310 | wmb(); | ||
311 | } | ||
58 | 312 | ||
59 | static inline void __au1200_ohci_control(void __iomem *base, int enable) | 313 | static inline void __au1200_ohci_control(void __iomem *base, int enable) |
60 | { | 314 | { |
@@ -233,6 +487,9 @@ int alchemy_usb_control(int block, int enable) | |||
233 | case ALCHEMY_CPU_AU1200: | 487 | case ALCHEMY_CPU_AU1200: |
234 | ret = au1200_usb_control(block, enable); | 488 | ret = au1200_usb_control(block, enable); |
235 | break; | 489 | break; |
490 | case ALCHEMY_CPU_AU1300: | ||
491 | ret = au1300_usb_control(block, enable); | ||
492 | break; | ||
236 | default: | 493 | default: |
237 | ret = -ENODEV; | 494 | ret = -ENODEV; |
238 | } | 495 | } |
@@ -281,6 +538,20 @@ static void au1200_usb_pm(int susp) | |||
281 | } | 538 | } |
282 | } | 539 | } |
283 | 540 | ||
541 | static void au1300_usb_pm(int susp) | ||
542 | { | ||
543 | void __iomem *base = | ||
544 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
545 | /* remember Port2 routing */ | ||
546 | if (susp) { | ||
547 | alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); | ||
548 | } else { | ||
549 | au1300_usb_init(); | ||
550 | __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); | ||
551 | wmb(); | ||
552 | } | ||
553 | } | ||
554 | |||
284 | static void alchemy_usb_pm(int susp) | 555 | static void alchemy_usb_pm(int susp) |
285 | { | 556 | { |
286 | switch (alchemy_get_cputype()) { | 557 | switch (alchemy_get_cputype()) { |
@@ -295,6 +566,9 @@ static void alchemy_usb_pm(int susp) | |||
295 | case ALCHEMY_CPU_AU1200: | 566 | case ALCHEMY_CPU_AU1200: |
296 | au1200_usb_pm(susp); | 567 | au1200_usb_pm(susp); |
297 | break; | 568 | break; |
569 | case ALCHEMY_CPU_AU1300: | ||
570 | au1300_usb_pm(susp); | ||
571 | break; | ||
298 | } | 572 | } |
299 | } | 573 | } |
300 | 574 | ||
@@ -328,6 +602,9 @@ static int __init alchemy_usb_init(void) | |||
328 | case ALCHEMY_CPU_AU1200: | 602 | case ALCHEMY_CPU_AU1200: |
329 | au1200_usb_init(); | 603 | au1200_usb_init(); |
330 | break; | 604 | break; |
605 | case ALCHEMY_CPU_AU1300: | ||
606 | au1300_usb_init(); | ||
607 | break; | ||
331 | } | 608 | } |
332 | 609 | ||
333 | register_syscore_ops(&alchemy_usb_pm_ops); | 610 | register_syscore_ops(&alchemy_usb_pm_ops); |
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c index afb6743cf094..f1424f9bc363 100644 --- a/drivers/usb/host/ehci-ath79.c +++ b/drivers/usb/host/ehci-ath79.c | |||
@@ -33,6 +33,10 @@ static const struct platform_device_id ehci_ath79_id_table[] = { | |||
33 | .driver_data = EHCI_ATH79_IP_V2, | 33 | .driver_data = EHCI_ATH79_IP_V2, |
34 | }, | 34 | }, |
35 | { | 35 | { |
36 | .name = "ar933x-ehci", | ||
37 | .driver_data = EHCI_ATH79_IP_V2, | ||
38 | }, | ||
39 | { | ||
36 | /* terminating entry */ | 40 | /* terminating entry */ |
37 | }, | 41 | }, |
38 | }; | 42 | }; |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 9b66df8278f3..95d1a71dccad 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -89,7 +89,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
89 | 89 | ||
90 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | 90 | static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) |
91 | { | 91 | { |
92 | int ret; | 92 | int ret, unit; |
93 | struct usb_hcd *hcd; | 93 | struct usb_hcd *hcd; |
94 | 94 | ||
95 | if (usb_disabled()) | 95 | if (usb_disabled()) |
@@ -120,7 +120,9 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
120 | goto err2; | 120 | goto err2; |
121 | } | 121 | } |
122 | 122 | ||
123 | if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) { | 123 | unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? |
124 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
125 | if (alchemy_usb_control(unit, 1)) { | ||
124 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); | 126 | printk(KERN_INFO "%s: controller init failed!\n", pdev->name); |
125 | ret = -ENODEV; | 127 | ret = -ENODEV; |
126 | goto err3; | 128 | goto err3; |
@@ -135,7 +137,7 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev) | |||
135 | return ret; | 137 | return ret; |
136 | } | 138 | } |
137 | 139 | ||
138 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); | 140 | alchemy_usb_control(unit, 0); |
139 | err3: | 141 | err3: |
140 | iounmap(hcd->regs); | 142 | iounmap(hcd->regs); |
141 | err2: | 143 | err2: |
@@ -148,9 +150,12 @@ err1: | |||
148 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) | 150 | static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev) |
149 | { | 151 | { |
150 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 152 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
153 | int unit; | ||
151 | 154 | ||
155 | unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ? | ||
156 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | ||
152 | usb_remove_hcd(hcd); | 157 | usb_remove_hcd(hcd); |
153 | alchemy_usb_control(ALCHEMY_USB_OHCI0, 0); | 158 | alchemy_usb_control(unit, 0); |
154 | iounmap(hcd->regs); | 159 | iounmap(hcd->regs); |
155 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 160 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
156 | usb_put_hcd(hcd); | 161 | usb_put_hcd(hcd); |
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d83e967e4e15..acd4ba555e3a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -1763,16 +1763,16 @@ config FB_AU1100 | |||
1763 | au1100fb:panel=<name>. | 1763 | au1100fb:panel=<name>. |
1764 | 1764 | ||
1765 | config FB_AU1200 | 1765 | config FB_AU1200 |
1766 | bool "Au1200 LCD Driver" | 1766 | bool "Au1200/Au1300 LCD Driver" |
1767 | depends on (FB = y) && MIPS_ALCHEMY | 1767 | depends on (FB = y) && MIPS_ALCHEMY |
1768 | select FB_SYS_FILLRECT | 1768 | select FB_SYS_FILLRECT |
1769 | select FB_SYS_COPYAREA | 1769 | select FB_SYS_COPYAREA |
1770 | select FB_SYS_IMAGEBLIT | 1770 | select FB_SYS_IMAGEBLIT |
1771 | select FB_SYS_FOPS | 1771 | select FB_SYS_FOPS |
1772 | help | 1772 | help |
1773 | This is the framebuffer driver for the AMD Au1200 SOC. It can drive | 1773 | This is the framebuffer driver for the Au1200/Au1300 SOCs. |
1774 | various panels and CRTs by passing in kernel cmd line option | 1774 | It can drive various panels and CRTs by passing in kernel cmd line |
1775 | au1200fb:panel=<name>. | 1775 | option au1200fb:panel=<name>. |
1776 | 1776 | ||
1777 | config FB_VT8500 | 1777 | config FB_VT8500 |
1778 | bool "VT8500 LCD Driver" | 1778 | bool "VT8500 LCD Driver" |
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 649cb35de4ed..de9da6774fd9 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c | |||
@@ -60,18 +60,6 @@ | |||
60 | 60 | ||
61 | #include "au1100fb.h" | 61 | #include "au1100fb.h" |
62 | 62 | ||
63 | /* | ||
64 | * Sanity check. If this is a new Au1100 based board, search for | ||
65 | * the PB1100 ifdefs to make sure you modify the code accordingly. | ||
66 | */ | ||
67 | #if defined(CONFIG_MIPS_PB1100) | ||
68 | #include <asm/mach-pb1x00/pb1100.h> | ||
69 | #elif defined(CONFIG_MIPS_DB1100) | ||
70 | #include <asm/mach-db1x00/db1x00.h> | ||
71 | #else | ||
72 | #error "Unknown Au1100 board, Au1100 FB driver not supported" | ||
73 | #endif | ||
74 | |||
75 | #define DRIVER_NAME "au1100fb" | 63 | #define DRIVER_NAME "au1100fb" |
76 | #define DRIVER_DESC "LCD controller driver for AU1100 processors" | 64 | #define DRIVER_DESC "LCD controller driver for AU1100 processors" |
77 | 65 | ||
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 72005598040f..04e4479d5afd 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | 45 | ||
46 | #include <asm/mach-au1x00/au1000.h> | 46 | #include <asm/mach-au1x00/au1000.h> |
47 | #include <asm/mach-au1x00/au1200fb.h> /* platform_data */ | ||
47 | #include "au1200fb.h" | 48 | #include "au1200fb.h" |
48 | 49 | ||
49 | #define DRIVER_NAME "au1200fb" | 50 | #define DRIVER_NAME "au1200fb" |
@@ -143,6 +144,7 @@ struct au1200_lcd_iodata_t { | |||
143 | /* Private, per-framebuffer management information (independent of the panel itself) */ | 144 | /* Private, per-framebuffer management information (independent of the panel itself) */ |
144 | struct au1200fb_device { | 145 | struct au1200fb_device { |
145 | struct fb_info *fb_info; /* FB driver info record */ | 146 | struct fb_info *fb_info; /* FB driver info record */ |
147 | struct au1200fb_platdata *pd; | ||
146 | 148 | ||
147 | int plane; | 149 | int plane; |
148 | unsigned char* fb_mem; /* FrameBuffer memory map */ | 150 | unsigned char* fb_mem; /* FrameBuffer memory map */ |
@@ -201,9 +203,6 @@ struct window_settings { | |||
201 | #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01 | 203 | #define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01 |
202 | #endif | 204 | #endif |
203 | 205 | ||
204 | extern int board_au1200fb_panel_init (void); | ||
205 | extern int board_au1200fb_panel_shutdown (void); | ||
206 | |||
207 | /* | 206 | /* |
208 | * Default window configurations | 207 | * Default window configurations |
209 | */ | 208 | */ |
@@ -334,8 +333,6 @@ struct panel_settings | |||
334 | uint32 mode_toyclksrc; | 333 | uint32 mode_toyclksrc; |
335 | uint32 mode_backlight; | 334 | uint32 mode_backlight; |
336 | uint32 mode_auxpll; | 335 | uint32 mode_auxpll; |
337 | int (*device_init)(void); | ||
338 | int (*device_shutdown)(void); | ||
339 | #define Xres min_xres | 336 | #define Xres min_xres |
340 | #define Yres min_yres | 337 | #define Yres min_yres |
341 | u32 min_xres; /* Minimum horizontal resolution */ | 338 | u32 min_xres; /* Minimum horizontal resolution */ |
@@ -385,8 +382,6 @@ static struct panel_settings known_lcd_panels[] = | |||
385 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 382 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
386 | .mode_backlight = 0x00000000, | 383 | .mode_backlight = 0x00000000, |
387 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 384 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
388 | .device_init = NULL, | ||
389 | .device_shutdown = NULL, | ||
390 | 320, 320, | 385 | 320, 320, |
391 | 240, 240, | 386 | 240, 240, |
392 | }, | 387 | }, |
@@ -415,8 +410,6 @@ static struct panel_settings known_lcd_panels[] = | |||
415 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 410 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
416 | .mode_backlight = 0x00000000, | 411 | .mode_backlight = 0x00000000, |
417 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 412 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
418 | .device_init = NULL, | ||
419 | .device_shutdown = NULL, | ||
420 | 640, 480, | 413 | 640, 480, |
421 | 640, 480, | 414 | 640, 480, |
422 | }, | 415 | }, |
@@ -445,8 +438,6 @@ static struct panel_settings known_lcd_panels[] = | |||
445 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 438 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
446 | .mode_backlight = 0x00000000, | 439 | .mode_backlight = 0x00000000, |
447 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 440 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
448 | .device_init = NULL, | ||
449 | .device_shutdown = NULL, | ||
450 | 800, 800, | 441 | 800, 800, |
451 | 600, 600, | 442 | 600, 600, |
452 | }, | 443 | }, |
@@ -475,8 +466,6 @@ static struct panel_settings known_lcd_panels[] = | |||
475 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 466 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
476 | .mode_backlight = 0x00000000, | 467 | .mode_backlight = 0x00000000, |
477 | .mode_auxpll = 6, /* 72MHz AUXPLL */ | 468 | .mode_auxpll = 6, /* 72MHz AUXPLL */ |
478 | .device_init = NULL, | ||
479 | .device_shutdown = NULL, | ||
480 | 1024, 1024, | 469 | 1024, 1024, |
481 | 768, 768, | 470 | 768, 768, |
482 | }, | 471 | }, |
@@ -505,8 +494,6 @@ static struct panel_settings known_lcd_panels[] = | |||
505 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 494 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
506 | .mode_backlight = 0x00000000, | 495 | .mode_backlight = 0x00000000, |
507 | .mode_auxpll = 10, /* 120MHz AUXPLL */ | 496 | .mode_auxpll = 10, /* 120MHz AUXPLL */ |
508 | .device_init = NULL, | ||
509 | .device_shutdown = NULL, | ||
510 | 1280, 1280, | 497 | 1280, 1280, |
511 | 1024, 1024, | 498 | 1024, 1024, |
512 | }, | 499 | }, |
@@ -535,8 +522,6 @@ static struct panel_settings known_lcd_panels[] = | |||
535 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 522 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
536 | .mode_backlight = 0x00000000, | 523 | .mode_backlight = 0x00000000, |
537 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 524 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
538 | .device_init = board_au1200fb_panel_init, | ||
539 | .device_shutdown = board_au1200fb_panel_shutdown, | ||
540 | 1024, 1024, | 525 | 1024, 1024, |
541 | 768, 768, | 526 | 768, 768, |
542 | }, | 527 | }, |
@@ -568,8 +553,6 @@ static struct panel_settings known_lcd_panels[] = | |||
568 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 553 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
569 | .mode_backlight = 0x00000000, | 554 | .mode_backlight = 0x00000000, |
570 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 555 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
571 | .device_init = board_au1200fb_panel_init, | ||
572 | .device_shutdown = board_au1200fb_panel_shutdown, | ||
573 | 640, 480, | 556 | 640, 480, |
574 | 640, 480, | 557 | 640, 480, |
575 | }, | 558 | }, |
@@ -601,8 +584,6 @@ static struct panel_settings known_lcd_panels[] = | |||
601 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 584 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
602 | .mode_backlight = 0x00000000, | 585 | .mode_backlight = 0x00000000, |
603 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 586 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
604 | .device_init = board_au1200fb_panel_init, | ||
605 | .device_shutdown = board_au1200fb_panel_shutdown, | ||
606 | 320, 320, | 587 | 320, 320, |
607 | 240, 240, | 588 | 240, 240, |
608 | }, | 589 | }, |
@@ -634,11 +615,43 @@ static struct panel_settings known_lcd_panels[] = | |||
634 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | 615 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ |
635 | .mode_backlight = 0x00000000, | 616 | .mode_backlight = 0x00000000, |
636 | .mode_auxpll = 8, /* 96MHz AUXPLL */ | 617 | .mode_auxpll = 8, /* 96MHz AUXPLL */ |
637 | .device_init = board_au1200fb_panel_init, | ||
638 | .device_shutdown = board_au1200fb_panel_shutdown, | ||
639 | 856, 856, | 618 | 856, 856, |
640 | 480, 480, | 619 | 480, 480, |
641 | }, | 620 | }, |
621 | [9] = { | ||
622 | .name = "DB1300_800x480", | ||
623 | .monspecs = { | ||
624 | .modedb = NULL, | ||
625 | .modedb_len = 0, | ||
626 | .hfmin = 30000, | ||
627 | .hfmax = 70000, | ||
628 | .vfmin = 60, | ||
629 | .vfmax = 60, | ||
630 | .dclkmin = 6000000, | ||
631 | .dclkmax = 28000000, | ||
632 | .input = FB_DISP_RGB, | ||
633 | }, | ||
634 | .mode_screen = LCD_SCREEN_SX_N(800) | | ||
635 | LCD_SCREEN_SY_N(480), | ||
636 | .mode_horztiming = LCD_HORZTIMING_HPW_N(5) | | ||
637 | LCD_HORZTIMING_HND1_N(16) | | ||
638 | LCD_HORZTIMING_HND2_N(8), | ||
639 | .mode_verttiming = LCD_VERTTIMING_VPW_N(4) | | ||
640 | LCD_VERTTIMING_VND1_N(8) | | ||
641 | LCD_VERTTIMING_VND2_N(5), | ||
642 | .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1) | | ||
643 | LCD_CLKCONTROL_IV | | ||
644 | LCD_CLKCONTROL_IH, | ||
645 | .mode_pwmdiv = 0x00000000, | ||
646 | .mode_pwmhi = 0x00000000, | ||
647 | .mode_outmask = 0x00FFFFFF, | ||
648 | .mode_fifoctrl = 0x2f2f2f2f, | ||
649 | .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ | ||
650 | .mode_backlight = 0x00000000, | ||
651 | .mode_auxpll = (48/12) * 2, | ||
652 | 800, 800, | ||
653 | 480, 480, | ||
654 | }, | ||
642 | }; | 655 | }; |
643 | 656 | ||
644 | #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels)) | 657 | #define NUM_PANELS (ARRAY_SIZE(known_lcd_panels)) |
@@ -764,7 +777,8 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, | |||
764 | return 0; | 777 | return 0; |
765 | } | 778 | } |
766 | 779 | ||
767 | static void au1200_setpanel (struct panel_settings *newpanel) | 780 | static void au1200_setpanel(struct panel_settings *newpanel, |
781 | struct au1200fb_platdata *pd) | ||
768 | { | 782 | { |
769 | /* | 783 | /* |
770 | * Perform global setup/init of LCD controller | 784 | * Perform global setup/init of LCD controller |
@@ -798,8 +812,8 @@ static void au1200_setpanel (struct panel_settings *newpanel) | |||
798 | the controller, the clock cannot be turned off before first | 812 | the controller, the clock cannot be turned off before first |
799 | shutting down the controller. | 813 | shutting down the controller. |
800 | */ | 814 | */ |
801 | if (panel->device_shutdown != NULL) | 815 | if (pd->panel_shutdown) |
802 | panel->device_shutdown(); | 816 | pd->panel_shutdown(); |
803 | } | 817 | } |
804 | 818 | ||
805 | /* Newpanel == NULL indicates a shutdown operation only */ | 819 | /* Newpanel == NULL indicates a shutdown operation only */ |
@@ -852,7 +866,8 @@ static void au1200_setpanel (struct panel_settings *newpanel) | |||
852 | au_sync(); | 866 | au_sync(); |
853 | 867 | ||
854 | /* Call init of panel */ | 868 | /* Call init of panel */ |
855 | if (panel->device_init != NULL) panel->device_init(); | 869 | if (pd->panel_init) |
870 | pd->panel_init(); | ||
856 | 871 | ||
857 | /* FIX!!!! not appropriate on panel change!!! Global setup/init */ | 872 | /* FIX!!!! not appropriate on panel change!!! Global setup/init */ |
858 | lcd->intenable = 0; | 873 | lcd->intenable = 0; |
@@ -1185,6 +1200,8 @@ static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
1185 | */ | 1200 | */ |
1186 | static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) | 1201 | static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) |
1187 | { | 1202 | { |
1203 | struct au1200fb_device *fbdev = fbi->par; | ||
1204 | |||
1188 | /* Short-circuit screen blanking */ | 1205 | /* Short-circuit screen blanking */ |
1189 | if (noblanking) | 1206 | if (noblanking) |
1190 | return 0; | 1207 | return 0; |
@@ -1194,13 +1211,13 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi) | |||
1194 | case FB_BLANK_UNBLANK: | 1211 | case FB_BLANK_UNBLANK: |
1195 | case FB_BLANK_NORMAL: | 1212 | case FB_BLANK_NORMAL: |
1196 | /* printk("turn on panel\n"); */ | 1213 | /* printk("turn on panel\n"); */ |
1197 | au1200_setpanel(panel); | 1214 | au1200_setpanel(panel, fbdev->pd); |
1198 | break; | 1215 | break; |
1199 | case FB_BLANK_VSYNC_SUSPEND: | 1216 | case FB_BLANK_VSYNC_SUSPEND: |
1200 | case FB_BLANK_HSYNC_SUSPEND: | 1217 | case FB_BLANK_HSYNC_SUSPEND: |
1201 | case FB_BLANK_POWERDOWN: | 1218 | case FB_BLANK_POWERDOWN: |
1202 | /* printk("turn off panel\n"); */ | 1219 | /* printk("turn off panel\n"); */ |
1203 | au1200_setpanel(NULL); | 1220 | au1200_setpanel(NULL, fbdev->pd); |
1204 | break; | 1221 | break; |
1205 | default: | 1222 | default: |
1206 | break; | 1223 | break; |
@@ -1428,6 +1445,7 @@ static void get_window(unsigned int plane, | |||
1428 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, | 1445 | static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, |
1429 | unsigned long arg) | 1446 | unsigned long arg) |
1430 | { | 1447 | { |
1448 | struct au1200fb_device *fbdev = info->par; | ||
1431 | int plane; | 1449 | int plane; |
1432 | int val; | 1450 | int val; |
1433 | 1451 | ||
@@ -1472,7 +1490,7 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
1472 | struct panel_settings *newpanel; | 1490 | struct panel_settings *newpanel; |
1473 | panel_index = iodata.global.panel_choice; | 1491 | panel_index = iodata.global.panel_choice; |
1474 | newpanel = &known_lcd_panels[panel_index]; | 1492 | newpanel = &known_lcd_panels[panel_index]; |
1475 | au1200_setpanel(newpanel); | 1493 | au1200_setpanel(newpanel, fbdev->pd); |
1476 | } | 1494 | } |
1477 | break; | 1495 | break; |
1478 | 1496 | ||
@@ -1588,22 +1606,102 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev) | |||
1588 | 1606 | ||
1589 | /*-------------------------------------------------------------------------*/ | 1607 | /*-------------------------------------------------------------------------*/ |
1590 | 1608 | ||
1591 | /* AU1200 LCD controller device driver */ | ||
1592 | 1609 | ||
1610 | static int au1200fb_setup(struct au1200fb_platdata *pd) | ||
1611 | { | ||
1612 | char *options = NULL; | ||
1613 | char *this_opt, *endptr; | ||
1614 | int num_panels = ARRAY_SIZE(known_lcd_panels); | ||
1615 | int panel_idx = -1; | ||
1616 | |||
1617 | fb_get_options(DRIVER_NAME, &options); | ||
1618 | |||
1619 | if (!options) | ||
1620 | goto out; | ||
1621 | |||
1622 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
1623 | /* Panel option - can be panel name, | ||
1624 | * "bs" for board-switch, or number/index */ | ||
1625 | if (!strncmp(this_opt, "panel:", 6)) { | ||
1626 | int i; | ||
1627 | long int li; | ||
1628 | char *endptr; | ||
1629 | this_opt += 6; | ||
1630 | /* First check for index, which allows | ||
1631 | * to short circuit this mess */ | ||
1632 | li = simple_strtol(this_opt, &endptr, 0); | ||
1633 | if (*endptr == '\0') | ||
1634 | panel_idx = (int)li; | ||
1635 | else if (strcmp(this_opt, "bs") == 0) | ||
1636 | panel_idx = pd->panel_index(); | ||
1637 | else { | ||
1638 | for (i = 0; i < num_panels; i++) { | ||
1639 | if (!strcmp(this_opt, | ||
1640 | known_lcd_panels[i].name)) { | ||
1641 | panel_idx = i; | ||
1642 | break; | ||
1643 | } | ||
1644 | } | ||
1645 | } | ||
1646 | if ((panel_idx < 0) || (panel_idx >= num_panels)) | ||
1647 | print_warn("Panel %s not supported!", this_opt); | ||
1648 | else | ||
1649 | panel_index = panel_idx; | ||
1650 | |||
1651 | } else if (strncmp(this_opt, "nohwcursor", 10) == 0) | ||
1652 | nohwcursor = 1; | ||
1653 | else if (strncmp(this_opt, "devices:", 8) == 0) { | ||
1654 | this_opt += 8; | ||
1655 | device_count = simple_strtol(this_opt, &endptr, 0); | ||
1656 | if ((device_count < 0) || | ||
1657 | (device_count > MAX_DEVICE_COUNT)) | ||
1658 | device_count = MAX_DEVICE_COUNT; | ||
1659 | } else if (strncmp(this_opt, "wincfg:", 7) == 0) { | ||
1660 | this_opt += 7; | ||
1661 | window_index = simple_strtol(this_opt, &endptr, 0); | ||
1662 | if ((window_index < 0) || | ||
1663 | (window_index >= ARRAY_SIZE(windows))) | ||
1664 | window_index = DEFAULT_WINDOW_INDEX; | ||
1665 | } else if (strncmp(this_opt, "off", 3) == 0) | ||
1666 | return 1; | ||
1667 | else | ||
1668 | print_warn("Unsupported option \"%s\"", this_opt); | ||
1669 | } | ||
1670 | |||
1671 | out: | ||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | /* AU1200 LCD controller device driver */ | ||
1593 | static int __devinit au1200fb_drv_probe(struct platform_device *dev) | 1676 | static int __devinit au1200fb_drv_probe(struct platform_device *dev) |
1594 | { | 1677 | { |
1595 | struct au1200fb_device *fbdev; | 1678 | struct au1200fb_device *fbdev; |
1679 | struct au1200fb_platdata *pd; | ||
1596 | struct fb_info *fbi = NULL; | 1680 | struct fb_info *fbi = NULL; |
1597 | unsigned long page; | 1681 | unsigned long page; |
1598 | int bpp, plane, ret, irq; | 1682 | int bpp, plane, ret, irq; |
1599 | 1683 | ||
1684 | print_info("" DRIVER_DESC ""); | ||
1685 | |||
1686 | pd = dev->dev.platform_data; | ||
1687 | if (!pd) | ||
1688 | return -ENODEV; | ||
1689 | |||
1690 | /* Setup driver with options */ | ||
1691 | if (au1200fb_setup(pd)) | ||
1692 | return -ENODEV; | ||
1693 | |||
1694 | /* Point to the panel selected */ | ||
1695 | panel = &known_lcd_panels[panel_index]; | ||
1696 | win = &windows[window_index]; | ||
1697 | |||
1698 | printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); | ||
1699 | printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); | ||
1700 | |||
1600 | /* shut gcc up */ | 1701 | /* shut gcc up */ |
1601 | ret = 0; | 1702 | ret = 0; |
1602 | fbdev = NULL; | 1703 | fbdev = NULL; |
1603 | 1704 | ||
1604 | /* Kickstart the panel */ | ||
1605 | au1200_setpanel(panel); | ||
1606 | |||
1607 | for (plane = 0; plane < device_count; ++plane) { | 1705 | for (plane = 0; plane < device_count; ++plane) { |
1608 | bpp = winbpp(win->w[plane].mode_winctrl1); | 1706 | bpp = winbpp(win->w[plane].mode_winctrl1); |
1609 | if (win->w[plane].xres == 0) | 1707 | if (win->w[plane].xres == 0) |
@@ -1619,6 +1717,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) | |||
1619 | _au1200fb_infos[plane] = fbi; | 1717 | _au1200fb_infos[plane] = fbi; |
1620 | fbdev = fbi->par; | 1718 | fbdev = fbi->par; |
1621 | fbdev->fb_info = fbi; | 1719 | fbdev->fb_info = fbi; |
1720 | fbdev->pd = pd; | ||
1622 | 1721 | ||
1623 | fbdev->plane = plane; | 1722 | fbdev->plane = plane; |
1624 | 1723 | ||
@@ -1680,6 +1779,11 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) | |||
1680 | goto failed; | 1779 | goto failed; |
1681 | } | 1780 | } |
1682 | 1781 | ||
1782 | platform_set_drvdata(dev, pd); | ||
1783 | |||
1784 | /* Kickstart the panel */ | ||
1785 | au1200_setpanel(panel, pd); | ||
1786 | |||
1683 | return 0; | 1787 | return 0; |
1684 | 1788 | ||
1685 | failed: | 1789 | failed: |
@@ -1699,12 +1803,13 @@ failed: | |||
1699 | 1803 | ||
1700 | static int __devexit au1200fb_drv_remove(struct platform_device *dev) | 1804 | static int __devexit au1200fb_drv_remove(struct platform_device *dev) |
1701 | { | 1805 | { |
1806 | struct au1200fb_platdata *pd = platform_get_drvdata(dev); | ||
1702 | struct au1200fb_device *fbdev; | 1807 | struct au1200fb_device *fbdev; |
1703 | struct fb_info *fbi; | 1808 | struct fb_info *fbi; |
1704 | int plane; | 1809 | int plane; |
1705 | 1810 | ||
1706 | /* Turn off the panel */ | 1811 | /* Turn off the panel */ |
1707 | au1200_setpanel(NULL); | 1812 | au1200_setpanel(NULL, pd); |
1708 | 1813 | ||
1709 | for (plane = 0; plane < device_count; ++plane) { | 1814 | for (plane = 0; plane < device_count; ++plane) { |
1710 | fbi = _au1200fb_infos[plane]; | 1815 | fbi = _au1200fb_infos[plane]; |
@@ -1732,7 +1837,8 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev) | |||
1732 | #ifdef CONFIG_PM | 1837 | #ifdef CONFIG_PM |
1733 | static int au1200fb_drv_suspend(struct device *dev) | 1838 | static int au1200fb_drv_suspend(struct device *dev) |
1734 | { | 1839 | { |
1735 | au1200_setpanel(NULL); | 1840 | struct au1200fb_platdata *pd = dev_get_drvdata(dev); |
1841 | au1200_setpanel(NULL, pd); | ||
1736 | 1842 | ||
1737 | lcd->outmask = 0; | 1843 | lcd->outmask = 0; |
1738 | au_sync(); | 1844 | au_sync(); |
@@ -1742,11 +1848,12 @@ static int au1200fb_drv_suspend(struct device *dev) | |||
1742 | 1848 | ||
1743 | static int au1200fb_drv_resume(struct device *dev) | 1849 | static int au1200fb_drv_resume(struct device *dev) |
1744 | { | 1850 | { |
1851 | struct au1200fb_platdata *pd = dev_get_drvdata(dev); | ||
1745 | struct fb_info *fbi; | 1852 | struct fb_info *fbi; |
1746 | int i; | 1853 | int i; |
1747 | 1854 | ||
1748 | /* Kickstart the panel */ | 1855 | /* Kickstart the panel */ |
1749 | au1200_setpanel(panel); | 1856 | au1200_setpanel(panel, pd); |
1750 | 1857 | ||
1751 | for (i = 0; i < device_count; i++) { | 1858 | for (i = 0; i < device_count; i++) { |
1752 | fbi = _au1200fb_infos[i]; | 1859 | fbi = _au1200fb_infos[i]; |
@@ -1781,100 +1888,8 @@ static struct platform_driver au1200fb_driver = { | |||
1781 | 1888 | ||
1782 | /*-------------------------------------------------------------------------*/ | 1889 | /*-------------------------------------------------------------------------*/ |
1783 | 1890 | ||
1784 | /* Kernel driver */ | ||
1785 | |||
1786 | static int au1200fb_setup(void) | ||
1787 | { | ||
1788 | char *options = NULL; | ||
1789 | char *this_opt, *endptr; | ||
1790 | int num_panels = ARRAY_SIZE(known_lcd_panels); | ||
1791 | int panel_idx = -1; | ||
1792 | |||
1793 | fb_get_options(DRIVER_NAME, &options); | ||
1794 | |||
1795 | if (options) { | ||
1796 | while ((this_opt = strsep(&options,",")) != NULL) { | ||
1797 | /* Panel option - can be panel name, | ||
1798 | * "bs" for board-switch, or number/index */ | ||
1799 | if (!strncmp(this_opt, "panel:", 6)) { | ||
1800 | int i; | ||
1801 | long int li; | ||
1802 | char *endptr; | ||
1803 | this_opt += 6; | ||
1804 | /* First check for index, which allows | ||
1805 | * to short circuit this mess */ | ||
1806 | li = simple_strtol(this_opt, &endptr, 0); | ||
1807 | if (*endptr == '\0') { | ||
1808 | panel_idx = (int)li; | ||
1809 | } | ||
1810 | else if (strcmp(this_opt, "bs") == 0) { | ||
1811 | extern int board_au1200fb_panel(void); | ||
1812 | panel_idx = board_au1200fb_panel(); | ||
1813 | } | ||
1814 | |||
1815 | else | ||
1816 | for (i = 0; i < num_panels; i++) { | ||
1817 | if (!strcmp(this_opt, known_lcd_panels[i].name)) { | ||
1818 | panel_idx = i; | ||
1819 | break; | ||
1820 | } | ||
1821 | } | ||
1822 | |||
1823 | if ((panel_idx < 0) || (panel_idx >= num_panels)) { | ||
1824 | print_warn("Panel %s not supported!", this_opt); | ||
1825 | } | ||
1826 | else | ||
1827 | panel_index = panel_idx; | ||
1828 | } | ||
1829 | |||
1830 | else if (strncmp(this_opt, "nohwcursor", 10) == 0) { | ||
1831 | nohwcursor = 1; | ||
1832 | } | ||
1833 | |||
1834 | else if (strncmp(this_opt, "devices:", 8) == 0) { | ||
1835 | this_opt += 8; | ||
1836 | device_count = simple_strtol(this_opt, | ||
1837 | &endptr, 0); | ||
1838 | if ((device_count < 0) || | ||
1839 | (device_count > MAX_DEVICE_COUNT)) | ||
1840 | device_count = MAX_DEVICE_COUNT; | ||
1841 | } | ||
1842 | |||
1843 | else if (strncmp(this_opt, "wincfg:", 7) == 0) { | ||
1844 | this_opt += 7; | ||
1845 | window_index = simple_strtol(this_opt, | ||
1846 | &endptr, 0); | ||
1847 | if ((window_index < 0) || | ||
1848 | (window_index >= ARRAY_SIZE(windows))) | ||
1849 | window_index = DEFAULT_WINDOW_INDEX; | ||
1850 | } | ||
1851 | |||
1852 | else if (strncmp(this_opt, "off", 3) == 0) | ||
1853 | return 1; | ||
1854 | /* Unsupported option */ | ||
1855 | else { | ||
1856 | print_warn("Unsupported option \"%s\"", this_opt); | ||
1857 | } | ||
1858 | } | ||
1859 | } | ||
1860 | return 0; | ||
1861 | } | ||
1862 | |||
1863 | static int __init au1200fb_init(void) | 1891 | static int __init au1200fb_init(void) |
1864 | { | 1892 | { |
1865 | print_info("" DRIVER_DESC ""); | ||
1866 | |||
1867 | /* Setup driver with options */ | ||
1868 | if (au1200fb_setup()) | ||
1869 | return -ENODEV; | ||
1870 | |||
1871 | /* Point to the panel selected */ | ||
1872 | panel = &known_lcd_panels[panel_index]; | ||
1873 | win = &windows[window_index]; | ||
1874 | |||
1875 | printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name); | ||
1876 | printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name); | ||
1877 | |||
1878 | return platform_driver_register(&au1200fb_driver); | 1893 | return platform_driver_register(&au1200fb_driver); |
1879 | } | 1894 | } |
1880 | 1895 | ||
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 93317b5b8740..a122d9287d16 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c | |||
@@ -25,14 +25,13 @@ | |||
25 | #include <asm/system.h> | 25 | #include <asm/system.h> |
26 | #include <asm/page.h> | 26 | #include <asm/page.h> |
27 | #include <asm/pgtable.h> | 27 | #include <asm/pgtable.h> |
28 | #include <asm/gio_device.h> | ||
29 | |||
28 | #include <video/newport.h> | 30 | #include <video/newport.h> |
29 | 31 | ||
30 | #include <linux/linux_logo.h> | 32 | #include <linux/linux_logo.h> |
31 | #include <linux/font.h> | 33 | #include <linux/font.h> |
32 | 34 | ||
33 | |||
34 | extern unsigned long sgi_gfxaddr; | ||
35 | |||
36 | #define FONT_DATA ((unsigned char *)font_vga_8x16.data) | 35 | #define FONT_DATA ((unsigned char *)font_vga_8x16.data) |
37 | 36 | ||
38 | /* borrowed from fbcon.c */ | 37 | /* borrowed from fbcon.c */ |
@@ -304,12 +303,6 @@ static const char *newport_startup(void) | |||
304 | { | 303 | { |
305 | int i; | 304 | int i; |
306 | 305 | ||
307 | if (!sgi_gfxaddr) | ||
308 | return NULL; | ||
309 | |||
310 | if (!npregs) | ||
311 | npregs = (struct newport_regs *)/* ioremap cannot fail */ | ||
312 | ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); | ||
313 | npregs->cset.config = NPORT_CFG_GD0; | 306 | npregs->cset.config = NPORT_CFG_GD0; |
314 | 307 | ||
315 | if (newport_wait(npregs)) | 308 | if (newport_wait(npregs)) |
@@ -743,26 +736,58 @@ const struct consw newport_con = { | |||
743 | .con_save_screen = DUMMY | 736 | .con_save_screen = DUMMY |
744 | }; | 737 | }; |
745 | 738 | ||
746 | #ifdef MODULE | 739 | static int newport_probe(struct gio_device *dev, |
747 | static int __init newport_console_init(void) | 740 | const struct gio_device_id *id) |
748 | { | 741 | { |
749 | if (!sgi_gfxaddr) | 742 | unsigned long newport_addr; |
750 | return 0; | ||
751 | 743 | ||
752 | if (!npregs) | 744 | if (!dev->resource.start) |
753 | npregs = (struct newport_regs *)/* ioremap cannot fail */ | 745 | return -EINVAL; |
754 | ioremap(sgi_gfxaddr, sizeof(struct newport_regs)); | 746 | |
747 | if (npregs) | ||
748 | return -EBUSY; /* we only support one Newport as console */ | ||
749 | |||
750 | newport_addr = dev->resource.start + 0xF0000; | ||
751 | if (!request_mem_region(newport_addr, 0x10000, "Newport")) | ||
752 | return -ENODEV; | ||
753 | |||
754 | npregs = (struct newport_regs *)/* ioremap cannot fail */ | ||
755 | ioremap(newport_addr, sizeof(struct newport_regs)); | ||
755 | 756 | ||
756 | return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); | 757 | return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1); |
757 | } | 758 | } |
758 | module_init(newport_console_init); | ||
759 | 759 | ||
760 | static void __exit newport_console_exit(void) | 760 | static void newport_remove(struct gio_device *dev) |
761 | { | 761 | { |
762 | give_up_console(&newport_con); | 762 | give_up_console(&newport_con); |
763 | iounmap((void *)npregs); | 763 | iounmap((void *)npregs); |
764 | } | 764 | } |
765 | |||
766 | static struct gio_device_id newport_ids[] = { | ||
767 | { .id = 0x7e }, | ||
768 | { .id = 0xff } | ||
769 | }; | ||
770 | |||
771 | MODULE_ALIAS("gio:7e"); | ||
772 | |||
773 | static struct gio_driver newport_driver = { | ||
774 | .name = "newport", | ||
775 | .id_table = newport_ids, | ||
776 | .probe = newport_probe, | ||
777 | .remove = newport_remove, | ||
778 | }; | ||
779 | |||
780 | int __init newport_console_init(void) | ||
781 | { | ||
782 | return gio_register_driver(&newport_driver); | ||
783 | } | ||
784 | |||
785 | void __exit newport_console_exit(void) | ||
786 | { | ||
787 | gio_unregister_driver(&newport_driver); | ||
788 | } | ||
789 | |||
790 | module_init(newport_console_init); | ||
765 | module_exit(newport_console_exit); | 791 | module_exit(newport_console_exit); |
766 | #endif | ||
767 | 792 | ||
768 | MODULE_LICENSE("GPL"); | 793 | MODULE_LICENSE("GPL"); |