2 * Based on linux/arch/mips/txx9/rbtx4938/setup.c,
3 * and RBTX49xx patch from CELF patch archive.
5 * 2003-2005 (c) MontaVista Software, Inc.
6 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/interrupt.h>
16 #include <linux/string.h>
17 #include <linux/module.h>
18 #include <linux/clk.h>
19 #include <linux/err.h>
20 #include <linux/gpio.h>
21 #include <linux/platform_device.h>
22 #include <linux/serial_core.h>
23 #include <linux/mtd/physmap.h>
24 #include <linux/leds.h>
25 #include <linux/device.h>
26 #include <linux/slab.h>
27 #include <linux/irq.h>
28 #include <asm/bootinfo.h>
31 #include <asm/reboot.h>
32 #include <asm/r4kcache.h>
33 #include <asm/sections.h>
34 #include <asm/txx9/generic.h>
35 #include <asm/txx9/pci.h>
36 #include <asm/txx9tmr.h>
37 #include <asm/txx9/ndfmc.h>
38 #include <asm/txx9/dmac.h>
39 #ifdef CONFIG_CPU_TX49XX
40 #include <asm/txx9/tx4938.h>
43 /* EBUSC settings of TX4927, etc. */
44 struct resource txx9_ce_res
[8];
45 static char txx9_ce_res_name
[8][4]; /* "CEn" */
47 /* pcode, internal register */
48 unsigned int txx9_pcode
;
49 char txx9_pcode_str
[8];
50 static struct resource txx9_reg_res
= {
51 .name
= txx9_pcode_str
,
52 .flags
= IORESOURCE_MEM
,
55 txx9_reg_res_init(unsigned int pcode
, unsigned long base
, unsigned long size
)
59 for (i
= 0; i
< ARRAY_SIZE(txx9_ce_res
); i
++) {
60 sprintf(txx9_ce_res_name
[i
], "CE%d", i
);
61 txx9_ce_res
[i
].flags
= IORESOURCE_MEM
;
62 txx9_ce_res
[i
].name
= txx9_ce_res_name
[i
];
66 sprintf(txx9_pcode_str
, "TX%x", pcode
);
68 txx9_reg_res
.start
= base
& 0xfffffffffULL
;
69 txx9_reg_res
.end
= (base
& 0xfffffffffULL
) + (size
- 1);
70 request_resource(&iomem_resource
, &txx9_reg_res
);
75 unsigned int txx9_master_clock
;
76 unsigned int txx9_cpu_clock
;
77 unsigned int txx9_gbus_clock
;
79 #ifdef CONFIG_CPU_TX39XX
80 /* don't enable by default - see errata */
81 int txx9_ccfg_toeon __initdata
;
83 int txx9_ccfg_toeon __initdata
= 1;
86 /* Minimum CLK support */
88 struct clk
*clk_get(struct device
*dev
, const char *id
)
90 if (!strcmp(id
, "spi-baseclk"))
91 return (struct clk
*)((unsigned long)txx9_gbus_clock
/ 2 / 2);
92 if (!strcmp(id
, "imbus_clk"))
93 return (struct clk
*)((unsigned long)txx9_gbus_clock
/ 2);
94 return ERR_PTR(-ENOENT
);
96 EXPORT_SYMBOL(clk_get
);
98 int clk_enable(struct clk
*clk
)
102 EXPORT_SYMBOL(clk_enable
);
104 void clk_disable(struct clk
*clk
)
107 EXPORT_SYMBOL(clk_disable
);
109 unsigned long clk_get_rate(struct clk
*clk
)
111 return (unsigned long)clk
;
113 EXPORT_SYMBOL(clk_get_rate
);
115 void clk_put(struct clk
*clk
)
118 EXPORT_SYMBOL(clk_put
);
122 #ifdef CONFIG_GPIOLIB
123 int gpio_to_irq(unsigned gpio
)
127 EXPORT_SYMBOL(gpio_to_irq
);
129 int irq_to_gpio(unsigned irq
)
133 EXPORT_SYMBOL(irq_to_gpio
);
136 #define BOARD_VEC(board) extern struct txx9_board_vec board;
137 #include <asm/txx9/boards.h>
140 struct txx9_board_vec
*txx9_board_vec __initdata
;
141 static char txx9_system_type
[32];
143 static struct txx9_board_vec
*board_vecs
[] __initdata
= {
144 #define BOARD_VEC(board) &board,
145 #include <asm/txx9/boards.h>
149 static struct txx9_board_vec
*__init
find_board_byname(const char *name
)
153 /* search board_vecs table */
154 for (i
= 0; i
< ARRAY_SIZE(board_vecs
); i
++) {
155 if (strstr(board_vecs
[i
]->system
, name
))
156 return board_vecs
[i
];
161 static void __init
prom_init_cmdline(void)
165 int i
; /* Always ignore the "-c" at argv[0] */
167 if (fw_arg0
>= CKSEG0
|| fw_arg1
< CKSEG0
) {
169 * argc is not a valid number, or argv32 is not a valid
176 argv32
= (int *)fw_arg1
;
179 arcs_cmdline
[0] = '\0';
181 for (i
= 1; i
< argc
; i
++) {
182 char *str
= (char *)(long)argv32
[i
];
184 strcat(arcs_cmdline
, " ");
185 if (strchr(str
, ' ')) {
186 strcat(arcs_cmdline
, "\"");
187 strcat(arcs_cmdline
, str
);
188 strcat(arcs_cmdline
, "\"");
190 strcat(arcs_cmdline
, str
);
194 static int txx9_ic_disable __initdata
;
195 static int txx9_dc_disable __initdata
;
197 #if defined(CONFIG_CPU_TX49XX)
198 /* flush all cache on very early stage (before 4k_cache_init) */
199 static void __init
early_flush_dcache(void)
201 unsigned int conf
= read_c0_config();
202 unsigned int dc_size
= 1 << (12 + ((conf
& CONF_DC
) >> 6));
203 unsigned int linesz
= 32;
204 unsigned long addr
, end
;
206 end
= INDEX_BASE
+ dc_size
/ 4;
208 for (addr
= INDEX_BASE
; addr
< end
; addr
+= linesz
) {
209 cache_op(Index_Writeback_Inv_D
, addr
| 0);
210 cache_op(Index_Writeback_Inv_D
, addr
| 1);
211 cache_op(Index_Writeback_Inv_D
, addr
| 2);
212 cache_op(Index_Writeback_Inv_D
, addr
| 3);
216 static void __init
txx9_cache_fixup(void)
220 conf
= read_c0_config();
221 /* flush and disable */
222 if (txx9_ic_disable
) {
223 conf
|= TX49_CONF_IC
;
224 write_c0_config(conf
);
226 if (txx9_dc_disable
) {
227 early_flush_dcache();
228 conf
|= TX49_CONF_DC
;
229 write_c0_config(conf
);
233 conf
= read_c0_config();
234 if (!txx9_ic_disable
)
235 conf
&= ~TX49_CONF_IC
;
236 if (!txx9_dc_disable
)
237 conf
&= ~TX49_CONF_DC
;
238 write_c0_config(conf
);
240 if (conf
& TX49_CONF_IC
)
241 pr_info("TX49XX I-Cache disabled.\n");
242 if (conf
& TX49_CONF_DC
)
243 pr_info("TX49XX D-Cache disabled.\n");
245 #elif defined(CONFIG_CPU_TX39XX)
246 /* flush all cache on very early stage (before tx39_cache_init) */
247 static void __init
early_flush_dcache(void)
249 unsigned int conf
= read_c0_config();
250 unsigned int dc_size
= 1 << (10 + ((conf
& TX39_CONF_DCS_MASK
) >>
251 TX39_CONF_DCS_SHIFT
));
252 unsigned int linesz
= 16;
253 unsigned long addr
, end
;
255 end
= INDEX_BASE
+ dc_size
/ 2;
257 for (addr
= INDEX_BASE
; addr
< end
; addr
+= linesz
) {
258 cache_op(Index_Writeback_Inv_D
, addr
| 0);
259 cache_op(Index_Writeback_Inv_D
, addr
| 1);
263 static void __init
txx9_cache_fixup(void)
267 conf
= read_c0_config();
268 /* flush and disable */
269 if (txx9_ic_disable
) {
270 conf
&= ~TX39_CONF_ICE
;
271 write_c0_config(conf
);
273 if (txx9_dc_disable
) {
274 early_flush_dcache();
275 conf
&= ~TX39_CONF_DCE
;
276 write_c0_config(conf
);
280 conf
= read_c0_config();
281 if (!txx9_ic_disable
)
282 conf
|= TX39_CONF_ICE
;
283 if (!txx9_dc_disable
)
284 conf
|= TX39_CONF_DCE
;
285 write_c0_config(conf
);
287 if (!(conf
& TX39_CONF_ICE
))
288 pr_info("TX39XX I-Cache disabled.\n");
289 if (!(conf
& TX39_CONF_DCE
))
290 pr_info("TX39XX D-Cache disabled.\n");
293 static inline void txx9_cache_fixup(void)
298 static void __init
preprocess_cmdline(void)
300 static char cmdline
[COMMAND_LINE_SIZE
] __initdata
;
303 strcpy(cmdline
, arcs_cmdline
);
305 arcs_cmdline
[0] = '\0';
307 char *str
= strsep(&s
, " ");
308 if (strncmp(str
, "board=", 6) == 0) {
309 txx9_board_vec
= find_board_byname(str
+ 6);
311 } else if (strncmp(str
, "masterclk=", 10) == 0) {
313 if (strict_strtoul(str
+ 10, 10, &val
) == 0)
314 txx9_master_clock
= val
;
316 } else if (strcmp(str
, "icdisable") == 0) {
319 } else if (strcmp(str
, "dcdisable") == 0) {
322 } else if (strcmp(str
, "toeoff") == 0) {
325 } else if (strcmp(str
, "toeon") == 0) {
330 strcat(arcs_cmdline
, " ");
331 strcat(arcs_cmdline
, str
);
337 static void __init
select_board(void)
341 /* first, determine by "board=" argument in preprocess_cmdline() */
344 /* next, determine by "board" envvar */
345 envstr
= prom_getenv("board");
347 txx9_board_vec
= find_board_byname(envstr
);
352 /* select "default" board */
353 #ifdef CONFIG_CPU_TX39XX
354 txx9_board_vec
= &jmr3927_vec
;
356 #ifdef CONFIG_CPU_TX49XX
357 switch (TX4938_REV_PCODE()) {
358 #ifdef CONFIG_TOSHIBA_RBTX4927
360 txx9_board_vec
= &rbtx4927_vec
;
363 txx9_board_vec
= &rbtx4937_vec
;
366 #ifdef CONFIG_TOSHIBA_RBTX4938
368 txx9_board_vec
= &rbtx4938_vec
;
371 #ifdef CONFIG_TOSHIBA_RBTX4939
373 txx9_board_vec
= &rbtx4939_vec
;
380 void __init
prom_init(void)
383 preprocess_cmdline();
386 strcpy(txx9_system_type
, txx9_board_vec
->system
);
388 txx9_board_vec
->prom_init();
391 void __init
prom_free_prom_memory(void)
393 unsigned long saddr
= PAGE_SIZE
;
394 unsigned long eaddr
= __pa_symbol(&_text
);
397 free_init_pages("prom memory", saddr
, eaddr
);
400 const char *get_system_type(void)
402 return txx9_system_type
;
405 const char *__init
prom_getenv(const char *name
)
409 if (fw_arg2
< CKSEG0
)
412 str
= (const s32
*)fw_arg2
;
413 /* YAMON style ("name", "value" pairs) */
414 while (str
[0] && str
[1]) {
415 if (!strcmp((const char *)(unsigned long)str
[0], name
))
416 return (const char *)(unsigned long)str
[1];
422 static void __noreturn
txx9_machine_halt(void)
425 clear_c0_status(ST0_IM
);
429 if (cpu_has_counter
) {
431 * Clear counter interrupt while it
432 * breaks WAIT instruction even if
441 /* Watchdog support */
442 void __init
txx9_wdt_init(unsigned long base
)
444 struct resource res
= {
446 .end
= base
+ 0x100 - 1,
447 .flags
= IORESOURCE_MEM
,
449 platform_device_register_simple("txx9wdt", -1, &res
, 1);
452 void txx9_wdt_now(unsigned long base
)
454 struct txx9_tmr_reg __iomem
*tmrptr
=
455 ioremap(base
, sizeof(struct txx9_tmr_reg
));
456 /* disable watch dog timer */
457 __raw_writel(TXx9_TMWTMR_WDIS
| TXx9_TMWTMR_TWC
, &tmrptr
->wtmr
);
458 __raw_writel(0, &tmrptr
->tcr
);
460 __raw_writel(TXx9_TMWTMR_TWIE
, &tmrptr
->wtmr
);
461 __raw_writel(1, &tmrptr
->cpra
); /* immediate */
462 __raw_writel(TXx9_TMTCR_TCE
| TXx9_TMTCR_CCDE
| TXx9_TMTCR_TMODE_WDOG
,
467 void __init
txx9_spi_init(int busid
, unsigned long base
, int irq
)
469 struct resource res
[] = {
472 .end
= base
+ 0x20 - 1,
473 .flags
= IORESOURCE_MEM
,
476 .flags
= IORESOURCE_IRQ
,
479 platform_device_register_simple("spi_txx9", busid
,
480 res
, ARRAY_SIZE(res
));
483 void __init
txx9_ethaddr_init(unsigned int id
, unsigned char *ethaddr
)
485 struct platform_device
*pdev
=
486 platform_device_alloc("tc35815-mac", id
);
488 platform_device_add_data(pdev
, ethaddr
, 6) ||
489 platform_device_add(pdev
))
490 platform_device_put(pdev
);
493 void __init
txx9_sio_init(unsigned long baseaddr
, int irq
,
494 unsigned int line
, unsigned int sclk
, int nocts
)
496 #ifdef CONFIG_SERIAL_TXX9
497 struct uart_port req
;
499 memset(&req
, 0, sizeof(req
));
501 req
.iotype
= UPIO_MEM
;
502 req
.membase
= ioremap(baseaddr
, 0x24);
503 req
.mapbase
= baseaddr
;
506 req
.flags
|= UPF_BUGGY_UART
/*HAVE_CTS_LINE*/;
508 req
.flags
|= UPF_MAGIC_MULTIPLIER
/*USE_SCLK*/;
511 req
.uartclk
= TXX9_IMCLK
;
512 early_serial_txx9_setup(&req
);
513 #endif /* CONFIG_SERIAL_TXX9 */
516 #ifdef CONFIG_EARLY_PRINTK
517 static void null_prom_putchar(char c
)
520 void (*txx9_prom_putchar
)(char c
) = null_prom_putchar
;
522 void prom_putchar(char c
)
524 txx9_prom_putchar(c
);
527 static void __iomem
*early_txx9_sio_port
;
529 static void early_txx9_sio_putchar(char c
)
531 #define TXX9_SICISR 0x0c
532 #define TXX9_SITFIFO 0x1c
533 #define TXX9_SICISR_TXALS 0x00000002
534 while (!(__raw_readl(early_txx9_sio_port
+ TXX9_SICISR
) &
537 __raw_writel(c
, early_txx9_sio_port
+ TXX9_SITFIFO
);
540 void __init
txx9_sio_putchar_init(unsigned long baseaddr
)
542 early_txx9_sio_port
= ioremap(baseaddr
, 0x24);
543 txx9_prom_putchar
= early_txx9_sio_putchar
;
545 #endif /* CONFIG_EARLY_PRINTK */
548 void __init
plat_mem_setup(void)
550 ioport_resource
.start
= 0;
551 ioport_resource
.end
= ~0UL; /* no limit */
552 iomem_resource
.start
= 0;
553 iomem_resource
.end
= ~0UL; /* no limit */
555 /* fallback restart/halt routines */
556 _machine_restart
= (void (*)(char *))txx9_machine_halt
;
557 _machine_halt
= txx9_machine_halt
;
558 pm_power_off
= txx9_machine_halt
;
561 pcibios_plat_setup
= txx9_pcibios_setup
;
563 txx9_board_vec
->mem_setup();
566 void __init
arch_init_irq(void)
568 txx9_board_vec
->irq_setup();
571 void __init
plat_time_init(void)
573 #ifdef CONFIG_CPU_TX49XX
574 mips_hpt_frequency
= txx9_cpu_clock
/ 2;
576 txx9_board_vec
->time_init();
579 static int __init
_txx9_arch_init(void)
581 if (txx9_board_vec
->arch_init
)
582 txx9_board_vec
->arch_init();
585 arch_initcall(_txx9_arch_init
);
587 static int __init
_txx9_device_init(void)
589 if (txx9_board_vec
->device_init
)
590 txx9_board_vec
->device_init();
593 device_initcall(_txx9_device_init
);
595 int (*txx9_irq_dispatch
)(int pending
);
596 asmlinkage
void plat_irq_dispatch(void)
598 int pending
= read_c0_status() & read_c0_cause() & ST0_IM
;
599 int irq
= txx9_irq_dispatch(pending
);
601 if (likely(irq
>= 0))
604 spurious_interrupt();
607 /* see include/asm-mips/mach-tx39xx/mangle-port.h, for example. */
608 #ifdef NEEDS_TXX9_SWIZZLE_ADDR_B
609 static unsigned long __swizzle_addr_none(unsigned long port
)
613 unsigned long (*__swizzle_addr_b
)(unsigned long port
) = __swizzle_addr_none
;
614 EXPORT_SYMBOL(__swizzle_addr_b
);
617 #ifdef NEEDS_TXX9_IOSWABW
618 static u16
ioswabw_default(volatile u16
*a
, u16 x
)
620 return le16_to_cpu(x
);
622 static u16
__mem_ioswabw_default(volatile u16
*a
, u16 x
)
626 u16 (*ioswabw
)(volatile u16
*a
, u16 x
) = ioswabw_default
;
627 EXPORT_SYMBOL(ioswabw
);
628 u16 (*__mem_ioswabw
)(volatile u16
*a
, u16 x
) = __mem_ioswabw_default
;
629 EXPORT_SYMBOL(__mem_ioswabw
);
632 void __init
txx9_physmap_flash_init(int no
, unsigned long addr
,
634 const struct physmap_flash_data
*pdata
)
636 #if IS_ENABLED(CONFIG_MTD_PHYSMAP)
637 struct resource res
= {
639 .end
= addr
+ size
- 1,
640 .flags
= IORESOURCE_MEM
,
642 struct platform_device
*pdev
;
643 static struct mtd_partition parts
[2];
644 struct physmap_flash_data pdata_part
;
646 /* If this area contained boot area, make separate partition */
647 if (pdata
->nr_parts
== 0 && !pdata
->parts
&&
648 addr
< 0x1fc00000 && addr
+ size
> 0x1fc00000 &&
650 parts
[0].name
= "boot";
651 parts
[0].offset
= 0x1fc00000 - addr
;
652 parts
[0].size
= addr
+ size
- 0x1fc00000;
653 parts
[1].name
= "user";
655 parts
[1].size
= 0x1fc00000 - addr
;
657 pdata_part
.nr_parts
= ARRAY_SIZE(parts
);
658 pdata_part
.parts
= parts
;
662 pdev
= platform_device_alloc("physmap-flash", no
);
664 platform_device_add_resources(pdev
, &res
, 1) ||
665 platform_device_add_data(pdev
, pdata
, sizeof(*pdata
)) ||
666 platform_device_add(pdev
))
667 platform_device_put(pdev
);
671 void __init
txx9_ndfmc_init(unsigned long baseaddr
,
672 const struct txx9ndfmc_platform_data
*pdata
)
674 #if IS_ENABLED(CONFIG_MTD_NAND_TXX9NDFMC)
675 struct resource res
= {
677 .end
= baseaddr
+ 0x1000 - 1,
678 .flags
= IORESOURCE_MEM
,
680 struct platform_device
*pdev
= platform_device_alloc("txx9ndfmc", -1);
683 platform_device_add_resources(pdev
, &res
, 1) ||
684 platform_device_add_data(pdev
, pdata
, sizeof(*pdata
)) ||
685 platform_device_add(pdev
))
686 platform_device_put(pdev
);
690 #if IS_ENABLED(CONFIG_LEDS_GPIO)
691 static DEFINE_SPINLOCK(txx9_iocled_lock
);
693 #define TXX9_IOCLED_MAXLEDS 8
695 struct txx9_iocled_data
{
696 struct gpio_chip chip
;
698 void __iomem
*mmioaddr
;
699 struct gpio_led_platform_data pdata
;
700 struct gpio_led leds
[TXX9_IOCLED_MAXLEDS
];
701 char names
[TXX9_IOCLED_MAXLEDS
][32];
704 static int txx9_iocled_get(struct gpio_chip
*chip
, unsigned int offset
)
706 struct txx9_iocled_data
*data
=
707 container_of(chip
, struct txx9_iocled_data
, chip
);
708 return data
->cur_val
& (1 << offset
);
711 static void txx9_iocled_set(struct gpio_chip
*chip
, unsigned int offset
,
714 struct txx9_iocled_data
*data
=
715 container_of(chip
, struct txx9_iocled_data
, chip
);
717 spin_lock_irqsave(&txx9_iocled_lock
, flags
);
719 data
->cur_val
|= 1 << offset
;
721 data
->cur_val
&= ~(1 << offset
);
722 writeb(data
->cur_val
, data
->mmioaddr
);
724 spin_unlock_irqrestore(&txx9_iocled_lock
, flags
);
727 static int txx9_iocled_dir_in(struct gpio_chip
*chip
, unsigned int offset
)
732 static int txx9_iocled_dir_out(struct gpio_chip
*chip
, unsigned int offset
,
735 txx9_iocled_set(chip
, offset
, value
);
739 void __init
txx9_iocled_init(unsigned long baseaddr
,
740 int basenum
, unsigned int num
, int lowactive
,
741 const char *color
, char **deftriggers
)
743 struct txx9_iocled_data
*iocled
;
744 struct platform_device
*pdev
;
746 static char *default_triggers
[] __initdata
= {
754 deftriggers
= default_triggers
;
755 iocled
= kzalloc(sizeof(*iocled
), GFP_KERNEL
);
758 iocled
->mmioaddr
= ioremap(baseaddr
, 1);
759 if (!iocled
->mmioaddr
)
761 iocled
->chip
.get
= txx9_iocled_get
;
762 iocled
->chip
.set
= txx9_iocled_set
;
763 iocled
->chip
.direction_input
= txx9_iocled_dir_in
;
764 iocled
->chip
.direction_output
= txx9_iocled_dir_out
;
765 iocled
->chip
.label
= "iocled";
766 iocled
->chip
.base
= basenum
;
767 iocled
->chip
.ngpio
= num
;
768 if (gpiochip_add(&iocled
->chip
))
771 basenum
= iocled
->chip
.base
;
773 pdev
= platform_device_alloc("leds-gpio", basenum
);
776 iocled
->pdata
.num_leds
= num
;
777 iocled
->pdata
.leds
= iocled
->leds
;
778 for (i
= 0; i
< num
; i
++) {
779 struct gpio_led
*led
= &iocled
->leds
[i
];
780 snprintf(iocled
->names
[i
], sizeof(iocled
->names
[i
]),
781 "iocled:%s:%u", color
, i
);
782 led
->name
= iocled
->names
[i
];
783 led
->gpio
= basenum
+ i
;
784 led
->active_low
= lowactive
;
785 if (deftriggers
&& *deftriggers
)
786 led
->default_trigger
= *deftriggers
++;
788 pdev
->dev
.platform_data
= &iocled
->pdata
;
789 if (platform_device_add(pdev
))
793 platform_device_put(pdev
);
795 if (gpiochip_remove(&iocled
->chip
))
798 iounmap(iocled
->mmioaddr
);
802 #else /* CONFIG_LEDS_GPIO */
803 void __init
txx9_iocled_init(unsigned long baseaddr
,
804 int basenum
, unsigned int num
, int lowactive
,
805 const char *color
, char **deftriggers
)
808 #endif /* CONFIG_LEDS_GPIO */
810 void __init
txx9_dmac_init(int id
, unsigned long baseaddr
, int irq
,
811 const struct txx9dmac_platform_data
*pdata
)
813 #if IS_ENABLED(CONFIG_TXX9_DMAC)
814 struct resource res
[] = {
817 .end
= baseaddr
+ 0x800 - 1,
818 .flags
= IORESOURCE_MEM
,
819 #ifndef CONFIG_MACH_TX49XX
822 .flags
= IORESOURCE_IRQ
,
826 #ifdef CONFIG_MACH_TX49XX
827 struct resource chan_res
[] = {
829 .flags
= IORESOURCE_IRQ
,
833 struct platform_device
*pdev
= platform_device_alloc("txx9dmac", id
);
834 struct txx9dmac_chan_platform_data cpdata
;
838 platform_device_add_resources(pdev
, res
, ARRAY_SIZE(res
)) ||
839 platform_device_add_data(pdev
, pdata
, sizeof(*pdata
)) ||
840 platform_device_add(pdev
)) {
841 platform_device_put(pdev
);
844 memset(&cpdata
, 0, sizeof(cpdata
));
845 cpdata
.dmac_dev
= pdev
;
846 for (i
= 0; i
< TXX9_DMA_MAX_NR_CHANNELS
; i
++) {
847 #ifdef CONFIG_MACH_TX49XX
848 chan_res
[0].start
= irq
+ i
;
850 pdev
= platform_device_alloc("txx9dmac-chan",
851 id
* TXX9_DMA_MAX_NR_CHANNELS
+ i
);
853 #ifdef CONFIG_MACH_TX49XX
854 platform_device_add_resources(pdev
, chan_res
,
855 ARRAY_SIZE(chan_res
)) ||
857 platform_device_add_data(pdev
, &cpdata
, sizeof(cpdata
)) ||
858 platform_device_add(pdev
))
859 platform_device_put(pdev
);
864 void __init
txx9_aclc_init(unsigned long baseaddr
, int irq
,
865 unsigned int dmac_id
,
866 unsigned int dma_chan_out
,
867 unsigned int dma_chan_in
)
869 #if IS_ENABLED(CONFIG_SND_SOC_TXX9ACLC)
870 unsigned int dma_base
= dmac_id
* TXX9_DMA_MAX_NR_CHANNELS
;
871 struct resource res
[] = {
874 .end
= baseaddr
+ 0x100 - 1,
875 .flags
= IORESOURCE_MEM
,
878 .flags
= IORESOURCE_IRQ
,
880 .name
= "txx9dmac-chan",
881 .start
= dma_base
+ dma_chan_out
,
882 .flags
= IORESOURCE_DMA
,
884 .name
= "txx9dmac-chan",
885 .start
= dma_base
+ dma_chan_in
,
886 .flags
= IORESOURCE_DMA
,
889 struct platform_device
*pdev
=
890 platform_device_alloc("txx9aclc-ac97", -1);
893 platform_device_add_resources(pdev
, res
, ARRAY_SIZE(res
)) ||
894 platform_device_add(pdev
))
895 platform_device_put(pdev
);
899 static struct bus_type txx9_sramc_subsys
= {
901 .dev_name
= "txx9_sram",
904 struct txx9_sramc_dev
{
906 struct bin_attribute bindata_attr
;
910 static ssize_t
txx9_sram_read(struct file
*filp
, struct kobject
*kobj
,
911 struct bin_attribute
*bin_attr
,
912 char *buf
, loff_t pos
, size_t size
)
914 struct txx9_sramc_dev
*dev
= bin_attr
->private;
915 size_t ramsize
= bin_attr
->size
;
919 if (pos
+ size
> ramsize
)
920 size
= ramsize
- pos
;
921 memcpy_fromio(buf
, dev
->base
+ pos
, size
);
925 static ssize_t
txx9_sram_write(struct file
*filp
, struct kobject
*kobj
,
926 struct bin_attribute
*bin_attr
,
927 char *buf
, loff_t pos
, size_t size
)
929 struct txx9_sramc_dev
*dev
= bin_attr
->private;
930 size_t ramsize
= bin_attr
->size
;
934 if (pos
+ size
> ramsize
)
935 size
= ramsize
- pos
;
936 memcpy_toio(dev
->base
+ pos
, buf
, size
);
940 void __init
txx9_sramc_init(struct resource
*r
)
942 struct txx9_sramc_dev
*dev
;
946 err
= subsys_system_register(&txx9_sramc_subsys
, NULL
);
949 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
952 size
= resource_size(r
);
953 dev
->base
= ioremap(r
->start
, size
);
956 dev
->dev
.bus
= &txx9_sramc_subsys
;
957 sysfs_bin_attr_init(&dev
->bindata_attr
);
958 dev
->bindata_attr
.attr
.name
= "bindata";
959 dev
->bindata_attr
.attr
.mode
= S_IRUSR
| S_IWUSR
;
960 dev
->bindata_attr
.read
= txx9_sram_read
;
961 dev
->bindata_attr
.write
= txx9_sram_write
;
962 dev
->bindata_attr
.size
= size
;
963 dev
->bindata_attr
.private = dev
;
964 err
= device_register(&dev
->dev
);
967 err
= sysfs_create_bin_file(&dev
->dev
.kobj
, &dev
->bindata_attr
);
969 device_unregister(&dev
->dev
);