From: Eugene Konev Date: Sun, 25 Mar 2007 05:42:16 +0000 (+0000) Subject: ar7: clocks setup (prerequisite for dsl/usb) and misc cleanups. X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=d81c7f76b91ad14244f1e036f29c806d85db5809;p=openwrt%2Fstaging%2Frobimarko.git ar7: clocks setup (prerequisite for dsl/usb) and misc cleanups. SVN-Revision: 6693 --- diff --git a/target/linux/ar7-2.6/config/default b/target/linux/ar7-2.6/config/default index 888a446ee0..1cef125cac 100644 --- a/target/linux/ar7-2.6/config/default +++ b/target/linux/ar7-2.6/config/default @@ -9,7 +9,7 @@ CONFIG_BASE_SMALL=0 # CONFIG_BCM43XX is not set # CONFIG_BLK_DEV_INITRD is not set CONFIG_BOOT_ELF32=y -CONFIG_CMDLINE="console=ttyS0,38400n8r root=/dev/mtdblock3 init=/etc/preinit" +CONFIG_CMDLINE="console=ttyS0,38400n8r init=/etc/preinit" CONFIG_CPMAC=y # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_HAS_LLSC=y diff --git a/target/linux/ar7-2.6/files/arch/mips/ar7/Makefile b/target/linux/ar7-2.6/files/arch/mips/ar7/Makefile index 0771cfcf26..3ec49ee0d4 100644 --- a/target/linux/ar7-2.6/files/arch/mips/ar7/Makefile +++ b/target/linux/ar7-2.6/files/arch/mips/ar7/Makefile @@ -7,6 +7,7 @@ obj-y := \ time.o \ platform.o \ gpio.o \ + clock.o \ vlynq.o obj-$(CONFIG_PCI) += \ diff --git a/target/linux/ar7-2.6/files/arch/mips/ar7/clock.c b/target/linux/ar7-2.6/files/arch/mips/ar7/clock.c new file mode 100644 index 0000000000..6da0c20aa9 --- /dev/null +++ b/target/linux/ar7-2.6/files/arch/mips/ar7/clock.c @@ -0,0 +1,362 @@ +/* + * $Id$ + * + * Copyright (C) 2007 OpenWrt.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BOOT_PLL_SOURCE_MASK 0x3 +#define CPU_PLL_SOURCE_SHIFT 16 +#define BUS_PLL_SOURCE_SHIFT 14 +#define USB_PLL_SOURCE_SHIFT 18 +#define DSP_PLL_SOURCE_SHIFT 22 +#define BOOT_PLL_SOURCE_AFE 0 +#define BOOT_PLL_SOURCE_BUS 0 +#define BOOT_PLL_SOURCE_REF 1 +#define BOOT_PLL_SOURCE_XTAL 2 +#define BOOT_PLL_SOURCE_CPU 3 +#define BOOT_PLL_BYPASS 0x00000020 +#define BOOT_PLL_ASYNC_MODE 0x02000000 +#define BOOT_PLL_2TO1_MODE 0x00008000 + +struct tnetd7300_clock { + u32 ctrl; +#define PREDIV_MASK 0x001f0000 +#define PREDIV_SHIFT 16 +#define POSTDIV_MASK 0x0000001f + u32 unused1[3]; + u32 pll; +#define MUL_MASK 0x0000f000 +#define MUL_SHIFT 12 +#define PLL_MODE_MASK 0x00000001 +#define PLL_NDIV 0x00000800 +#define PLL_DIV 0x00000002 +#define PLL_STATUS 0x00000001 + u32 unused2[3]; +} __attribute__ ((packed)); + +struct tnetd7300_clocks { + struct tnetd7300_clock bus; + struct tnetd7300_clock cpu; + struct tnetd7300_clock usb; + struct tnetd7300_clock dsp; +} __attribute__ ((packed)); + +struct tnetd7200_clock { + u32 ctrl; + u32 unused1[3]; +#define DIVISOR_ENABLE_MASK 0x00008000 + u32 mul; + u32 prediv; + u32 postdiv; + u32 unused2[7]; + u32 cmd; + u32 status; + u32 cmden; + u32 padding[15]; +}; + +struct tnetd7200_clocks { + struct tnetd7200_clock cpu; + struct tnetd7200_clock dsp; + struct tnetd7200_clock usb; +}; + +int ar7_afe_clock = 35328000; +int ar7_ref_clock = 25000000; +int ar7_xtal_clock = 24000000; + +int ar7_cpu_clock = 150000000; +EXPORT_SYMBOL(ar7_cpu_clock); +int ar7_bus_clock = 125000000; +EXPORT_SYMBOL(ar7_bus_clock); +int ar7_dsp_clock = 0; +EXPORT_SYMBOL(ar7_dsp_clock); + +static int gcd(int x, int y) +{ + if (x > y) + return (x % y) ? gcd(y, x % y) : y; + return (y % x) ? gcd(x, y % x) : x; +} + +static inline int ABS(int x) +{ + return (x >= 0) ? x : -x; +} + +static void approximate(int base, int target, int *prediv, + int *postdiv, int *mul) +{ + int i, j, k, freq, res = target; + for (i = 1; i <= 16; i++) { + for (j = 1; j <= 32; j++) { + for (k = 1; k <= 32; k++) { + freq = ABS(base / j * i / k - target); + if (freq < res) { + res = freq; + *mul = i; + *prediv = j; + *postdiv = k; + } + } + } + } +} + +static void calculate(int base, int target, int *prediv, int *postdiv, + int *mul) +{ + int tmp_gcd, tmp_base, tmp_freq; + + for (*prediv = 1; *prediv <= 32; (*prediv)++) { + tmp_base = base / *prediv; + tmp_gcd = gcd(target, tmp_base); + *mul = target / tmp_gcd; + *postdiv = tmp_base / tmp_gcd; + if ((*mul < 1) || (*mul >= 16)) + continue; + if ((*postdiv > 0) & (*postdiv <= 32)) + break; + } + + if (base / (*prediv) * (*mul) / (*postdiv) != target) { + approximate(base, target, prediv, postdiv, mul); + tmp_freq = base / (*prediv) * (*mul) / (*postdiv); + printk(KERN_WARNING + "Adjusted requested frequency %d to %d\n", + target, tmp_freq); + } + + printk(KERN_DEBUG "Clocks: prediv: %d, postdiv: %d, mul: %d\n", + *prediv, *postdiv, *mul); +} + +static int tnetd7300_dsp_clock(void) +{ + u32 didr1, didr2; + u8 rev = ar7_chip_rev(); + didr1 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x18)); + didr2 = readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x1c)); + if (didr2 & (1 << 23)) + return 0; + if ((rev >= 0x23) && (rev != 0x57)) + return 250000000; + if ((((didr2 & 0x1fff) << 10) | ((didr1 & 0xffc00000) >> 22)) + > 4208000) + return 250000000; + return 0; +} + +static int tnetd7300_get_clock(u32 shift, struct tnetd7300_clock *clock, + u32 *bootcr, u32 bus_clock) +{ + int product; + int base_clock = ar7_ref_clock; + int prediv = ((clock->ctrl & PREDIV_MASK) >> PREDIV_SHIFT) + 1; + int postdiv = (clock->ctrl & POSTDIV_MASK) + 1; + int divisor = prediv * postdiv; + int mul = ((clock->pll & MUL_MASK) >> MUL_SHIFT) + 1; + + switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) { + case BOOT_PLL_SOURCE_BUS: + base_clock = bus_clock; + break; + case BOOT_PLL_SOURCE_REF: + base_clock = ar7_ref_clock; + break; + case BOOT_PLL_SOURCE_XTAL: + base_clock = ar7_xtal_clock; + break; + case BOOT_PLL_SOURCE_CPU: + base_clock = ar7_cpu_clock; + break; + } + + if (*bootcr & BOOT_PLL_BYPASS) + return base_clock / divisor; + + if ((clock->pll & PLL_MODE_MASK) == 0) + return (base_clock >> (mul / 16 + 1)) / divisor; + + if ((clock->pll & (PLL_NDIV | PLL_DIV)) == (PLL_NDIV | PLL_DIV)) { + product = (mul & 1) ? + (base_clock * mul) >> 1 : + (base_clock * (mul - 1)) >> 2; + return product / divisor; + } + + if (mul == 16) + return base_clock / divisor; + + return base_clock * mul / divisor; +} + +static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock, + u32 *bootcr, u32 frequency) +{ + volatile u32 status; + int prediv, postdiv, mul; + int base_clock = ar7_bus_clock; + + switch ((*bootcr & (BOOT_PLL_SOURCE_MASK << shift)) >> shift) { + case BOOT_PLL_SOURCE_BUS: + base_clock = ar7_bus_clock; + break; + case BOOT_PLL_SOURCE_REF: + base_clock = ar7_ref_clock; + break; + case BOOT_PLL_SOURCE_XTAL: + base_clock = ar7_xtal_clock; + break; + case BOOT_PLL_SOURCE_CPU: + base_clock = ar7_cpu_clock; + break; + } + + calculate(base_clock, frequency, &prediv, &postdiv, &mul); + + clock->ctrl = ((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1); + mdelay(1); + clock->pll = 4; + do { + status = clock->pll; + } while (status & PLL_STATUS); + clock->pll = ((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e; + mdelay(75); +} + +static void __init tnetd7300_init_clocks(void) +{ + u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); + struct tnetd7300_clocks *clocks = (struct tnetd7300_clocks *)ioremap_nocache(AR7_REGS_POWER + 0x20, sizeof(struct tnetd7300_clocks)); + + ar7_bus_clock = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT, + &clocks->bus, bootcr, + ar7_afe_clock); + + if (*bootcr & BOOT_PLL_ASYNC_MODE) { + ar7_cpu_clock = tnetd7300_get_clock(CPU_PLL_SOURCE_SHIFT, + &clocks->cpu, + bootcr, ar7_afe_clock); + } else { + ar7_cpu_clock = ar7_bus_clock; + } + + tnetd7300_set_clock(USB_PLL_SOURCE_SHIFT, &clocks->usb, + bootcr, 48000000); + + if (ar7_dsp_clock == 250000000) + tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp, + bootcr, ar7_dsp_clock); + + iounmap(clocks); + iounmap(bootcr); +} + +static int tnetd7200_get_clock(int base, struct tnetd7200_clock *clock, + u32 *bootcr, u32 bus_clock) +{ + int divisor = ((clock->prediv & 0x1f) + 1) * + ((clock->postdiv & 0x1f) + 1); + + if (*bootcr & BOOT_PLL_BYPASS) + return base / divisor; + + return base * ((clock->mul & 0xf) + 1) / divisor; +} + +static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock, + u32 *bootcr, u32 frequency) +{ + volatile u32 status; + int prediv, postdiv, mul; + + calculate(base, frequency, &prediv, &postdiv, &mul); + + clock->ctrl = 0; + clock->prediv = DIVISOR_ENABLE_MASK | prediv; + clock->mul = mul; + mdelay(1); + do { + status = clock->status; + } while (status & PLL_STATUS); + clock->postdiv = DIVISOR_ENABLE_MASK | postdiv; + clock->cmden = 1; + clock->cmd = 1; + do { + status = clock->status; + } while (status & PLL_STATUS); + clock->ctrl = 1; +} + +static void __init tnetd7200_init_clocks(void) +{ + u32 *bootcr = (u32 *)ioremap_nocache(AR7_REGS_DCL, 4); + struct tnetd7200_clocks *clocks = (struct tnetd7200_clocks *)ioremap_nocache(AR7_REGS_POWER + 0x80, sizeof(struct tnetd7200_clocks)); + + ar7_cpu_clock = tnetd7200_get_clock(ar7_afe_clock, + &clocks->cpu, + bootcr, ar7_afe_clock); + + if (*bootcr & BOOT_PLL_ASYNC_MODE) { + ar7_bus_clock = 125000000; + } else { + if (*bootcr & BOOT_PLL_2TO1_MODE) { + ar7_bus_clock = ar7_cpu_clock / 2; + } else { + ar7_bus_clock = ar7_cpu_clock; + } + } + + tnetd7200_set_clock(ar7_ref_clock * 5, &clocks->usb, + bootcr, 48000000); + + if (ar7_dsp_clock == 250000000) + tnetd7200_set_clock(ar7_ref_clock, &clocks->dsp, + bootcr, ar7_dsp_clock); + + iounmap(clocks); + iounmap(bootcr); +} + +void __init ar7_init_clocks(void) +{ + switch (ar7_chip_id()) { + case AR7_CHIP_7100: + tnetd7200_init_clocks(); + break; + case AR7_CHIP_7200: +#warning FIXME: check revision + ar7_dsp_clock = 250000000; + tnetd7200_init_clocks(); + break; + case AR7_CHIP_7300: + ar7_dsp_clock = tnetd7300_dsp_clock(); + tnetd7300_init_clocks(); + break; + default: + break; + } +} diff --git a/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c b/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c index 7176be3022..e613164f06 100644 --- a/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c +++ b/target/linux/ar7-2.6/files/arch/mips/ar7/prom.c @@ -47,7 +47,7 @@ struct psp_chip_map { /* I hate this. No. *I* *HATE* *THIS* */ static __initdata struct psp_chip_map psp_chip_map[] = { { - .chip = 0x5, + .chip = AR7_CHIP_7100, .names = { "dummy", "cpufrequency", "memsize", "flashsize", "modetty0", "modetty1", "prompt", @@ -65,7 +65,7 @@ static __initdata struct psp_chip_map psp_chip_map[] = { }, }, { - .chip = 0x18, + .chip = AR7_CHIP_7200, .names = { "dummy", "cpufrequency", "memsize", "flashsize", "modetty0", "modetty1", "prompt", @@ -83,7 +83,7 @@ static __initdata struct psp_chip_map psp_chip_map[] = { }, }, { - .chip = 0x2b, + .chip = AR7_CHIP_7300, .names = { "dummy", "cpufrequency", "memsize", "flashsize", "modetty0", "modetty1", "prompt", @@ -186,7 +186,7 @@ static int __init parse_psp_env(void *start) char *src, *dest, *name, *value; struct psp_env_var *vars = start; - chip = get_chip_id(); + chip = ar7_chip_id(); for (map = psp_chip_map; map->chip; map++) if (map->chip == chip) break; diff --git a/target/linux/ar7-2.6/files/arch/mips/ar7/setup.c b/target/linux/ar7-2.6/files/arch/mips/ar7/setup.c index 301abe0689..fb3d20c183 100644 --- a/target/linux/ar7-2.6/files/arch/mips/ar7/setup.c +++ b/target/linux/ar7-2.6/files/arch/mips/ar7/setup.c @@ -72,13 +72,13 @@ static void ar7_machine_power_off(void) const char *get_system_type(void) { - u16 chip_id = get_chip_id(); + u16 chip_id = ar7_chip_id(); switch (chip_id) { - case 0x5: + case AR7_CHIP_7300: return "TI AR7 (TNETD7300)"; - case 0x18: + case AR7_CHIP_7100: return "TI AR7 (TNETD7100)"; - case 0x2b: + case AR7_CHIP_7200: return "TI AR7 (TNETD7200)"; default: return "TI AR7 (Unknown)"; @@ -95,6 +95,8 @@ static int __init ar7_init_console(void) * given by the bios and saves the command line. */ +extern void ar7_init_clocks(void); + void __init plat_mem_setup(void) { unsigned long io_base; @@ -110,6 +112,7 @@ void __init plat_mem_setup(void) set_io_port_base(io_base); prom_meminit(); + ar7_init_clocks(); ioport_resource.start = 0; ioport_resource.end = ~0; diff --git a/target/linux/ar7-2.6/files/drivers/char/watchdog/ar7_wdt.c b/target/linux/ar7-2.6/files/drivers/char/watchdog/ar7_wdt.c index 00919e76e7..59ac693d43 100644 --- a/target/linux/ar7-2.6/files/drivers/char/watchdog/ar7_wdt.c +++ b/target/linux/ar7-2.6/files/drivers/char/watchdog/ar7_wdt.c @@ -70,9 +70,6 @@ typedef struct { static struct semaphore open_semaphore; static unsigned expect_close; -/* XXX correct? assumed to be sysfreq/2. get this dynamically ... */ -#define vbus_freq (ar7_bus_freq() / 2) - /* XXX currently fixed, allows max margin ~68.72 secs */ #define prescale_value 0xFFFF @@ -143,14 +140,14 @@ static void ar7_wdt_update_margin(int new_margin) { u32 change; - change = new_margin * (vbus_freq / prescale_value); + change = new_margin * (ar7_vbus_freq() / prescale_value); if (change < 1) change = 1; if (change > 0xFFFF) change = 0xFFFF; ar7_wdt_change(change); - margin = change * prescale_value / vbus_freq; + margin = change * prescale_value / ar7_vbus_freq(); printk(KERN_INFO DRVNAME ": timer margin %d seconds (prescale %d, change %d, freq %d)\n", - margin, prescale_value, change, vbus_freq); + margin, prescale_value, change, ar7_vbus_freq()); } static void ar7_wdt_enable_wdt(void) diff --git a/target/linux/ar7-2.6/files/drivers/mtd/ar7part.c b/target/linux/ar7-2.6/files/drivers/mtd/ar7part.c index 2b3edf67b7..0ae96a305f 100644 --- a/target/linux/ar7-2.6/files/drivers/mtd/ar7part.c +++ b/target/linux/ar7-2.6/files/drivers/mtd/ar7part.c @@ -29,6 +29,7 @@ #include #include #include +#include struct ar7_bin_rec { unsigned int checksum; @@ -108,6 +109,7 @@ static int create_mtd_partitions(struct mtd_info *master, ar7_parts[p - 1].size -= ar7_parts[p].size; ar7_parts[p - 1].mask_flags |= MTD_WRITEABLE; ar7_parts[p++].mask_flags = 0; + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, p - 1); } else { printk("Squashfs not found. Moving rootfs partition to next erase block\n"); if ((root_offset % master->erasesize) > 0) @@ -116,6 +118,7 @@ static int create_mtd_partitions(struct mtd_info *master, ar7_parts[p].offset = root_offset; ar7_parts[p].size = master->size - root_offset - post_size; + ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, p); } *pparts = ar7_parts; return p; diff --git a/target/linux/ar7-2.6/files/include/asm-mips/ar7/ar7.h b/target/linux/ar7-2.6/files/include/asm-mips/ar7/ar7.h index fe51a8d67b..a5fa474aff 100644 --- a/target/linux/ar7-2.6/files/include/asm-mips/ar7/ar7.h +++ b/target/linux/ar7-2.6/files/include/asm-mips/ar7/ar7.h @@ -31,12 +31,20 @@ #define AR7_REGS_GPIO (AR7_REGS_BASE + 0x0900) #define AR7_REGS_POWER (AR7_REGS_BASE + 0x0a00) #define AR7_REGS_WDT (AR7_REGS_BASE + 0x0b00) +#define AR7_REGS_TIMER0 (AR7_REGS_BASE + 0x0c00) +#define AR7_REGS_TIMER1 (AR7_REGS_BASE + 0x0d00) #define AR7_REGS_UART0 (AR7_REGS_BASE + 0x0e00) #define AR7_REGS_UART1 (AR7_REGS_BASE + 0x0f00) +#define AR7_REGS_I2C (AR7_REGS_BASE + 0x1000) +#define AR7_REGS_USB (AR7_REGS_BASE + 0x1200) +#define AR7_REGS_DMA (AR7_REGS_BASE + 0x1400) #define AR7_REGS_RESET (AR7_REGS_BASE + 0x1600) +#define AR7_REGS_BIST (AR7_REGS_BASE + 0x1700) #define AR7_REGS_VLYNQ0 (AR7_REGS_BASE + 0x1800) +#define AR7_REGS_DCL (AR7_REGS_BASE + 0x1A00) #define AR7_REGS_VLYNQ1 (AR7_REGS_BASE + 0x1C00) #define AR7_REGS_MDIO (AR7_REGS_BASE + 0x1E00) +#define AR7_REGS_FSER (AR7_REGS_BASE + 0x2000) #define AR7_REGS_IRQ (AR7_REGS_BASE + 0x2400) #define AR7_REGS_MAC1 (AR7_REGS_BASE + 0x2800) @@ -54,6 +62,9 @@ #define AR7_GPIO_BIT_STATUS_LED 8 +#define AR7_CHIP_7100 0x18 +#define AR7_CHIP_7200 0x2b +#define AR7_CHIP_7300 0x05 /* Interrupts */ #define AR7_IRQ_UART0 15 @@ -66,49 +77,52 @@ struct plat_cpmac_data { char dev_addr[6]; }; +struct plat_dsl_data { + int reset_bit_dsl; + int reset_bit_sar; +}; + extern char *prom_getenv(char *envname); -/* A bunch of small bit-toggling functions */ -static inline u32 get_chip_id(void) +extern int ar7_cpu_clock, ar7_bus_clock, ar7_dsp_clock; + +static inline u16 ar7_chip_id(void) { - return *((u16 *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)); + return readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) & 0xffff; +} + +static inline u8 ar7_chip_rev(void) +{ + return (readl((void *)KSEG1ADDR(AR7_REGS_GPIO + 0x14)) >> 16) & 0xff; } static inline int ar7_cpu_freq(void) { - u16 chip_id = get_chip_id(); - switch (chip_id) { - case 0x5: - return 150000000; - case 0x18: - case 0x2b: - return 211968000; - default: - return 150000000; - } + return ar7_cpu_clock; } static inline int ar7_bus_freq(void) { - u16 chip_id = get_chip_id(); - switch (chip_id) { - case 0x5: - return 125000000; - case 0x18: - case 0x2b: - return 105984000; - default: - return 125000000; - } + return ar7_bus_clock; +} + +static inline int ar7_vbus_freq(void) +{ + return ar7_bus_clock / 2; +} +#define ar7_cpmac_freq ar7_vbus_freq + +static inline int ar7_dsp_freq(void) +{ + return ar7_dsp_clock; } -#define ar7_cpmac_freq ar7_bus_freq static inline int ar7_has_high_cpmac(void) { - u16 chip_id = get_chip_id(); + u16 chip_id = ar7_chip_id(); switch (chip_id) { - case 0x18: - case 0x2b: + case AR7_CHIP_7100: + case AR7_CHIP_7200: return 0; default: return 1; @@ -118,15 +132,15 @@ static inline int ar7_has_high_cpmac(void) static inline void ar7_device_enable(u32 bit) { - volatile u32 *reset_reg = (u32 *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); - *reset_reg |= (1 << bit); + void *reset_reg = (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); + writel(readl(reset_reg) | (1 << bit), reset_reg); mdelay(20); } static inline void ar7_device_disable(u32 bit) { - volatile u32 *reset_reg = (u32 *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); - *reset_reg &= ~(1 << bit); + void *reset_reg = (void *)KSEG1ADDR(AR7_REGS_RESET + AR7_RESET_PEREPHERIAL); + writel(readl(reset_reg) & ~(1 << bit), reset_reg); mdelay(20); } @@ -138,15 +152,15 @@ static inline void ar7_device_reset(u32 bit) static inline void ar7_device_on(u32 bit) { - volatile u32 *power_reg = (u32 *)KSEG1ADDR(AR7_REGS_POWER); - *power_reg |= (1 << bit); + void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER); + writel(readl(power_reg) | (1 << bit), power_reg); mdelay(20); } static inline void ar7_device_off(u32 bit) { - volatile u32 *power_reg = (u32 *)KSEG1ADDR(AR7_REGS_POWER); - *power_reg &= ~(1 << bit); + void *power_reg = (void *)KSEG1ADDR(AR7_REGS_POWER); + writel(readl(power_reg) & ~(1 << bit), power_reg); mdelay(20); } diff --git a/target/linux/ar7-2.6/files/include/asm-mips/ar7/gpio.h b/target/linux/ar7-2.6/files/include/asm-mips/ar7/gpio.h index 73673feff6..97638077fd 100644 --- a/target/linux/ar7-2.6/files/include/asm-mips/ar7/gpio.h +++ b/target/linux/ar7-2.6/files/include/asm-mips/ar7/gpio.h @@ -35,7 +35,7 @@ static inline int gpio_direction_input(unsigned gpio) if (gpio >= AR7_GPIO_MAX) return -EINVAL; - __raw_writel(__raw_readl(gpio_dir) | (1 << gpio), gpio_dir); + writel(readl(gpio_dir) | (1 << gpio), gpio_dir); return 0; } @@ -47,7 +47,7 @@ static inline int gpio_direction_output(unsigned gpio) if (gpio >= AR7_GPIO_MAX) return -EINVAL; - __raw_writel(__raw_readl(gpio_dir) & ~(1 << gpio), gpio_dir); + writel(readl(gpio_dir) & ~(1 << gpio), gpio_dir); return 0; } @@ -59,7 +59,7 @@ static inline int gpio_get_value(unsigned gpio) if (gpio >= AR7_GPIO_MAX) return -EINVAL; - return ((__raw_readl(gpio_in) & (1 << gpio)) != 0); + return ((readl(gpio_in) & (1 << gpio)) != 0); } static inline void gpio_set_value(unsigned gpio, int value) @@ -70,10 +70,10 @@ static inline void gpio_set_value(unsigned gpio, int value) if (gpio >= AR7_GPIO_MAX) return; - tmp = __raw_readl(gpio_out) & ~(1 << gpio); + tmp = readl(gpio_out) & ~(1 << gpio); if (value) tmp |= 1 << gpio; - __raw_writel(tmp, gpio_out); + writel(tmp, gpio_out); } static inline int gpio_to_irq(unsigned gpio) @@ -94,7 +94,7 @@ static inline int ar7_gpio_enable(unsigned gpio) if (gpio >= AR7_GPIO_MAX) return -EINVAL; - __raw_writel(__raw_readl(gpio_en) | (1 << gpio), gpio_en); + writel(readl(gpio_en) | (1 << gpio), gpio_en); return 0; } @@ -106,7 +106,7 @@ static inline int ar7_gpio_disable(unsigned gpio) if (gpio >= AR7_GPIO_MAX) return -EINVAL; - __raw_writel(__raw_readl(gpio_en) & ~(1 << gpio), gpio_en); + writel(readl(gpio_en) & ~(1 << gpio), gpio_en); return 0; }