From: Linus Torvalds Date: Mon, 19 Feb 2007 21:18:39 +0000 (-0800) Subject: Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=59b8175c771040afcd4ad67022b0cc80c216b866;p=openwrt%2Fstaging%2Fblogic.git Merge branch 'for-linus' of /home/rmk/linux-2.6-arm * 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (117 commits) [ARM] 4058/2: iop32x: set ->broken_parity_status on n2100 onboard r8169 ports [ARM] 4140/1: AACI stability add ac97 timeout and retries [ARM] 4139/1: AACI record support [ARM] 4138/1: AACI: multiple channel support for IRQ handling [ARM] 4211/1: Provide a defconfig for ns9xxx [ARM] 4210/1: base for new machine type "NetSilicon NS9360" [ARM] 4222/1: S3C2443: Remove reference to missing S3C2443_PM [ARM] 4221/1: S3C2443: DMA support [ARM] 4220/1: S3C24XX: DMA system initialised from sysdev [ARM] 4219/1: S3C2443: DMA source definitions [ARM] 4218/1: S3C2412: fix CONFIG_CPU_S3C2412_ONLY wrt to S3C2443 [ARM] 4217/1: S3C24XX: remove the dma channel show at startup [ARM] 4090/2: avoid clash between PXA and SA1111 defines [ARM] 4216/1: add .gitignore entries for ARM specific files [ARM] 4214/2: S3C2410: Add Armzone QT2410 [ARM] 4215/1: s3c2410 usb device: per-platform vbus_draw [ARM] 4213/1: S3C2410 - Update definition of ADCTSC_XY_PST [ARM] 4098/1: ARM: rtc_lock only used with rtc_cmos [ARM] 4137/1: Add kexec support [ARM] 4201/1: SMP barriers pair needed for the secondary boot process ... Fix up conflict due to typedef removal in sound/arm/aaci.h --- 59b8175c771040afcd4ad67022b0cc80c216b866 diff --cc arch/arm/mach-at91/clock.c index 000000000000,f6cb74806043..06c9a0507d0d mode 000000,100644..100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@@ -1,0 -1,640 +1,640 @@@ + /* + * linux/arch/arm/mach-at91/clock.c + * + * Copyright (C) 2005 David Brownell + * Copyright (C) 2005 Ivan Kokshaysky + * + * 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. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + + #include + #include + #include + + #include "clock.h" + + + /* + * There's a lot more which can be done with clocks, including cpufreq + * integration, slow clock mode support (for system suspend), letting + * PLLB be used at other rates (on boards that don't need USB), etc. + */ + + #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) + #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) + #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) + #define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) + + + static LIST_HEAD(clocks); + static DEFINE_SPINLOCK(clk_lock); + + static u32 at91_pllb_usb_init; + + /* + * Four primary clock sources: two crystal oscillators (32K, main), and + * two PLLs. PLLA usually runs the master clock; and PLLB must run at + * 48 MHz (unless no USB function clocks are needed). The main clock and + * both PLLs are turned off to run in "slow clock mode" (system suspend). + */ + static struct clk clk32k = { + .name = "clk32k", + .rate_hz = AT91_SLOW_CLOCK, + .users = 1, /* always on */ + .id = 0, + .type = CLK_TYPE_PRIMARY, + }; + static struct clk main_clk = { + .name = "main", + .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ + .id = 1, + .type = CLK_TYPE_PRIMARY, + }; + static struct clk plla = { + .name = "plla", + .parent = &main_clk, + .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ + .id = 2, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, + }; + + static void pllb_mode(struct clk *clk, int is_on) + { + u32 value; + + if (is_on) { + is_on = AT91_PMC_LOCKB; + value = at91_pllb_usb_init; + } else + value = 0; + + // REVISIT: Add work-around for AT91RM9200 Errata #26 ? + at91_sys_write(AT91_CKGR_PLLBR, value); + + do { + cpu_relax(); + } while ((at91_sys_read(AT91_PMC_SR) & AT91_PMC_LOCKB) != is_on); + } + + static struct clk pllb = { + .name = "pllb", + .parent = &main_clk, + .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ + .mode = pllb_mode, + .id = 3, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, + }; + + static void pmc_sys_mode(struct clk *clk, int is_on) + { + if (is_on) + at91_sys_write(AT91_PMC_SCER, clk->pmc_mask); + else + at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); + } + + /* USB function clocks (PLLB must be 48 MHz) */ + static struct clk udpck = { + .name = "udpck", + .parent = &pllb, + .mode = pmc_sys_mode, + }; + static struct clk uhpck = { + .name = "uhpck", + .parent = &pllb, + .mode = pmc_sys_mode, + }; + + + /* + * The master clock is divided from the CPU clock (by 1-4). It's used for + * memory, interfaces to on-chip peripherals, the AIC, and sometimes more + * (e.g baud rate generation). It's sourced from one of the primary clocks. + */ + static struct clk mck = { + .name = "mck", + .pmc_mask = AT91_PMC_MCKRDY, /* in PMC_SR */ + }; + + static void pmc_periph_mode(struct clk *clk, int is_on) + { + if (is_on) + at91_sys_write(AT91_PMC_PCER, clk->pmc_mask); + else + at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); + } + + static struct clk __init *at91_css_to_clk(unsigned long css) + { + switch (css) { + case AT91_PMC_CSS_SLOW: + return &clk32k; + case AT91_PMC_CSS_MAIN: + return &main_clk; + case AT91_PMC_CSS_PLLA: + return &plla; + case AT91_PMC_CSS_PLLB: + return &pllb; + } + + return NULL; + } + + /* + * Associate a particular clock with a function (eg, "uart") and device. + * The drivers can then request the same 'function' with several different + * devices and not care about which clock name to use. + */ + void __init at91_clock_associate(const char *id, struct device *dev, const char *func) + { + struct clk *clk = clk_get(NULL, id); + + if (!dev || !clk || !IS_ERR(clk_get(dev, func))) + return; + + clk->function = func; + clk->dev = dev; + } + + /* clocks cannot be de-registered no refcounting necessary */ + struct clk *clk_get(struct device *dev, const char *id) + { + struct clk *clk; + + list_for_each_entry(clk, &clocks, node) { + if (strcmp(id, clk->name) == 0) + return clk; + if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) + return clk; + } + + return ERR_PTR(-ENOENT); + } + EXPORT_SYMBOL(clk_get); + + void clk_put(struct clk *clk) + { + } + EXPORT_SYMBOL(clk_put); + + static void __clk_enable(struct clk *clk) + { + if (clk->parent) + __clk_enable(clk->parent); + if (clk->users++ == 0 && clk->mode) + clk->mode(clk, 1); + } + + int clk_enable(struct clk *clk) + { + unsigned long flags; + + spin_lock_irqsave(&clk_lock, flags); + __clk_enable(clk); + spin_unlock_irqrestore(&clk_lock, flags); + return 0; + } + EXPORT_SYMBOL(clk_enable); + + static void __clk_disable(struct clk *clk) + { + BUG_ON(clk->users == 0); + if (--clk->users == 0 && clk->mode) + clk->mode(clk, 0); + if (clk->parent) + __clk_disable(clk->parent); + } + + void clk_disable(struct clk *clk) + { + unsigned long flags; + + spin_lock_irqsave(&clk_lock, flags); + __clk_disable(clk); + spin_unlock_irqrestore(&clk_lock, flags); + } + EXPORT_SYMBOL(clk_disable); + + unsigned long clk_get_rate(struct clk *clk) + { + unsigned long flags; + unsigned long rate; + + spin_lock_irqsave(&clk_lock, flags); + for (;;) { + rate = clk->rate_hz; + if (rate || !clk->parent) + break; + clk = clk->parent; + } + spin_unlock_irqrestore(&clk_lock, flags); + return rate; + } + EXPORT_SYMBOL(clk_get_rate); + + /*------------------------------------------------------------------------*/ + + #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + + /* + * For now, only the programmable clocks support reparenting (MCK could + * do this too, with care) or rate changing (the PLLs could do this too, + * ditto MCK but that's more for cpufreq). Drivers may reparent to get + * a better rate match; we don't. + */ + + long clk_round_rate(struct clk *clk, unsigned long rate) + { + unsigned long flags; + unsigned prescale; + unsigned long actual; + + if (!clk_is_programmable(clk)) + return -EINVAL; + spin_lock_irqsave(&clk_lock, flags); + + actual = clk->parent->rate_hz; + for (prescale = 0; prescale < 7; prescale++) { + if (actual && actual <= rate) + break; + actual >>= 1; + } + + spin_unlock_irqrestore(&clk_lock, flags); + return (prescale < 7) ? actual : -ENOENT; + } + EXPORT_SYMBOL(clk_round_rate); + + int clk_set_rate(struct clk *clk, unsigned long rate) + { + unsigned long flags; + unsigned prescale; + unsigned long actual; + + if (!clk_is_programmable(clk)) + return -EINVAL; + if (clk->users) + return -EBUSY; + spin_lock_irqsave(&clk_lock, flags); + + actual = clk->parent->rate_hz; + for (prescale = 0; prescale < 7; prescale++) { + if (actual && actual <= rate) { + u32 pckr; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + pckr &= AT91_PMC_CSS_PLLB; /* clock selection */ + pckr |= prescale << 2; + at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); + clk->rate_hz = actual; + break; + } + actual >>= 1; + } + + spin_unlock_irqrestore(&clk_lock, flags); + return (prescale < 7) ? actual : -ENOENT; + } + EXPORT_SYMBOL(clk_set_rate); + + struct clk *clk_get_parent(struct clk *clk) + { + return clk->parent; + } + EXPORT_SYMBOL(clk_get_parent); + + int clk_set_parent(struct clk *clk, struct clk *parent) + { + unsigned long flags; + + if (clk->users) + return -EBUSY; + if (!clk_is_primary(parent) || !clk_is_programmable(clk)) + return -EINVAL; + spin_lock_irqsave(&clk_lock, flags); + + clk->rate_hz = parent->rate_hz; + clk->parent = parent; + at91_sys_write(AT91_PMC_PCKR(clk->id), parent->id); + + spin_unlock_irqrestore(&clk_lock, flags); + return 0; + } + EXPORT_SYMBOL(clk_set_parent); + + /* establish PCK0..PCK3 parentage and rate */ + static void init_programmable_clock(struct clk *clk) + { + struct clk *parent; + u32 pckr; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + parent = at91_css_to_clk(pckr & AT91_PMC_CSS); + clk->parent = parent; + clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); + } + + #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ + + /*------------------------------------------------------------------------*/ + + #ifdef CONFIG_DEBUG_FS + + static int at91_clk_show(struct seq_file *s, void *unused) + { + u32 scsr, pcsr, sr; + struct clk *clk; + unsigned i; + + seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); + seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); + + seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); + seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); + seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); + seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); + + seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); + for (i = 0; i < 4; i++) + seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i))); + seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); + + seq_printf(s, "\n"); + + list_for_each_entry(clk, &clocks, node) { + char *state; + + if (clk->mode == pmc_sys_mode) + state = (scsr & clk->pmc_mask) ? "on" : "off"; + else if (clk->mode == pmc_periph_mode) + state = (pcsr & clk->pmc_mask) ? "on" : "off"; + else if (clk->pmc_mask) + state = (sr & clk->pmc_mask) ? "on" : "off"; + else if (clk == &clk32k || clk == &main_clk) + state = "on"; + else + state = ""; + + seq_printf(s, "%-10s users=%2d %-3s %9ld Hz %s\n", + clk->name, clk->users, state, clk_get_rate(clk), + clk->parent ? clk->parent->name : ""); + } + return 0; + } + + static int at91_clk_open(struct inode *inode, struct file *file) + { + return single_open(file, at91_clk_show, NULL); + } + -static struct file_operations at91_clk_operations = { ++static const struct file_operations at91_clk_operations = { + .open = at91_clk_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + }; + + static int __init at91_clk_debugfs_init(void) + { + /* /sys/kernel/debug/at91_clk */ + (void) debugfs_create_file("at91_clk", S_IFREG | S_IRUGO, NULL, NULL, &at91_clk_operations); + + return 0; + } + postcore_initcall(at91_clk_debugfs_init); + + #endif + + /*------------------------------------------------------------------------*/ + + /* Register a new clock */ + int __init clk_register(struct clk *clk) + { + if (clk_is_peripheral(clk)) { + clk->parent = &mck; + clk->mode = pmc_periph_mode; + list_add_tail(&clk->node, &clocks); + } + else if (clk_is_sys(clk)) { + clk->parent = &mck; + clk->mode = pmc_sys_mode; + + list_add_tail(&clk->node, &clocks); + } + #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + else if (clk_is_programmable(clk)) { + clk->mode = pmc_sys_mode; + init_programmable_clock(clk); + list_add_tail(&clk->node, &clocks); + } + #endif + + return 0; + } + + + /*------------------------------------------------------------------------*/ + + static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) + { + unsigned mul, div; + + div = reg & 0xff; + mul = (reg >> 16) & 0x7ff; + if (div && mul) { + freq /= div; + freq *= mul + 1; + } else + freq = 0; + + return freq; + } + + static u32 __init at91_usb_rate(struct clk *pll, u32 freq, u32 reg) + { + if (pll == &pllb && (reg & AT91_PMC_USB96M)) + return freq / 2; + else + return freq; + } + + static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) + { + unsigned i, div = 0, mul = 0, diff = 1 << 30; + unsigned ret = (out_freq > 155000000) ? 0xbe00 : 0x3e00; + + /* PLL output max 240 MHz (or 180 MHz per errata) */ + if (out_freq > 240000000) + goto fail; + + for (i = 1; i < 256; i++) { + int diff1; + unsigned input, mul1; + + /* + * PLL input between 1MHz and 32MHz per spec, but lower + * frequences seem necessary in some cases so allow 100K. + */ + input = main_freq / i; + if (input < 100000) + continue; + if (input > 32000000) + continue; + + mul1 = out_freq / input; + if (mul1 > 2048) + continue; + if (mul1 < 2) + goto fail; + + diff1 = out_freq - input * mul1; + if (diff1 < 0) + diff1 = -diff1; + if (diff > diff1) { + diff = diff1; + div = i; + mul = mul1; + if (diff == 0) + break; + } + } + if (i == 256 && diff > (out_freq >> 5)) + goto fail; + return ret | ((mul - 1) << 16) | div; + fail: + return 0; + } + + static struct clk *const standard_pmc_clocks[] __initdata = { + /* four primary clocks */ + &clk32k, + &main_clk, + &plla, + &pllb, + + /* PLLB children (USB) */ + &udpck, + &uhpck, + + /* MCK */ + &mck + }; + + int __init at91_clock_init(unsigned long main_clock) + { + unsigned tmp, freq, mckr; + int i; + + /* + * When the bootloader initialized the main oscillator correctly, + * there's no problem using the cycle counter. But if it didn't, + * or when using oscillator bypass mode, we must be told the speed + * of the main clock. + */ + if (!main_clock) { + do { + tmp = at91_sys_read(AT91_CKGR_MCFR); + } while (!(tmp & AT91_PMC_MAINRDY)); + main_clock = (tmp & AT91_PMC_MAINF) * (AT91_SLOW_CLOCK / 16); + } + main_clk.rate_hz = main_clock; + + /* report if PLLA is more than mildly overclocked */ + plla.rate_hz = at91_pll_rate(&plla, main_clock, at91_sys_read(AT91_CKGR_PLLAR)); + if (plla.rate_hz > 209000000) + pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); + + /* + * USB clock init: choose 48 MHz PLLB value, + * disable 48MHz clock during usb peripheral suspend. + * + * REVISIT: assumes MCK doesn't derive from PLLB! + */ + at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; + pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); + if (cpu_is_at91rm9200()) { + uhpck.pmc_mask = AT91RM9200_PMC_UHP; + udpck.pmc_mask = AT91RM9200_PMC_UDP; + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + } + at91_sys_write(AT91_CKGR_PLLBR, 0); + + udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); + uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); + + /* + * MCK and CPU derive from one of those primary clocks. + * For now, assume this parentage won't change. + */ + mckr = at91_sys_read(AT91_PMC_MCKR); + mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); + freq = mck.parent->rate_hz; + freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ + mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ + + /* Register the PMC's standard clocks */ + for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) + list_add_tail(&standard_pmc_clocks[i]->node, &clocks); + + /* MCK and CPU clock are "always on" */ + clk_enable(&mck); + + printk("Clocks: CPU %u MHz, master %u MHz, main %u.%03u MHz\n", + freq / 1000000, (unsigned) mck.rate_hz / 1000000, + (unsigned) main_clock / 1000000, + ((unsigned) main_clock % 1000000) / 1000); + + return 0; + } + + /* + * Several unused clocks may be active. Turn them off. + */ + static int __init at91_clock_reset(void) + { + unsigned long pcdr = 0; + unsigned long scdr = 0; + struct clk *clk; + + list_for_each_entry(clk, &clocks, node) { + if (clk->users > 0) + continue; + + if (clk->mode == pmc_periph_mode) + pcdr |= clk->pmc_mask; + + if (clk->mode == pmc_sys_mode) + scdr |= clk->pmc_mask; + + pr_debug("Clocks: disable unused %s\n", clk->name); + } + + at91_sys_write(AT91_PMC_PCDR, pcdr); + at91_sys_write(AT91_PMC_SCDR, scdr); + + return 0; + } + late_initcall(at91_clock_reset); diff --cc arch/arm/mach-at91/gpio.c index 000000000000,9b7495cd555d..7b87f3f101b7 mode 000000,100644..100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@@ -1,0 -1,414 +1,462 @@@ + /* + * linux/arch/arm/mach-at91/gpio.c + * + * Copyright (C) 2005 HP Labs + * + * 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. + */ + + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + + #include "generic.h" + + + static struct at91_gpio_bank *gpio; + static int gpio_banks; + + + static inline void __iomem *pin_to_controller(unsigned pin) + { + void __iomem *sys_base = (void __iomem *) AT91_VA_BASE_SYS; + + pin -= PIN_BASE; + pin /= 32; + if (likely(pin < gpio_banks)) + return sys_base + gpio[pin].offset; + + return NULL; + } + + static inline unsigned pin_to_mask(unsigned pin) + { + pin -= PIN_BASE; + return 1 << (pin % 32); + } + + + /*--------------------------------------------------------------------------*/ + + /* Not all hardware capabilities are exposed through these calls; they + * only encapsulate the most common features and modes. (So if you + * want to change signals in groups, do it directly.) + * + * Bootloaders will usually handle some of the pin multiplexing setup. + * The intent is certainly that by the time Linux is fully booted, all + * pins should have been fully initialized. These setup calls should + * only be used by board setup routines, or possibly in driver probe(). + * + * For bootloaders doing all that setup, these calls could be inlined + * as NOPs so Linux won't duplicate any setup code + */ + + ++/* ++ * mux the pin to the "GPIO" peripheral role. ++ */ ++int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup) ++{ ++ void __iomem *pio = pin_to_controller(pin); ++ unsigned mask = pin_to_mask(pin); ++ ++ if (!pio) ++ return -EINVAL; ++ __raw_writel(mask, pio + PIO_IDR); ++ __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); ++ __raw_writel(mask, pio + PIO_PER); ++ return 0; ++} ++EXPORT_SYMBOL(at91_set_GPIO_periph); ++ ++ + /* + * mux the pin to the "A" internal peripheral role. + */ + int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_ASR); + __raw_writel(mask, pio + PIO_PDR); + return 0; + } + EXPORT_SYMBOL(at91_set_A_periph); + + + /* + * mux the pin to the "B" internal peripheral role. + */ + int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_BSR); + __raw_writel(mask, pio + PIO_PDR); + return 0; + } + EXPORT_SYMBOL(at91_set_B_periph); + + + /* + * mux the pin to the gpio controller (instead of "A" or "B" peripheral), and + * configure it for an input. + */ + int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR)); + __raw_writel(mask, pio + PIO_ODR); + __raw_writel(mask, pio + PIO_PER); + return 0; + } + EXPORT_SYMBOL(at91_set_gpio_input); + + + /* + * mux the pin to the gpio controller (instead of "A" or "B" peripheral), + * and configure it for an output. + */ + int __init_or_module at91_set_gpio_output(unsigned pin, int value) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + PIO_IDR); + __raw_writel(mask, pio + PIO_PUDR); + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); + __raw_writel(mask, pio + PIO_OER); + __raw_writel(mask, pio + PIO_PER); + return 0; + } + EXPORT_SYMBOL(at91_set_gpio_output); + + + /* + * enable/disable the glitch filter; mostly used with IRQ handling. + */ + int __init_or_module at91_set_deglitch(unsigned pin, int is_on) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR)); + return 0; + } + EXPORT_SYMBOL(at91_set_deglitch); + + /* + * enable/disable the multi-driver; This is only valid for output and + * allows the output pin to run as an open collector output. + */ + int __init_or_module at91_set_multi_drive(unsigned pin, int is_on) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + + __raw_writel(mask, pio + (is_on ? PIO_MDER : PIO_MDDR)); + return 0; + } + EXPORT_SYMBOL(at91_set_multi_drive); + + /*--------------------------------------------------------------------------*/ + ++/* new-style GPIO calls; these expect at91_set_GPIO_periph to have been ++ * called, and maybe at91_set_multi_drive() for putout pins. ++ */ ++ ++int gpio_direction_input(unsigned pin) ++{ ++ void __iomem *pio = pin_to_controller(pin); ++ unsigned mask = pin_to_mask(pin); ++ ++ if (!pio || !(__raw_readl(pio + PIO_PSR) & mask)) ++ return -EINVAL; ++ __raw_writel(mask, pio + PIO_OER); ++ return 0; ++} ++EXPORT_SYMBOL(gpio_direction_input); ++ ++int gpio_direction_output(unsigned pin) ++{ ++ void __iomem *pio = pin_to_controller(pin); ++ unsigned mask = pin_to_mask(pin); ++ ++ if (!pio || !(__raw_readl(pio + PIO_PSR) & mask)) ++ return -EINVAL; ++ __raw_writel(mask, pio + PIO_OER); ++ return 0; ++} ++EXPORT_SYMBOL(gpio_direction_output); ++ ++/*--------------------------------------------------------------------------*/ ++ + /* + * assuming the pin is muxed as a gpio output, set its value. + */ + int at91_set_gpio_value(unsigned pin, int value) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (!pio) + return -EINVAL; + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); + return 0; + } + EXPORT_SYMBOL(at91_set_gpio_value); + + + /* + * read the pin's value (works even if it's not muxed as a gpio). + */ + int at91_get_gpio_value(unsigned pin) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + u32 pdsr; + + if (!pio) + return -EINVAL; + pdsr = __raw_readl(pio + PIO_PDSR); + return (pdsr & mask) != 0; + } + EXPORT_SYMBOL(at91_get_gpio_value); + + /*--------------------------------------------------------------------------*/ + + #ifdef CONFIG_PM + + static u32 wakeups[MAX_GPIO_BANKS]; + static u32 backups[MAX_GPIO_BANKS]; + + static int gpio_irq_set_wake(unsigned pin, unsigned state) + { + unsigned mask = pin_to_mask(pin); + unsigned bank = (pin - PIN_BASE) / 32; + + if (unlikely(bank >= MAX_GPIO_BANKS)) + return -EINVAL; + + if (state) + wakeups[bank] |= mask; + else + wakeups[bank] &= ~mask; + + set_irq_wake(gpio[bank].id, state); + + return 0; + } + + void at91_gpio_suspend(void) + { + int i; + + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; + + backups[i] = at91_sys_read(pio + PIO_IMR); + at91_sys_write(pio + PIO_IDR, backups[i]); + at91_sys_write(pio + PIO_IER, wakeups[i]); + + if (!wakeups[i]) + clk_disable(gpio[i].clock); + else { + #ifdef CONFIG_PM_DEBUG + printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", 'A'+i, wakeups[i]); + #endif + } + } + } + + void at91_gpio_resume(void) + { + int i; + + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; + + if (!wakeups[i]) + clk_enable(gpio[i].clock); + + at91_sys_write(pio + PIO_IDR, wakeups[i]); + at91_sys_write(pio + PIO_IER, backups[i]); + } + } + + #else + #define gpio_irq_set_wake NULL + #endif + + + /* Several AIC controller irqs are dispatched through this GPIO handler. + * To use any AT91_PIN_* as an externally triggered IRQ, first call + * at91_set_gpio_input() then maybe enable its glitch filter. + * Then just request_irq() with the pin ID; it works like any ARM IRQ + * handler, though it always triggers on rising and falling edges. + * + * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after + * configuring them with at91_set_a_periph() or at91_set_b_periph(). + * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering. + */ + + static void gpio_irq_mask(unsigned pin) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (pio) + __raw_writel(mask, pio + PIO_IDR); + } + + static void gpio_irq_unmask(unsigned pin) + { + void __iomem *pio = pin_to_controller(pin); + unsigned mask = pin_to_mask(pin); + + if (pio) + __raw_writel(mask, pio + PIO_IER); + } + + static int gpio_irq_type(unsigned pin, unsigned type) + { + return (type == IRQT_BOTHEDGE) ? 0 : -EINVAL; + } + + static struct irq_chip gpio_irqchip = { + .name = "GPIO", + .mask = gpio_irq_mask, + .unmask = gpio_irq_unmask, + .set_type = gpio_irq_type, + .set_wake = gpio_irq_set_wake, + }; + + static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) + { + unsigned pin; + struct irq_desc *gpio; + void __iomem *pio; + u32 isr; + + pio = get_irq_chip_data(irq); + + /* temporarily mask (level sensitive) parent IRQ */ + desc->chip->ack(irq); + for (;;) { + /* reading ISR acks the pending (edge triggered) GPIO interrupt */ + isr = __raw_readl(pio + PIO_ISR) & __raw_readl(pio + PIO_IMR); + if (!isr) + break; + + pin = (unsigned) get_irq_data(irq); + gpio = &irq_desc[pin]; + + while (isr) { + if (isr & 1) { + if (unlikely(gpio->depth)) { + /* + * The core ARM interrupt handler lazily disables IRQs so + * another IRQ must be generated before it actually gets + * here to be disabled on the GPIO controller. + */ + gpio_irq_mask(pin); + } + else + desc_handle_irq(pin, gpio); + } + pin++; + gpio++; + isr >>= 1; + } + } + desc->chip->unmask(irq); + /* now it may re-trigger */ + } + + /*--------------------------------------------------------------------------*/ + + /* + * Called from the processor-specific init to enable GPIO interrupt support. + */ + void __init at91_gpio_irq_setup(void) + { + unsigned pioc, pin; + + for (pioc = 0, pin = PIN_BASE; + pioc < gpio_banks; + pioc++) { + void __iomem *controller; + unsigned id = gpio[pioc].id; + unsigned i; + + clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ + + controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; + __raw_writel(~0, controller + PIO_IDR); + + set_irq_data(id, (void *) pin); + set_irq_chip_data(id, controller); + + for (i = 0; i < 32; i++, pin++) { + /* + * Can use the "simple" and not "edge" handler since it's + * shorter, and the AIC handles interupts sanely. + */ + set_irq_chip(pin, &gpio_irqchip); + set_irq_handler(pin, handle_simple_irq); + set_irq_flags(pin, IRQF_VALID); + } + + set_irq_chained_handler(id, gpio_irq_handler); + } + pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); + } + + /* + * Called from the processor-specific init to enable GPIO pin support. + */ + void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) + { + BUG_ON(nr_banks > MAX_GPIO_BANKS); + + gpio = data; + gpio_banks = nr_banks; + } diff --cc include/asm-arm/arch-at91/gpio.h index 000000000000,256f9b200ab2..98ad2114f43a mode 000000,100644..100644 --- a/include/asm-arm/arch-at91/gpio.h +++ b/include/asm-arm/arch-at91/gpio.h @@@ -1,0 -1,208 +1,252 @@@ + /* + * include/asm-arm/arch-at91/gpio.h + * + * Copyright (C) 2005 HP Labs + * + * 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. + * + */ + + #ifndef __ASM_ARCH_AT91RM9200_GPIO_H + #define __ASM_ARCH_AT91RM9200_GPIO_H + + #include + + #define PIN_BASE NR_AIC_IRQS + + #define MAX_GPIO_BANKS 5 + + /* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ + + #define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0) + #define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1) + #define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) + #define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) + #define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) + #define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) + #define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) + #define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) + #define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) + #define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) + #define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) + #define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) + #define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) + #define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) + #define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) + #define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) + #define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) + #define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) + #define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) + #define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) + #define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) + #define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) + #define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) + #define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) + #define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) + #define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) + #define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) + #define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) + #define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) + #define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) + #define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) + #define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) + + #define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0) + #define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1) + #define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) + #define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) + #define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) + #define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) + #define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) + #define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) + #define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) + #define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) + #define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) + #define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) + #define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) + #define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) + #define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) + #define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) + #define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) + #define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) + #define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) + #define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) + #define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) + #define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) + #define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) + #define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) + #define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) + #define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) + #define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) + #define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) + #define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) + #define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) + #define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) + #define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) + + #define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0) + #define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1) + #define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) + #define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) + #define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) + #define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) + #define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) + #define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) + #define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) + #define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) + #define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) + #define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) + #define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) + #define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) + #define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) + #define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) + #define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) + #define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) + #define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) + #define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) + #define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) + #define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) + #define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) + #define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) + #define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) + #define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) + #define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) + #define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) + #define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) + #define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) + #define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) + #define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) + + #define AT91_PIN_PD0 (PIN_BASE + 0x60 + 0) + #define AT91_PIN_PD1 (PIN_BASE + 0x60 + 1) + #define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) + #define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) + #define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) + #define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) + #define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) + #define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) + #define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) + #define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) + #define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) + #define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) + #define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) + #define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) + #define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) + #define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) + #define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) + #define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) + #define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) + #define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) + #define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) + #define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) + #define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) + #define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) + #define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) + #define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) + #define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) + #define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) + #define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) + #define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) + #define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) + #define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) + + #define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0) + #define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1) + #define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2) + #define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3) + #define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4) + #define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5) + #define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6) + #define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7) + #define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8) + #define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9) + #define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10) + #define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11) + #define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12) + #define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13) + #define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14) + #define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15) + #define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16) + #define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17) + #define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18) + #define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19) + #define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20) + #define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21) + #define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22) + #define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23) + #define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24) + #define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25) + #define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26) + #define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27) + #define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28) + #define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29) + #define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30) + #define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31) + + #ifndef __ASSEMBLY__ + /* setup setup routines, called from board init or driver probe() */ ++extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup); + extern int __init_or_module at91_set_gpio_output(unsigned pin, int value); + extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on); + extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on); + + /* callable at any time */ + extern int at91_set_gpio_value(unsigned pin, int value); + extern int at91_get_gpio_value(unsigned pin); + + /* callable only from core power-management code */ + extern void at91_gpio_suspend(void); + extern void at91_gpio_resume(void); -#endif + -#endif ++/*-------------------------------------------------------------------------*/ ++ ++/* wrappers for "new style" GPIO calls. the old AT91-specfic ones should ++ * eventually be removed (along with this errno.h inclusion), and the ++ * gpio request/free calls should probably be implemented. ++ */ ++ ++#include ++ ++static inline int gpio_request(unsigned gpio, const char *label) ++{ ++ return 0; ++} ++ ++static inline void gpio_free(unsigned gpio) ++{ ++} ++ ++extern int gpio_direction_input(unsigned gpio); ++extern int gpio_direction_output(unsigned gpio); + ++static inline int gpio_get_value(unsigned gpio) ++{ ++ return at91_get_gpio_value(gpio); ++} ++ ++static inline void gpio_set_value(unsigned gpio, int value) ++{ ++ at91_set_gpio_value(gpio, value); ++} ++ ++#include /* cansleep wrappers */ ++ ++static inline int gpio_to_irq(unsigned gpio) ++{ ++ return gpio; ++} ++ ++static inline int irq_to_gpio(unsigned irq) ++{ ++ return irq; ++} ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif diff --cc sound/arm/aaci.h index 9175ff9ded01,788c24afaf9f..924f69c1c44c --- a/sound/arm/aaci.h +++ b/sound/arm/aaci.h @@@ -228,7 -228,8 +228,8 @@@ struct aaci /* AC'97 */ struct mutex ac97_sem; - ac97_bus_t *ac97_bus; - ac97_t *ac97; + struct snd_ac97_bus *ac97_bus; ++ struct snd_ac97 *ac97; u32 maincr; spinlock_t lock;