diff options
author | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
---|---|---|
committer | Denys Dmytriyenko <denis@denix.org> | 2009-03-17 14:32:59 -0400 |
commit | 709c4d66e0b107ca606941b988bad717c0b45d9b (patch) | |
tree | 37ee08b1eb308f3b2b6426d5793545c38396b838 /packages/linux/opensimpad/mmc-spi.patch | |
parent | fa6cd5a3b993f16c27de4ff82b42684516d433ba (diff) |
rename packages/ to recipes/ per earlier agreement
See links below for more details:
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326
http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816
Signed-off-by: Denys Dmytriyenko <denis@denix.org>
Acked-by: Mike Westerhof <mwester@dls.net>
Acked-by: Philip Balister <philip@balister.org>
Acked-by: Khem Raj <raj.khem@gmail.com>
Acked-by: Marcin Juszkiewicz <hrw@openembedded.org>
Acked-by: Koen Kooi <koen@openembedded.org>
Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'packages/linux/opensimpad/mmc-spi.patch')
-rw-r--r-- | packages/linux/opensimpad/mmc-spi.patch | 885 |
1 files changed, 0 insertions, 885 deletions
diff --git a/packages/linux/opensimpad/mmc-spi.patch b/packages/linux/opensimpad/mmc-spi.patch deleted file mode 100644 index 1841b45fbd..0000000000 --- a/packages/linux/opensimpad/mmc-spi.patch +++ /dev/null @@ -1,885 +0,0 @@ - -# -# Patch managed by http://www.holgerschurig.de/patcher.html -# - ---- /dev/null -+++ linux-2.4.27/drivers/block/mmc.c -@@ -0,0 +1,857 @@ -+/* -+ * Copyright (c) Clément Ballabriga, 2005 - GPL -+ * Copyright (c) Guylhem Aznar, 2005 - GPL -+ * -+ * Please check http://externe.net/zaurus/simpad-bluetooth reference design first. -+ * -+ * Based on Madsuk/Rohde work on a MMC driver for the WRT54G. -+ * -+ * This is an ugly hack of a driver. I am surprised if it ever works! -+ * So please use a real driver or contribute one to the 2.4/2.6 mmc framework -+ */ -+ -+#include <linux/stddef.h> -+#include <linux/delay.h> -+#include <linux/timer.h> -+#include <linux/module.h> -+#include <linux/mm.h> -+#include <linux/init.h> -+#include <linux/fs.h> -+#include <linux/blkpg.h> -+#include <linux/hdreg.h> -+#include <linux/major.h> -+ -+#include <asm/hardware.h> -+#include <asm/uaccess.h> -+#include <asm/io.h> -+ -+/* -+ * ******************************************************************* -+ * -+ * This is the only configurable part. -+ * -+ * ******************************************************************* -+ * -+ */ -+ -+// #define DEBUG 1 -+ -+#define DEVICE_NAME "mmc" -+#define DEVICE_NR(device) (MINOR(device)) -+#define DEVICE_ON(device) -+#define DEVICE_OFF(device) -+#define MAJOR_NR 121 -+ -+/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */ -+ -+#include <linux/blk.h> -+ -+MODULE_AUTHOR("Guylhem Aznar <mmc-driver @externe.net>"); -+MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode by GPIO"); -+MODULE_SUPPORTED_DEVICE("Simpad"); -+MODULE_LICENSE("GPL"); -+ -+/* Registers should be architecture independant - but it's not ! */ -+ -+#define MAP_START 0x90040000 -+#define MAP_SIZE 0x00001000 -+ -+#define MY_GPLR 0 -+#define MY_GPDR 1 -+#define MY_GPSR 2 -+#define MY_GPCR 3 -+#define MY_GRER 4 -+#define MY_GFER 5 -+#define MY_GEDR 6 -+#define MY_GAFR 7 -+ -+/* -+ * If you are using different GPIOs in your hardware hack, you must -+ * first make sure they are unused for other functions and then -+ * configure them here. -+ * -+ * On the simpad I use spare pins from the UART1 (internal serial port): -+ * - DCD (in) : GPIO 23 : DO -+ * - DTR (out) : GPIO 07 : CS -+ * - RI (in) : GPIO 19 : CLK -+ * - DSR (in) : GPIO 06 : DI -+ * -+ * Don't worry about in/out original function - the GPIOs will be -+ * reprogrammed. -+ */ -+ -+#define GPIO_SD_DO 23 -+#define GPIO_SD_CS 7 -+#define GPIO_SD_CLK 19 -+#define GPIO_SD_DI 6 -+ -+/* -+ * ******************************************************************* -+ * -+ * Do not change anything below ! -+ * -+ * ******************************************************************* -+ * -+ */ -+ -+ -+/* GPIO states */ -+#define LOW 0 -+#define HIGH 1 -+ -+#define INPUT 0 -+#define OUTPUT 1 -+ -+#define PRESENT 1 -+#define ABSENT 0 -+ -+typedef unsigned int uint32; -+typedef unsigned long u32_t; -+typedef unsigned short u16_t; -+typedef unsigned char u8_t; -+ -+/* we have only one device */ -+static int hd_sizes[1 << 6]; -+static int hd_blocksizes[1 << 6]; -+static int hd_hardsectsizes[1 << 6]; -+static int hd_maxsect[1 << 6]; -+static struct hd_struct hd[1 << 6]; -+ -+static struct timer_list mmc_timer; -+ -+/* start with no card */ -+static int mmc_media_detect = 0; -+static int mmc_media_changed = 1; -+ -+extern struct gendisk hd_gendisk; -+ -+/* Use only one global device */ -+typedef struct gpio_s gpio_t; -+struct gpio_s { -+ volatile u32_t *base; -+}; -+ -+static gpio_t gp = { -+ (void *) io_p2v(MAP_START) -+}; -+ -+/* -+ * ******************************************************************* -+ * -+ * Begin GPIO hardware access functions. -+ * -+ * ******************************************************************* -+ * -+ */ -+ -+gpio_t *gpio_open(void) -+{ -+ static gpio_t tmp; -+ tmp.base = (void *) io_p2v(MAP_START); -+ return (&tmp); -+} -+ -+void gpio_setdir(gpio_t * g, int num, int dir) -+{ -+ if (dir == 1) { -+ g->base[MY_GPDR] |= (1 << num); -+ } else { -+ g->base[MY_GPDR] &= ~(1 << num); -+ -+ } -+} -+ -+void gpio_setalt(gpio_t * g, int num, int alt) -+{ -+ if (alt == 1) { -+ g->base[MY_GAFR] |= (1 << num); -+ } else { -+ g->base[MY_GAFR] &= ~(1 << num); -+ } -+} -+ -+int gpio_getdir(gpio_t * g, int num) -+{ -+ return ((g->base[MY_GPDR] & (1 << num)) ? 1 : 0); -+} -+ -+int gpio_getalt(gpio_t * g, int num) -+{ -+ return ((g->base[MY_GAFR] & (1 << num)) ? 1 : 0); -+} -+ -+static int gpio_read(gpio_t * g, int num) -+{ -+ int what; -+ -+ what=(g->base[MY_GPLR] & (1 << num)) ? 1 : 0; -+ -+#ifdef DEBUG -+ if (num == GPIO_SD_DO) { -+ printk ("GPIO_SD_DO read: %u\n", what); -+ } -+#endif -+ return (what); -+} -+ -+static int gpio_write(gpio_t * g, int num, int val) -+{ -+#ifdef DEBUG -+ int check; -+#endif -+ -+ if (val == 1) { -+ g->base[MY_GPSR] = 1 << num; -+ } else { -+ g->base[MY_GPCR] = 1 << num; -+ } -+#ifdef DEBUG -+ check=gpio_read(g,num); -+ if (check != val) -+ { -+ printk ("Error while write to %d: found %d after writing %d\n",num, check, val); -+ return (1); -+ } -+ else return(0); -+#endif -+ -+} -+ -+/* -+ * ******************************************************************* -+ * -+ * Begin SPI hardware access functions. -+ * -+ * ******************************************************************* -+ * -+ */ -+static int mmc_spi_media_detect(void) -+{ -+// FIXME: add card detection/test by SPI -+ -+ return 1; -+} -+ -+static int mmc_spi_hardware_init(void) -+{ -+ /*unsigned char gpio_outen;*/ -+ -+ printk("mmc: GPIO init\n"); -+ -+ /* Now global -+ * gp = gpio_open(); */ -+ -+ /* Cut existing functions */ -+ gpio_setalt(&gp, GPIO_SD_CLK, 0); -+ gpio_setalt(&gp, GPIO_SD_DI, 0); -+ gpio_setalt(&gp, GPIO_SD_DO, 0); -+ gpio_setalt(&gp, GPIO_SD_CS, 0); -+ -+ /* Remap directions */ -+ gpio_setdir(&gp, GPIO_SD_CLK, OUTPUT); -+ gpio_setdir(&gp, GPIO_SD_DI, OUTPUT); -+ gpio_setdir(&gp, GPIO_SD_DO, INPUT); -+ gpio_setdir(&gp, GPIO_SD_CS, OUTPUT); -+ -+ printk("mmc: initialising MMC\n"); -+ -+ /* Start */ -+ gpio_write(&gp, GPIO_SD_CLK, LOW); -+ gpio_write(&gp, GPIO_SD_DI, LOW); -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ return 0; -+} -+ -+/* return what has been read, write the parameter */ -+ -+static unsigned char mmc_spi_readwrite(unsigned char data_out) -+{ -+ int i; -+ unsigned char result = 0/*, tmp_data = 0*/; -+ -+ for (i = 0; i < 8; i++) { -+ if (data_out & (0x01 << (7 - i))) -+ gpio_write(&gp, GPIO_SD_DI, HIGH); -+ else -+ gpio_write(&gp, GPIO_SD_DI, LOW); -+ -+ gpio_write(&gp, GPIO_SD_CLK, HIGH); -+ -+ result <<= 1; -+ -+ if (gpio_read(&gp, GPIO_SD_DO) == 1) -+ result |= 1; -+ -+ gpio_write(&gp, GPIO_SD_CLK, LOW); -+ } -+ -+ return (result); -+} -+ -+static int mmc_spi_card_init(void) -+{ -+ unsigned char result = 0; -+ short i, j; -+ unsigned long flags; -+ -+ save_flags(flags); -+ cli(); -+ -+ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS)); -+ printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI)); -+ printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO)); -+ printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK)); -+ -+ printk("mmc: card init 1/2\n"); -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ for (i = 0; i < 20; i++) -+ mmc_spi_readwrite(0xff); -+ -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ -+ mmc_spi_readwrite(0x40); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0x00); -+ mmc_spi_readwrite(0x95); -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0x01) -+ break; -+ } -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ if (result != 0x01) { -+ printk("mmc: card init %d error\n", result); -+ restore_flags(flags); -+ return (1); -+ } -+ -+ printk("mmc: card init 2/2\n"); -+ for (j = 0; j < 10000; j++) { -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ -+ mmc_spi_readwrite(0x41); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0x00); -+ mmc_spi_readwrite(0xff); -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0x00) -+ break; -+ } -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ if (result == 0x00) { -+ restore_flags(flags); -+ printk("mmc: card init 3/3\n"); -+ return (0); -+ } -+ } -+ restore_flags(flags); -+ -+ return (2); -+} -+ -+ -+static int mmc_spi_card_config(void) -+{ -+ unsigned char result = 0; -+ short i; -+ unsigned char csd[32]; -+ unsigned int c_size; -+ unsigned int c_size_mult; -+ unsigned int mult; -+ unsigned int read_bl_len; -+ unsigned int blocknr = 0; -+ unsigned int block_len = 0; -+ unsigned int size = 0; -+ -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0xff); -+ mmc_spi_readwrite(0x49); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0x00); -+ mmc_spi_readwrite(0xff); -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0x00) -+ break; -+ } -+ if (result != 0x00) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (1); -+ } -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0xfe) -+ break; -+ } -+ if (result != 0xfe) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (2); -+ } -+ for (i = 0; i < 16; i++) { -+ result = mmc_spi_readwrite(0xff); -+ csd[i] = result; -+ } -+ for (i = 0; i < 2; i++) { -+ result = mmc_spi_readwrite(0xff); -+ } -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ if (result == 0x00) -+ return (3); -+ -+ c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256; -+ c_size >>= 6; -+ c_size_mult = csd[10] + (csd[9] & 0x03) * 256; -+ c_size_mult >>= 7; -+ read_bl_len = csd[5] & 0x0f; -+ mult = 1; -+ mult <<= c_size_mult + 2; -+ blocknr = (c_size + 1) * mult; -+ block_len = 1; -+ block_len <<= read_bl_len; -+ size = block_len * blocknr; -+ size >>= 10; -+ -+ for (i = 0; i < (1 << 6); i++) { -+ hd_blocksizes[i] = 1024; -+ hd_hardsectsizes[i] = block_len; -+ hd_maxsect[i] = 256; -+ } -+ hd_sizes[0] = size; -+ hd[0].nr_sects = blocknr; -+ -+ -+ printk("Size = %d, hardsectsize = %d, sectors = %d\n", -+ size, block_len, blocknr); -+ -+ return 0; -+} -+ -+ -+/* -+ * ******************************************************************* -+ * -+ * End of SPI hardware access functions. -+ * -+ * ******************************************************************* -+ */ -+ -+ -+static int mmc_write_block(unsigned int dest_addr, unsigned char *data) -+{ -+ unsigned int address; -+ unsigned char result = 0; -+ unsigned char ab0, ab1, ab2, ab3; -+ int i; -+ -+ address = dest_addr; -+ -+ ab3 = 0xff & (address >> 24); -+ ab2 = 0xff & (address >> 16); -+ ab1 = 0xff & (address >> 8); -+ ab0 = 0xff & address; -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0xff); -+ mmc_spi_readwrite(0x58); -+ mmc_spi_readwrite(ab3); /* msb */ -+ mmc_spi_readwrite(ab2); -+ mmc_spi_readwrite(ab1); -+ mmc_spi_readwrite(ab0); /* lsb */ -+ mmc_spi_readwrite(0xff); -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0x00) -+ break; -+ } -+ if (result != 0x00) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (1); -+ } -+ -+ mmc_spi_readwrite(0xfe); -+ for (i = 0; i < 512; i++) -+ mmc_spi_readwrite(data[i]); -+ for (i = 0; i < 2; i++) -+ mmc_spi_readwrite(0xff); -+ -+ for (i = 0; i < 1000000; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0xff) -+ break; -+ } -+ if (result != 0xff) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (3); -+ } -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (0); -+} -+ -+static int mmc_read_block(unsigned char *data, unsigned int src_addr) -+{ -+ unsigned int address; -+ unsigned char result = 0; -+ unsigned char ab0, ab1, ab2, ab3; -+ int i; -+ -+ address = src_addr; -+ -+ ab3 = 0xff & (address >> 24); -+ ab2 = 0xff & (address >> 16); -+ ab1 = 0xff & (address >> 8); -+ ab0 = 0xff & address; -+ -+ gpio_write(&gp, GPIO_SD_CS, LOW); -+ for (i = 0; i < 4; i++) -+ mmc_spi_readwrite(0xff); -+ mmc_spi_readwrite(0x51); -+ mmc_spi_readwrite(ab3); /* msb */ -+ mmc_spi_readwrite(ab2); -+ mmc_spi_readwrite(ab1); -+ mmc_spi_readwrite(ab0); /* lsb */ -+ -+ mmc_spi_readwrite(0xff); -+ for (i = 0; i < 8; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0x00) -+ break; -+ } -+ if (result != 0x00) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (1); -+ } -+ for (i = 0; i < 100000; i++) { -+ result = mmc_spi_readwrite(0xff); -+ if (result == 0xfe) -+ break; -+ } -+ if (result != 0xfe) { -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ return (2); -+ } -+ for (i = 0; i < 512; i++) { -+ result = mmc_spi_readwrite(0xff); -+ data[i] = result; -+ } -+ for (i = 0; i < 2; i++) { -+ result = mmc_spi_readwrite(0xff); -+ } -+ gpio_write(&gp, GPIO_SD_CS, HIGH); -+ mmc_spi_readwrite(0xff); -+ -+ return (0); -+} -+ -+static void mmc_request(request_queue_t * q) -+{ -+ unsigned int mmc_address; -+ unsigned char *buffer_address; -+ int nr_sectors; -+ int i; -+ int cmd; -+ int result, code; -+ -+ (void) q; -+ while (1) { -+ code = 1; // Default is success -+ INIT_REQUEST; -+ mmc_address = -+ (CURRENT->sector + -+ hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0]; -+ buffer_address = CURRENT->buffer; -+ nr_sectors = CURRENT->current_nr_sectors; -+ cmd = CURRENT->cmd; -+ if (((CURRENT->sector + CURRENT->current_nr_sectors + -+ hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects) -+ || (mmc_media_detect == 0)) { -+ code = 0; -+ } else if (cmd == READ) { -+ spin_unlock_irq(&io_request_lock); -+ for (i = 0; i < nr_sectors; i++) { -+ result = mmc_read_block(buffer_address, mmc_address); -+ if (result != 0) { -+ printk("mmc: error %d in mmc_read_block\n", result); -+ code = 0; -+ break; -+ } else { -+ mmc_address += hd_hardsectsizes[0]; -+ buffer_address += hd_hardsectsizes[0]; -+ } -+ } -+ spin_lock_irq(&io_request_lock); -+ } else if (cmd == WRITE) { -+ spin_unlock_irq(&io_request_lock); -+ for (i = 0; i < nr_sectors; i++) { -+ result = mmc_write_block(mmc_address, buffer_address); -+ if (result != 0) { -+ printk("mmc: error %d in mmc_write_block\n", result); -+ code = 0; -+ break; -+ } else { -+ mmc_address += hd_hardsectsizes[0]; -+ buffer_address += hd_hardsectsizes[0]; -+ } -+ } -+ spin_lock_irq(&io_request_lock); -+ } else { -+ code = 0; -+ } -+ end_request(code); -+ } -+} -+ -+ -+static int mmc_open(struct inode *inode, struct file *filp) -+{ -+ /*int device;*/ -+ (void) filp; -+ mmc_media_detect = mmc_spi_media_detect(); -+ -+ if (mmc_media_detect == 0) -+ return -ENODEV; -+ -+#if defined(MODULE) -+ MOD_INC_USE_COUNT; -+#endif -+ return 0; -+} -+ -+static int mmc_release(struct inode *inode, struct file *filp) -+{ -+ (void) filp; -+ fsync_dev(inode->i_rdev); -+ invalidate_buffers(inode->i_rdev); -+ -+#if defined(MODULE) -+ MOD_DEC_USE_COUNT; -+#endif -+ return 0; -+} -+ -+static int mmc_revalidate(kdev_t dev) -+{ -+ int target, max_p, start, i; -+ -+ mmc_media_detect = mmc_spi_media_detect(); -+ -+ if (mmc_media_detect == 0) -+ return -ENODEV; -+ -+ target = DEVICE_NR(dev); -+ -+ max_p = hd_gendisk.max_p; -+ start = target << 6; -+ for (i = max_p - 1; i >= 0; i--) { -+ int minor = start + i; -+ invalidate_device(MKDEV(MAJOR_NR, minor), 1); -+ hd_gendisk.part[minor].start_sect = 0; -+ hd_gendisk.part[minor].nr_sects = 0; -+ } -+ -+ grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2); -+ -+ return 0; -+} -+ -+static int mmc_ioctl(struct inode *inode, struct file *filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ if (!inode || !inode->i_rdev) -+ return -EINVAL; -+ -+ switch (cmd) { -+ case BLKGETSIZE: -+ return put_user(hd[MINOR(inode->i_rdev)].nr_sects, -+ (unsigned long *) arg); -+ case BLKGETSIZE64: -+ return put_user((u64) hd[MINOR(inode->i_rdev)]. -+ nr_sects, (u64 *) arg); -+ case BLKRRPART: -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ return mmc_revalidate(inode->i_rdev); -+ case HDIO_GETGEO: -+ { -+ struct hd_geometry *loc, g; -+ loc = (struct hd_geometry *) arg; -+ if (!loc) -+ return -EINVAL; -+ g.heads = 4; -+ g.sectors = 16; -+ g.cylinders = hd[0].nr_sects / (4 * 16); -+ g.start = hd[MINOR(inode->i_rdev)].start_sect; -+ return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0; -+ } -+ default: -+ return blk_ioctl(inode->i_rdev, cmd, arg); -+ } -+} -+ -+ -+/* -+static int mmc_check_media_change(kdev_t dev) -+{ -+ (void) dev; -+ if (mmc_media_changed == 1) { -+ mmc_media_changed = 0; -+ return 1; -+ } else -+ return 0; -+} -+*/ -+ -+static struct block_device_operations mmc_bdops = { -+ open:mmc_open, -+ release:mmc_release, -+ ioctl:mmc_ioctl, -+/* FIXME: add media change support -+ * check_media_change: mmc_check_media_change, -+ * revalidate: mmc_revalidate, -+ */ -+}; -+ -+static struct gendisk hd_gendisk = { -+ major:MAJOR_NR, -+ major_name:DEVICE_NAME, -+ minor_shift:6, -+ max_p:1 << 6, -+ part:hd, -+ sizes:hd_sizes, -+ fops:&mmc_bdops, -+}; -+ -+static int mmc_init(void) -+{ -+ int result; -+ -+ result = mmc_spi_hardware_init(); -+ -+ if (result != 0) { -+ printk("mmc: error %d in mmc_spi_hardware_init\n", result); -+ return -1; -+ } -+ -+ result = mmc_spi_card_init(); -+ if (result != 0) { -+ // Give it an extra shot -+ result = mmc_spi_card_init(); -+ if (result != 0) { -+ printk("mmc: error %d in mmc_card_init\n", result); -+ return -1; -+ } -+ } -+ -+ memset(hd_sizes, 0, sizeof(hd_sizes)); -+ result = mmc_spi_card_config(); -+ if (result != 0) { -+ printk("mmc: error %d in mmc_card_config\n", result); -+ return -1; -+ } -+ -+ -+ blk_size[MAJOR_NR] = hd_sizes; -+ -+ memset(hd, 0, sizeof(hd)); -+ hd[0].nr_sects = hd_sizes[0] * 2; -+ -+ blksize_size[MAJOR_NR] = hd_blocksizes; -+ hardsect_size[MAJOR_NR] = hd_hardsectsizes; -+ max_sectors[MAJOR_NR] = hd_maxsect; -+ -+ hd_gendisk.nr_real = 1; -+ -+ register_disk(&hd_gendisk, MKDEV(MAJOR_NR, 0), 1 << 6, -+ &mmc_bdops, hd_sizes[0] * 2); -+ -+ return 0; -+} -+ -+static void mmc_exit(void) -+{ -+ blk_size[MAJOR_NR] = NULL; -+ blksize_size[MAJOR_NR] = NULL; -+ hardsect_size[MAJOR_NR] = NULL; -+ max_sectors[MAJOR_NR] = NULL; -+ hd[0].nr_sects = 0; -+} -+ -+static void mmc_check_media(void) -+{ -+ int old_state, new_state; -+ int result; -+ -+ old_state = mmc_media_detect; -+ new_state = mmc_spi_media_detect(); -+ -+ if (old_state != new_state) { -+ mmc_media_changed = 1; -+ if (new_state == PRESENT) { -+ result = mmc_init(); -+ if (result != 0) -+ printk("mmc: error %d in mmc_init\n", result); -+ } else { -+ mmc_exit(); -+ } -+ } -+ -+ /* del_timer(&mmc_timer); -+ mmc_timer.expires = jiffies + 10*HZ; -+ add_timer(&mmc_timer); */ -+} -+ -+static int __init mmc_driver_init(void) -+{ -+ int result; -+ -+ result = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops); -+ if (result < 0) { -+ printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR); -+ return result; -+ } -+ -+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request); -+ -+ mmc_check_media(); -+ -+ /*init_timer(&mmc_timer); -+ mmc_timer.expires = jiffies + HZ; -+ mmc_timer.function = (void *)mmc_check_media; -+ add_timer(&mmc_timer); */ -+ -+ -+ read_ahead[MAJOR_NR] = 8; -+ add_gendisk(&hd_gendisk); -+ -+ -+ return 0; -+} -+ -+static void __exit mmc_driver_exit(void) -+{ -+ int i; -+ del_timer(&mmc_timer); -+ -+ for (i = 0; i < (1 << 6); i++) -+ fsync_dev(MKDEV(MAJOR_NR, i)); -+ -+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); -+ del_gendisk(&hd_gendisk); -+ devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME); -+ mmc_exit(); -+} -+ -+module_init(mmc_driver_init); -+module_exit(mmc_driver_exit); ---- linux-2.4.27/drivers/block/Config.in~mmc-spi -+++ linux-2.4.27/drivers/block/Config.in -@@ -4,6 +4,7 @@ - mainmenu_option next_comment - comment 'Block devices' - -+tristate 'MMC SPI driver' CONFIG_BLK_DEV_MMC - tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD - if [ "$CONFIG_AMIGA" = "y" ]; then - tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY ---- linux-2.4.27/drivers/block/Makefile~mmc-spi -+++ linux-2.4.27/drivers/block/Makefile -@@ -15,6 +15,7 @@ - obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o - - obj-$(CONFIG_MAC_FLOPPY) += swim3.o -+obj-$(CONFIG_BLK_DEV_MMC) += mmc.o - obj-$(CONFIG_BLK_DEV_FD) += floppy.o - obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o - obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o |