Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/drzeus/mmc

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/drzeus/mmc:
  sdhci: release irq during suspend
  sdhci: make isr tolerant of read errors
  mmc: require explicit support for high-speed
  ncpfs: make sure server connection survives a kill
  • Loading branch information
Linus Torvalds committed Mar 7, 2007
2 parents 205c911 + a715dfc commit 8328258
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 115 deletions.
83 changes: 48 additions & 35 deletions drivers/mmc/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,11 @@ static inline void mmc_set_ios(struct mmc_host *host)
{
struct mmc_ios *ios = &host->ios;

pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n",
pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "
"width %u timing %u\n",
mmc_hostname(host), ios->clock, ios->bus_mode,
ios->power_mode, ios->chip_select, ios->vdd,
ios->bus_width);
ios->bus_width, ios->timing);

host->ops->set_ios(host, ios);
}
Expand Down Expand Up @@ -809,6 +810,7 @@ static void mmc_power_up(struct mmc_host *host)
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.power_mode = MMC_POWER_UP;
host->ios.bus_width = MMC_BUS_WIDTH_1;
host->ios.timing = MMC_TIMING_LEGACY;
mmc_set_ios(host);

mmc_delay(1);
Expand All @@ -828,6 +830,7 @@ static void mmc_power_off(struct mmc_host *host)
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.power_mode = MMC_POWER_OFF;
host->ios.bus_width = MMC_BUS_WIDTH_1;
host->ios.timing = MMC_TIMING_LEGACY;
mmc_set_ios(host);
}

Expand Down Expand Up @@ -1112,46 +1115,50 @@ static void mmc_process_ext_csds(struct mmc_host *host)
continue;
}

/* Activate highspeed support. */
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_HS_TIMING << 16) |
(1 << 8) |
EXT_CSD_CMD_SET_NORMAL;
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
if (host->caps & MMC_CAP_MMC_HIGHSPEED) {
/* Activate highspeed support. */
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_HS_TIMING << 16) |
(1 << 8) |
EXT_CSD_CMD_SET_NORMAL;
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;

err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) {
printk("%s: failed to switch card to mmc v4 "
"high-speed mode.\n",
mmc_hostname(card->host));
continue;
}
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) {
printk("%s: failed to switch card to mmc v4 "
"high-speed mode.\n",
mmc_hostname(card->host));
continue;
}

mmc_card_set_highspeed(card);
mmc_card_set_highspeed(card);

/* Check for host support for wide-bus modes. */
if (!(host->caps & MMC_CAP_4_BIT_DATA)) {
continue;
host->ios.timing = MMC_TIMING_SD_HS;
mmc_set_ios(host);
}

/* Activate 4-bit support. */
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_BUS_WIDTH << 16) |
(EXT_CSD_BUS_WIDTH_4 << 8) |
EXT_CSD_CMD_SET_NORMAL;
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
/* Check for host support for wide-bus modes. */
if (host->caps & MMC_CAP_4_BIT_DATA) {
/* Activate 4-bit support. */
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(EXT_CSD_BUS_WIDTH << 16) |
(EXT_CSD_BUS_WIDTH_4 << 8) |
EXT_CSD_CMD_SET_NORMAL;
cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;

err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) {
printk("%s: failed to switch card to "
"mmc v4 4-bit bus mode.\n",
mmc_hostname(card->host));
continue;
}
err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
if (err != MMC_ERR_NONE) {
printk("%s: failed to switch card to "
"mmc v4 4-bit bus mode.\n",
mmc_hostname(card->host));
continue;
}

host->ios.bus_width = MMC_BUS_WIDTH_4;
host->ios.bus_width = MMC_BUS_WIDTH_4;
mmc_set_ios(host);
}
}

kfree(ext_csd);
Expand Down Expand Up @@ -1241,6 +1248,9 @@ static void mmc_read_switch_caps(struct mmc_host *host)
unsigned char *status;
struct scatterlist sg;

if (!(host->caps & MMC_CAP_SD_HIGHSPEED))
return;

status = kmalloc(64, GFP_KERNEL);
if (!status) {
printk(KERN_WARNING "%s: Unable to allocate buffer for "
Expand Down Expand Up @@ -1332,6 +1342,9 @@ static void mmc_read_switch_caps(struct mmc_host *host)
}

mmc_card_set_highspeed(card);

host->ios.timing = MMC_TIMING_SD_HS;
mmc_set_ios(host);
}

kfree(status);
Expand Down
39 changes: 23 additions & 16 deletions drivers/mmc/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,6 @@ static void sdhci_finish_command(struct sdhci_host *host)
static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
int div;
u8 ctrl;
u16 clk;
unsigned long timeout;

