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 @@ ...@@ -32,6 +32,7 @@
#include <asm/arch/udc.h> #include <asm/arch/udc.h>
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h>
#include "generic.h" #include "generic.h"
...@@ -128,6 +129,12 @@ static struct platform_device pxamci_device = { ...@@ -128,6 +129,12 @@ static struct platform_device pxamci_device = {
.resource = pxamci_resources, .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; static struct pxa2xx_udc_mach_info pxa_udc_info;
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/sizes.h> #include <asm/sizes.h>
#include <asm/arch/mmc.h>
#include "pxamci.h" #include "pxamci.h"
#ifdef CONFIG_MMC_DEBUG #ifdef CONFIG_MMC_DEBUG
...@@ -52,6 +54,7 @@ struct pxamci_host { ...@@ -52,6 +54,7 @@ struct pxamci_host {
unsigned int cmdat; unsigned int cmdat;
unsigned int imask; unsigned int imask;
unsigned int power_mode; unsigned int power_mode;
struct pxamci_platform_data *pdata;
struct mmc_request *mrq; struct mmc_request *mrq;
struct mmc_command *cmd; struct mmc_command *cmd;
...@@ -384,9 +387,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ...@@ -384,9 +387,8 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->power_mode != ios->power_mode) { if (host->power_mode != ios->power_mode) {
host->power_mode = ios->power_mode; host->power_mode = ios->power_mode;
/* if (host->pdata && host->pdata->setpower)
* power control? none on the lubbock. host->pdata->setpower(mmc->dev, ios->vdd);
*/
if (ios->power_mode == MMC_POWER_ON) if (ios->power_mode == MMC_POWER_ON)
host->cmdat |= CMDAT_INIT; host->cmdat |= CMDAT_INIT;
...@@ -407,6 +409,12 @@ static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs) ...@@ -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; 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) static int pxamci_probe(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
...@@ -433,11 +441,14 @@ static int pxamci_probe(struct device *dev) ...@@ -433,11 +441,14 @@ static int pxamci_probe(struct device *dev)
mmc->ops = &pxamci_ops; mmc->ops = &pxamci_ops;
mmc->f_min = 312500; mmc->f_min = 312500;
mmc->f_max = 20000000; mmc->f_max = 20000000;
mmc->ocr_avail = MMC_VDD_32_33;
host = mmc_priv(mmc); host = mmc_priv(mmc);
host->mmc = mmc; host->mmc = mmc;
host->dma = -1; 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); host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
if (!host->sg_cpu) { if (!host->sg_cpu) {
...@@ -482,6 +493,9 @@ static int pxamci_probe(struct device *dev) ...@@ -482,6 +493,9 @@ static int pxamci_probe(struct device *dev)
dev_set_drvdata(dev, mmc); dev_set_drvdata(dev, mmc);
if (host->pdata && host->pdata->init)
host->pdata->init(dev, pxamci_detect_irq, mmc);
mmc_add_host(mmc); mmc_add_host(mmc);
return 0; return 0;
...@@ -510,6 +524,9 @@ static int pxamci_remove(struct device *dev) ...@@ -510,6 +524,9 @@ static int pxamci_remove(struct device *dev)
if (mmc) { if (mmc) {
struct pxamci_host *host = mmc_priv(mmc); struct pxamci_host *host = mmc_priv(mmc);
if (host->pdata && host->pdata->exit)
host->pdata->exit(dev, mmc);
mmc_remove_host(mmc); mmc_remove_host(mmc);
pxamci_stop_clock(host); pxamci_stop_clock(host);
...@@ -517,6 +534,8 @@ static int pxamci_remove(struct device *dev) ...@@ -517,6 +534,8 @@ static int pxamci_remove(struct device *dev)
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE, END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
host->base + MMC_I_MASK); host->base + MMC_I_MASK);
pxa_set_cken(CKEN12_MMC, 0);
free_irq(host->irq, host); free_irq(host->irq, host);
pxa_free_dma(host->dma); pxa_free_dma(host->dma);
iounmap(host->base); 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