Commit f4370750 authored by Russell King's avatar Russell King

[MMC] PXAMCI: enable use of platform specific data.

This allows platforms to hook in their card detection, power control
and power availability information.
parent 8c599ffc
......@@ -32,6 +32,7 @@
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include "generic.h"
......@@ -128,6 +129,12 @@ static struct platform_device pxamci_device = {
.resource = pxamci_resources,
};
void __init pxa_set_mci_info(struct pxamci_platform_data *info)
{
pxamci_device.dev.platform_data = info;
}
EXPORT_SYMBOL(pxa_set_mci_info);
static struct pxa2xx_udc_mach_info pxa_udc_info;
......
......@@ -33,6 +33,8 @@
#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/arch/mmc.h>
#include "pxamci.h"
#ifdef CONFIG_MMC_DEBUG
......@@ -52,6 +54,7 @@ struct pxamci_host {
unsigned int cmdat;
unsigned int imask;
unsigned int power_mode;
struct pxamci_platform_data *pdata;
struct mmc_request *mrq;
struct mmc_command *cmd;
......@@ -384,9 +387,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->power_mode != ios->power_mode) {
host->power_mode = ios->power_mode;
/*
* power control? none on the lubbock.
*/
if (host->pdata && host->pdata->setpower)
host->pdata->setpower(mmc->dev, ios->vdd);
if (ios->power_mode == MMC_POWER_ON)
host->cmdat |= CMDAT_INIT;
......@@ -407,6 +409,12 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
}
static irqreturn_t pxamci_detect_irq(int irq, void *devid, struct pt_regs *regs)
{
mmc_detect_change(devid);
return IRQ_HANDLED;
}
static int pxamci_probe(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
......@@ -433,11 +441,14 @@ static int pxamci_probe(struct device *dev)
mmc->ops = &pxamci_ops;
mmc->f_min = 312500;
mmc->f_max = 20000000;
mmc->ocr_avail = MMC_VDD_32_33;
host = mmc_priv(mmc);
host->mmc = mmc;
host->dma = -1;
host->pdata = pdev->dev.platform_data;
mmc->ocr_avail = host->pdata ?
host->pdata->ocr_mask :
MMC_VDD_32_33|MMC_VDD_33_34;
host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
if (!host->sg_cpu) {
......@@ -482,6 +493,9 @@ static int pxamci_probe(struct device *dev)
dev_set_drvdata(dev, mmc);
if (host->pdata && host->pdata->init)
host->pdata->init(dev, pxamci_detect_irq, mmc);
mmc_add_host(mmc);
return 0;
......@@ -510,6 +524,9 @@ static int pxamci_remove(struct device *dev)
if (mmc) {
struct pxamci_host *host = mmc_priv(mmc);
if (host->pdata && host->pdata->exit)
host->pdata->exit(dev, mmc);
mmc_remove_host(mmc);
pxamci_stop_clock(host);
......@@ -517,6 +534,8 @@ static int pxamci_remove(struct device *dev)
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
host->base + MMC_I_MASK);
pxa_set_cken(CKEN12_MMC, 0);
free_irq(host->irq, host);
pxa_free_dma(host->dma);
iounmap(host->base);
......
#ifndef ASMARM_ARCH_MMC_H
#define ASMARM_ARCH_MMC_H
#include <linux/mmc/protocol.h>
#include <linux/interrupt.h>
struct device;
struct mmc_host;
struct pxamci_platform_data {
unsigned int ocr_mask; /* available voltages */
int (*init)(struct device *, irqreturn_t (*)(int, void *, struct pt_regs *), void *);
void (*setpower)(struct device *, unsigned int);
void (*exit)(struct device *, void *);
};
extern void pxa_set_mci_info(struct pxamci_platform_data *info);
#endif
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