Expand All @@ -615,13 +614,6 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)

writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);

ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
if (clock > 25000000)
ctrl |= SDHCI_CTRL_HISPD;
else
ctrl &= ~SDHCI_CTRL_HISPD;
writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);

if (clock == 0)
goto out;

Expand Down Expand Up @@ -761,10 +753,17 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
sdhci_set_power(host, ios->vdd);

ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);

if (ios->bus_width == MMC_BUS_WIDTH_4)
ctrl |= SDHCI_CTRL_4BITBUS;
else
ctrl &= ~SDHCI_CTRL_4BITBUS;

if (ios->timing == MMC_TIMING_SD_HS)
ctrl |= SDHCI_CTRL_HISPD;
else
ctrl &= ~SDHCI_CTRL_HISPD;

writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);

mmiowb();
Expand Down Expand Up @@ -994,7 +993,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)

intmask = readl(host->ioaddr + SDHCI_INT_STATUS);

if (!intmask) {
if (!intmask || intmask == 0xffffffff) {
result = IRQ_NONE;
goto out;
}
Expand Down Expand Up @@ -1080,6 +1079,13 @@ static int sdhci_suspend (struct pci_dev *pdev, pm_message_t state)

pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);

for (i = 0;i < chip->num_slots;i++) {
if (!chip->hosts[i])
continue;
free_irq(chip->hosts[i]->irq, chip->hosts[i]);
}

pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));

Expand Down Expand Up @@ -1108,6 +1114,11 @@ static int sdhci_resume (struct pci_dev *pdev)
continue;
if (chip->hosts[i]->flags & SDHCI_USE_DMA)
pci_set_master(pdev);
ret = request_irq(chip->hosts[i]->irq, sdhci_irq,
IRQF_SHARED, chip->hosts[i]->slot_descr,
chip->hosts[i]);
if (ret)
return ret;
sdhci_init(chip->hosts[i]);
mmiowb();
ret = mmc_resume_host(chip->hosts[i]->mmc);
Expand Down Expand Up @@ -1274,6 +1285,9 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
mmc->f_max = host->max_clk;
mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;

if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;

mmc->ocr_avail = 0;
if (caps & SDHCI_CAN_VDD_330)
mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
Expand All @@ -1282,13 +1296,6 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot)
if (caps & SDHCI_CAN_VDD_180)
mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19;

if ((host->max_clk > 25000000) && !(caps & SDHCI_CAN_DO_HISPD)) {
printk(KERN_ERR "%s: Controller reports > 25 MHz base clock,"
" but no high speed support.\n",
host->slot_descr);
mmc->f_max = 25000000;
}

if (mmc->ocr_avail == 0) {
printk(KERN_ERR "%s: Hardware doesn't report any "
"support voltages.\n", host->slot_descr);
Expand Down
16 changes: 14 additions & 2 deletions fs/ncpfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
server->packet = vmalloc(NCP_PACKET_SIZE);
if (server->packet == NULL)
goto out_nls;
server->txbuf = vmalloc(NCP_PACKET_SIZE);
if (server->txbuf == NULL)
goto out_packet;
server->rxbuf = vmalloc(NCP_PACKET_SIZE);
if (server->rxbuf == NULL)
goto out_txbuf;

sock->sk->sk_data_ready = ncp_tcp_data_ready;
sock->sk->sk_error_report = ncp_tcp_error_report;
Expand All @@ -597,7 +603,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
error = ncp_connect(server);
ncp_unlock_server(server);
if (error < 0)
goto out_packet;
goto out_rxbuf;
DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));

error = -EMSGSIZE; /* -EREMOTESIDEINCOMPATIBLE */
Expand Down Expand Up @@ -666,8 +672,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
ncp_lock_server(server);
ncp_disconnect(server);
ncp_unlock_server(server);
out_packet:
out_rxbuf:
ncp_stop_tasks(server);
vfree(server->rxbuf);
out_txbuf:
vfree(server->txbuf);
out_packet:
vfree(server->packet);
out_nls:
#ifdef CONFIG_NCPFS_NLS
Expand Down Expand Up @@ -723,6 +733,8 @@ static void ncp_put_super(struct super_block *sb)

kfree(server->priv.data);
kfree(server->auth.object_name);
vfree(server->rxbuf);
vfree(server->txbuf);
vfree(server->packet);
sb->s_fs_info = NULL;
kfree(server);
Expand Down
Loading

0 comments on commit 8328258

Please sign in to comment.