Commit 6663050e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm:
  ALSA: AACI: fix timeout duration
  ALSA: AACI: fix timeout condition checking
  ARM: 6636/1: ep93xx: default multiplexed gpio ports to gpio mode
  ARM: 6637/1: Make the argument to virt_to_phys() "const volatile"
  ARM: twd: ensure timer reload is reprogrammed on entry to periodic mode
  ARM: 6635/2: Configure reference clock for Versatile Express timers
  ARM: versatile: name configuration options after actual board names
  ARM: realview: name configuration options after actual board names
  ARM: realview,vexpress: fix section mismatch warning for pen_release
  ARM: 6632/3: mmci: stop using the blockend interrupts
parents 3af03655 2f8e7285
...@@ -50,6 +50,12 @@ ...@@ -50,6 +50,12 @@
#define SCPCELLID2 0xFF8 #define SCPCELLID2 0xFF8
#define SCPCELLID3 0xFFC #define SCPCELLID3 0xFFC
#define SCCTRL_TIMEREN0SEL_REFCLK (0 << 15)
#define SCCTRL_TIMEREN0SEL_TIMCLK (1 << 15)
#define SCCTRL_TIMEREN1SEL_REFCLK (0 << 17)
#define SCCTRL_TIMEREN1SEL_TIMCLK (1 << 17)
static inline void sysctl_soft_reset(void __iomem *base) static inline void sysctl_soft_reset(void __iomem *base)
{ {
/* writing any value to SCSYSSTAT reg will reset system */ /* writing any value to SCSYSSTAT reg will reset system */
......
...@@ -188,7 +188,7 @@ ...@@ -188,7 +188,7 @@
* translation for translating DMA addresses. Use the driver * translation for translating DMA addresses. Use the driver
* DMA support - see dma-mapping.h. * DMA support - see dma-mapping.h.
*/ */
static inline unsigned long virt_to_phys(void *x) static inline unsigned long virt_to_phys(const volatile void *x)
{ {
return __virt_to_phys((unsigned long)(x)); return __virt_to_phys((unsigned long)(x));
} }
......
...@@ -36,6 +36,7 @@ static void twd_set_mode(enum clock_event_mode mode, ...@@ -36,6 +36,7 @@ static void twd_set_mode(enum clock_event_mode mode,
/* timer load already set up */ /* timer load already set up */
ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
| TWD_TIMER_CONTROL_PERIODIC; | TWD_TIMER_CONTROL_PERIODIC;
__raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD);
break; break;
case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_ONESHOT:
/* period set, and timer enabled in 'next_event' hook */ /* period set, and timer enabled in 'next_event' hook */
...@@ -81,7 +82,7 @@ int twd_timer_ack(void) ...@@ -81,7 +82,7 @@ int twd_timer_ack(void)
static void __cpuinit twd_calibrate_rate(void) static void __cpuinit twd_calibrate_rate(void)
{ {
unsigned long load, count; unsigned long count;
u64 waitjiffies; u64 waitjiffies;
/* /*
...@@ -116,10 +117,6 @@ static void __cpuinit twd_calibrate_rate(void) ...@@ -116,10 +117,6 @@ static void __cpuinit twd_calibrate_rate(void)
printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
(twd_timer_rate / 1000000) % 100); (twd_timer_rate / 1000000) % 100);
} }
load = twd_timer_rate / HZ;
__raw_writel(load, twd_base + TWD_TIMER_LOAD);
} }
/* /*
......
...@@ -427,6 +427,13 @@ void __init ep93xx_gpio_init(void) ...@@ -427,6 +427,13 @@ void __init ep93xx_gpio_init(void)
{ {
int i; int i;
/* Set Ports C, D, E, G, and H for GPIO use */
ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
EP93XX_SYSCON_DEVCFG_GONK |
EP93XX_SYSCON_DEVCFG_EONIDE |
EP93XX_SYSCON_DEVCFG_GONIDE |
EP93XX_SYSCON_DEVCFG_HONIDE);
for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++)
gpiochip_add(&ep93xx_gpio_banks[i].chip); gpiochip_add(&ep93xx_gpio_banks[i].chip);
} }
...@@ -2,52 +2,56 @@ menu "RealView platform type" ...@@ -2,52 +2,56 @@ menu "RealView platform type"
depends on ARCH_REALVIEW depends on ARCH_REALVIEW
config MACH_REALVIEW_EB config MACH_REALVIEW_EB
bool "Support RealView/EB platform" bool "Support RealView(R) Emulation Baseboard"
select ARM_GIC select ARM_GIC
help help
Include support for the ARM(R) RealView Emulation Baseboard platform. Include support for the ARM(R) RealView(R) Emulation Baseboard
platform.
config REALVIEW_EB_A9MP config REALVIEW_EB_A9MP
bool "Support Multicore Cortex-A9" bool "Support Multicore Cortex-A9 Tile"
depends on MACH_REALVIEW_EB depends on MACH_REALVIEW_EB
select CPU_V7 select CPU_V7
help help
Enable support for the Cortex-A9MPCore tile on the Realview platform. Enable support for the Cortex-A9MPCore tile fitted to the
Realview(R) Emulation Baseboard platform.
config REALVIEW_EB_ARM11MP config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore tile" bool "Support ARM11MPCore Tile"
depends on MACH_REALVIEW_EB depends on MACH_REALVIEW_EB
select CPU_V6 select CPU_V6
select ARCH_HAS_BARRIERS if SMP select ARCH_HAS_BARRIERS if SMP
help help
Enable support for the ARM11MPCore tile on the Realview platform. Enable support for the ARM11MPCore tile fitted to the Realview(R)
Emulation Baseboard platform.
config REALVIEW_EB_ARM11MP_REVB config REALVIEW_EB_ARM11MP_REVB
bool "Support ARM11MPCore RevB tile" bool "Support ARM11MPCore RevB Tile"
depends on REALVIEW_EB_ARM11MP depends on REALVIEW_EB_ARM11MP
help help
Enable support for the ARM11MPCore RevB tile on the Realview Enable support for the ARM11MPCore Revision B tile on the
platform. Since there are device address differences, a Realview(R) Emulation Baseboard platform. Since there are device
kernel built with this option enabled is not compatible with address differences, a kernel built with this option enabled is
other revisions of the ARM11MPCore tile. not compatible with other revisions of the ARM11MPCore tile.
config MACH_REALVIEW_PB11MP config MACH_REALVIEW_PB11MP
bool "Support RealView/PB11MPCore platform" bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
select CPU_V6 select CPU_V6
select ARM_GIC select ARM_GIC
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select ARCH_HAS_BARRIERS if SMP select ARCH_HAS_BARRIERS if SMP
help help
Include support for the ARM(R) RealView MPCore Platform Baseboard. Include support for the ARM(R) RealView(R) Platform Baseboard for
PB11MPCore is a platform with an on-board ARM11MPCore and has the ARM11MPCore. This platform has an on-board ARM11MPCore and has
support for PCI-E and Compact Flash. support for PCI-E and Compact Flash.
config MACH_REALVIEW_PB1176 config MACH_REALVIEW_PB1176
bool "Support RealView/PB1176 platform" bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
select CPU_V6 select CPU_V6
select ARM_GIC select ARM_GIC
help help
Include support for the ARM(R) RealView ARM1176 Platform Baseboard. Include support for the ARM(R) RealView(R) Platform Baseboard for
ARM1176JZF-S.
config REALVIEW_PB1176_SECURE_FLASH config REALVIEW_PB1176_SECURE_FLASH
bool "Allow access to the secure flash memory block" bool "Allow access to the secure flash memory block"
...@@ -59,23 +63,24 @@ config REALVIEW_PB1176_SECURE_FLASH ...@@ -59,23 +63,24 @@ config REALVIEW_PB1176_SECURE_FLASH
block (64MB @ 0x3c000000) is required. block (64MB @ 0x3c000000) is required.
config MACH_REALVIEW_PBA8 config MACH_REALVIEW_PBA8
bool "Support RealView/PB-A8 platform" bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
select CPU_V7 select CPU_V7
select ARM_GIC select ARM_GIC
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
help help
Include support for the ARM(R) RealView Cortex-A8 Platform Baseboard. Include support for the ARM(R) RealView Platform Baseboard for
PB-A8 is a platform with an on-board Cortex-A8 and has support for Cortex(tm)-A8. This platform has an on-board Cortex-A8 and has
PCI-E and Compact Flash. support for PCI-E and Compact Flash.
config MACH_REALVIEW_PBX config MACH_REALVIEW_PBX
bool "Support RealView/PBX platform" bool "Support RealView(R) Platform Baseboard Explore"
select ARM_GIC select ARM_GIC
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
select ZONE_DMA if SPARSEMEM select ZONE_DMA if SPARSEMEM
help help
Include support for the ARM(R) RealView PBX platform. Include support for the ARM(R) RealView(R) Platform Baseboard
Explore.
config REALVIEW_HIGH_PHYS_OFFSET config REALVIEW_HIGH_PHYS_OFFSET
bool "High physical base address for the RealView platform" bool "High physical base address for the RealView platform"
......
...@@ -41,7 +41,7 @@ volatile int __cpuinitdata pen_release = -1; ...@@ -41,7 +41,7 @@ volatile int __cpuinitdata pen_release = -1;
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably. * or not. This is necessary for the hotplug code to work reliably.
*/ */
static void write_pen_release(int val) static void __cpuinit write_pen_release(int val)
{ {
pen_release = val; pen_release = val;
smp_wmb(); smp_wmb();
......
...@@ -2,17 +2,19 @@ menu "Versatile platform type" ...@@ -2,17 +2,19 @@ menu "Versatile platform type"
depends on ARCH_VERSATILE depends on ARCH_VERSATILE
config ARCH_VERSATILE_PB config ARCH_VERSATILE_PB
bool "Support Versatile/PB platform" bool "Support Versatile Platform Baseboard for ARM926EJ-S"
select CPU_ARM926T select CPU_ARM926T
select MIGHT_HAVE_PCI select MIGHT_HAVE_PCI
default y default y
help help
Include support for the ARM(R) Versatile/PB platform. Include support for the ARM(R) Versatile Platform Baseboard
for the ARM926EJ-S.
config MACH_VERSATILE_AB config MACH_VERSATILE_AB
bool "Support Versatile/AB platform" bool "Support Versatile Application Baseboard for ARM926EJ-S"
select CPU_ARM926T select CPU_ARM926T
help help
Include support for the ARM(R) Versatile/AP platform. Include support for the ARM(R) Versatile Application Baseboard
for the ARM926EJ-S.
endmenu endmenu
...@@ -39,7 +39,7 @@ volatile int __cpuinitdata pen_release = -1; ...@@ -39,7 +39,7 @@ volatile int __cpuinitdata pen_release = -1;
* observers, irrespective of whether they're taking part in coherency * observers, irrespective of whether they're taking part in coherency
* or not. This is necessary for the hotplug code to work reliably. * or not. This is necessary for the hotplug code to work reliably.
*/ */
static void write_pen_release(int val) static void __cpuinit write_pen_release(int val)
{ {
pen_release = val; pen_release = val;
smp_wmb(); smp_wmb();
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/hardware/arm_timer.h> #include <asm/hardware/arm_timer.h>
#include <asm/hardware/timer-sp.h> #include <asm/hardware/timer-sp.h>
#include <asm/hardware/sp810.h>
#include <mach/motherboard.h> #include <mach/motherboard.h>
...@@ -50,8 +51,16 @@ void __init v2m_map_io(struct map_desc *tile, size_t num) ...@@ -50,8 +51,16 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
static void __init v2m_timer_init(void) static void __init v2m_timer_init(void)
{ {
u32 scctrl;
versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
......
...@@ -46,10 +46,6 @@ static unsigned int fmax = 515633; ...@@ -46,10 +46,6 @@ static unsigned int fmax = 515633;
* is asserted (likewise for RX) * is asserted (likewise for RX)
* @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
* is asserted (likewise for RX) * is asserted (likewise for RX)
* @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
* and will not work at all.
* @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
* using DMA.
* @sdio: variant supports SDIO * @sdio: variant supports SDIO
* @st_clkdiv: true if using a ST-specific clock divider algorithm * @st_clkdiv: true if using a ST-specific clock divider algorithm
*/ */
...@@ -59,8 +55,6 @@ struct variant_data { ...@@ -59,8 +55,6 @@ struct variant_data {
unsigned int datalength_bits; unsigned int datalength_bits;
unsigned int fifosize; unsigned int fifosize;
unsigned int fifohalfsize; unsigned int fifohalfsize;
bool broken_blockend;
bool broken_blockend_dma;
bool sdio; bool sdio;
bool st_clkdiv; bool st_clkdiv;
}; };
...@@ -76,7 +70,6 @@ static struct variant_data variant_u300 = { ...@@ -76,7 +70,6 @@ static struct variant_data variant_u300 = {
.fifohalfsize = 8 * 4, .fifohalfsize = 8 * 4,
.clkreg_enable = 1 << 13, /* HWFCEN */ .clkreg_enable = 1 << 13, /* HWFCEN */
.datalength_bits = 16, .datalength_bits = 16,
.broken_blockend_dma = true,
.sdio = true, .sdio = true,
}; };
...@@ -86,7 +79,6 @@ static struct variant_data variant_ux500 = { ...@@ -86,7 +79,6 @@ static struct variant_data variant_ux500 = {
.clkreg = MCI_CLK_ENABLE, .clkreg = MCI_CLK_ENABLE,
.clkreg_enable = 1 << 14, /* HWFCEN */ .clkreg_enable = 1 << 14, /* HWFCEN */
.datalength_bits = 24, .datalength_bits = 24,
.broken_blockend = true,
.sdio = true, .sdio = true,
.st_clkdiv = true, .st_clkdiv = true,
}; };
...@@ -210,8 +202,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) ...@@ -210,8 +202,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
host->data = data; host->data = data;
host->size = data->blksz * data->blocks; host->size = data->blksz * data->blocks;
host->data_xfered = 0; host->data_xfered = 0;
host->blockend = false;
host->dataend = false;
mmci_init_sg(host, data); mmci_init_sg(host, data);
...@@ -288,21 +278,26 @@ static void ...@@ -288,21 +278,26 @@ static void
mmci_data_irq(struct mmci_host *host, struct mmc_data *data, mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
unsigned int status) unsigned int status)
{ {
struct variant_data *variant = host->variant;
/* First check for errors */ /* First check for errors */
if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) { if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
u32 remain, success;
/* Calculate how far we are into the transfer */
remain = readl(host->base + MMCIDATACNT) << 2;
success = data->blksz * data->blocks - remain;
dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
if (status & MCI_DATACRCFAIL) if (status & MCI_DATACRCFAIL) {
/* Last block was not successful */
host->data_xfered = ((success / data->blksz) - 1 * data->blksz);
data->error = -EILSEQ; data->error = -EILSEQ;
else if (status & MCI_DATATIMEOUT) } else if (status & MCI_DATATIMEOUT) {
host->data_xfered = success;
data->error = -ETIMEDOUT; data->error = -ETIMEDOUT;
else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
host->data_xfered = success;
data->error = -EIO; data->error = -EIO;
}
/* Force-complete the transaction */
host->blockend = true;
host->dataend = true;
/* /*
* We hit an error condition. Ensure that any data * We hit an error condition. Ensure that any data
...@@ -321,61 +316,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, ...@@ -321,61 +316,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
} }
} }
/* if (status & MCI_DATABLOCKEND)
* On ARM variants in PIO mode, MCI_DATABLOCKEND dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
* is always sent first, and we increase the
* transfered number of bytes for that IRQ. Then
* MCI_DATAEND follows and we conclude the transaction.
*
* On the Ux500 single-IRQ variant MCI_DATABLOCKEND
* doesn't seem to immediately clear from the status,
* so we can't use it keep count when only one irq is
* used because the irq will hit for other reasons, and
* then the flag is still up. So we use the MCI_DATAEND
* IRQ at the end of the entire transfer because
* MCI_DATABLOCKEND is broken.
*
* In the U300, the IRQs can arrive out-of-order,
* e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
* so for this case we use the flags "blockend" and
* "dataend" to make sure both IRQs have arrived before
* concluding the transaction. (This does not apply
* to the Ux500 which doesn't fire MCI_DATABLOCKEND
* at all.) In DMA mode it suffers from the same problem
* as the Ux500.
*/
if (status & MCI_DATABLOCKEND) {
/*
* Just being a little over-cautious, we do not
* use this progressive update if the hardware blockend
* flag is unreliable: since it can stay high between
* IRQs it will corrupt the transfer counter.
*/
if (!variant->broken_blockend)
host->data_xfered += data->blksz;
host->blockend = true;
}
if (status & MCI_DATAEND)
host->dataend = true;
/* if (status & MCI_DATAEND) {
* On variants with broken blockend we shall only wait for dataend,
* on others we must sync with the blockend signal since they can
* appear out-of-order.
*/
if (host->dataend && (host->blockend || variant->broken_blockend)) {
mmci_stop_data(host); mmci_stop_data(host);
/* Reset these flags */ if (!data->error)
host->blockend = false; /* The error clause is handled above, success! */
host->dataend = false;
/*
* Variants with broken blockend flags need to handle the
* end of the entire transfer here.
*/
if (variant->broken_blockend && !data->error)
host->data_xfered += data->blksz * data->blocks; host->data_xfered += data->blksz * data->blocks;
if (!data->stop) { if (!data->stop) {
...@@ -770,7 +718,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -770,7 +718,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
struct variant_data *variant = id->data; struct variant_data *variant = id->data;
struct mmci_host *host; struct mmci_host *host;
struct mmc_host *mmc; struct mmc_host *mmc;
unsigned int mask;
int ret; int ret;
/* must have platform data */ /* must have platform data */
...@@ -951,12 +898,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id) ...@@ -951,12 +898,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
goto irq0_free; goto irq0_free;
} }
mask = MCI_IRQENABLE; writel(MCI_IRQENABLE, host->base + MMCIMASK0);
/* Don't use the datablockend flag if it's broken */
if (variant->broken_blockend)
mask &= ~MCI_DATABLOCKEND;
writel(mask, host->base + MMCIMASK0);
amba_set_drvdata(dev, mmc); amba_set_drvdata(dev, mmc);
......
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
#define MCI_IRQENABLE \ #define MCI_IRQENABLE \
(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK) MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
/* These interrupts are directed to IRQ1 when two IRQ lines are available */ /* These interrupts are directed to IRQ1 when two IRQ lines are available */
#define MCI_IRQ1MASK \ #define MCI_IRQ1MASK \
...@@ -177,9 +177,6 @@ struct mmci_host { ...@@ -177,9 +177,6 @@ struct mmci_host {
struct timer_list timer; struct timer_list timer;
unsigned int oldstat; unsigned int oldstat;
bool blockend;
bool dataend;
/* pio stuff */ /* pio stuff */
struct sg_mapping_iter sg_miter; struct sg_mapping_iter sg_miter;
unsigned int size; unsigned int size;
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#define DRIVER_NAME "aaci-pl041" #define DRIVER_NAME "aaci-pl041"
#define FRAME_PERIOD_US 21
/* /*
* PM support is not complete. Turn it off. * PM support is not complete. Turn it off.
*/ */
...@@ -64,8 +66,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, ...@@ -64,8 +66,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
unsigned short val) unsigned short val)
{ {
struct aaci *aaci = ac97->private_data; struct aaci *aaci = ac97->private_data;
int timeout;
u32 v; u32 v;
int timeout = 5000;
if (ac97->num >= 4) if (ac97->num >= 4)
return; return;
...@@ -81,14 +83,17 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, ...@@ -81,14 +83,17 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
writel(val << 4, aaci->base + AACI_SL2TX); writel(val << 4, aaci->base + AACI_SL2TX);
writel(reg << 12, aaci->base + AACI_SL1TX); writel(reg << 12, aaci->base + AACI_SL1TX);
/* /* Initially, wait one frame period */
* Wait for the transmission of both slots to complete. udelay(FRAME_PERIOD_US);
*/
/* And then wait an additional eight frame periods for it to be sent */
timeout = FRAME_PERIOD_US * 8;
do { do {
udelay(1);
v = readl(aaci->base + AACI_SLFR); v = readl(aaci->base + AACI_SLFR);
} while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout); } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
if (!timeout) if (v & (SLFR_1TXB|SLFR_2TXB))
dev_err(&aaci->dev->dev, dev_err(&aaci->dev->dev,
"timeout waiting for write to complete\n"); "timeout waiting for write to complete\n");
...@@ -101,9 +106,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, ...@@ -101,9 +106,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{ {
struct aaci *aaci = ac97->private_data; struct aaci *aaci = ac97->private_data;
int timeout, retries = 10;
u32 v; u32 v;
int timeout = 5000;
int retries = 10;
if (ac97->num >= 4) if (ac97->num >= 4)
return ~0; return ~0;
...@@ -117,35 +121,34 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg) ...@@ -117,35 +121,34 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
*/ */
writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX); writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
/* /* Initially, wait one frame period */
* Wait for the transmission to complete. udelay(FRAME_PERIOD_US);
*/
/* And then wait an additional eight frame periods for it to be sent */
timeout = FRAME_PERIOD_US * 8;
do { do {
udelay(1);
v = readl(aaci->base + AACI_SLFR); v = readl(aaci->base + AACI_SLFR);
} while ((v & SLFR_1TXB) && --timeout); } while ((v & SLFR_1TXB) && --timeout);
if (!timeout) { if (v & SLFR_1TXB) {
dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n"); dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
v = ~0; v = ~0;
goto out; goto out;
} }
/* /* Now wait for the response frame */
* Give the AC'97 codec more than enough time udelay(FRAME_PERIOD_US);
* to respond. (42us = ~2 frames at 48kHz.)
*/
udelay(42);
/* /* And then wait an additional eight frame periods for data */
* Wait for slot 2 to indicate data. timeout = FRAME_PERIOD_US * 8;
*/
timeout = 5000;
do { do {
udelay(1);
cond_resched(); cond_resched();
v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
} while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout); } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
if (!timeout) { if (v != (SLFR_1RXV|SLFR_2RXV)) {
dev_err(&aaci->dev->dev, "timeout on RX valid\n"); dev_err(&aaci->dev->dev, "timeout on RX valid\n");
v = ~0; v = ~0;
goto out; goto out;
...@@ -179,6 +182,7 @@ aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask) ...@@ -179,6 +182,7 @@ aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
int timeout = 5000; int timeout = 5000;
do { do {
udelay(1);
val = readl(aacirun->base + AACI_SR); val = readl(aacirun->base + AACI_SR);
} while (val & mask && timeout--); } while (val & mask && timeout--);
} }
...@@ -874,7 +878,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) ...@@ -874,7 +878,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
* Give the AC'97 codec more than enough time * Give the AC'97 codec more than enough time
* to wake up. (42us = ~2 frames at 48kHz.) * to wake up. (42us = ~2 frames at 48kHz.)
*/ */
udelay(42); udelay(FRAME_PERIOD_US * 2);
ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus); ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
if (ret) if (ret)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment