diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/cmx270_nand.c | 79 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_cm_x270.c | 93 |
2 files changed, 74 insertions, 98 deletions
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index cb663ef245d..fc8529bedfd 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c @@ -20,9 +20,11 @@ #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> +#include <linux/gpio.h> #include <asm/io.h> #include <asm/irq.h> +#include <asm/mach-types.h> #include <asm/arch/hardware.h> #include <asm/arch/pxa-regs.h> @@ -30,20 +32,6 @@ #define GPIO_NAND_CS (11) #define GPIO_NAND_RB (89) -/* This macro needed to ensure in-order operation of GPIO and local - * bus. Without both asm command and dummy uncached read there're - * states when NAND access is broken. I've looked for such macro(s) in - * include/asm-arm but found nothing approptiate. - * dmac_clean_range is close, but is makes cache invalidation - * unnecessary here and it cannot be used in module - */ -#define DRAIN_WB() \ - do { \ - unsigned char dummy; \ - asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \ - dummy=*((unsigned char*)UNCACHED_ADDR); \ - } while(0) - /* MTD structure for CM-X270 board */ static struct mtd_info *cmx270_nand_mtd; @@ -103,14 +91,14 @@ static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) static inline void nand_cs_on(void) { - GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); + gpio_set_value(GPIO_NAND_CS, 0); } static void nand_cs_off(void) { - DRAIN_WB(); + dsb(); - GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); + gpio_set_value(GPIO_NAND_CS, 1); } /* @@ -122,7 +110,7 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, struct nand_chip* this = mtd->priv; unsigned int nandaddr = (unsigned int)this->IO_ADDR_W; - DRAIN_WB(); + dsb(); if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_ALE ) @@ -139,12 +127,12 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, nand_cs_off(); } - DRAIN_WB(); + dsb(); this->IO_ADDR_W = (void __iomem*)nandaddr; if (dat != NAND_CMD_NONE) writel((dat << 16), this->IO_ADDR_W); - DRAIN_WB(); + dsb(); } /* @@ -152,9 +140,9 @@ static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, */ static int cmx270_device_ready(struct mtd_info *mtd) { - DRAIN_WB(); + dsb(); - return (GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB)); + return (gpio_get_value(GPIO_NAND_RB)); } /* @@ -168,20 +156,40 @@ static int cmx270_init(void) int mtd_parts_nb = 0; int ret; + if (!machine_is_armcore()) + return -ENODEV; + + ret = gpio_request(GPIO_NAND_CS, "NAND CS"); + if (ret) { + pr_warning("CM-X270: failed to request NAND CS gpio\n"); + return ret; + } + + gpio_direction_output(GPIO_NAND_CS, 1); + + ret = gpio_request(GPIO_NAND_RB, "NAND R/B"); + if (ret) { + pr_warning("CM-X270: failed to request NAND R/B gpio\n"); + goto err_gpio_request; + } + + gpio_direction_input(GPIO_NAND_RB); + /* Allocate memory for MTD device structure and private data */ cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); if (!cmx270_nand_mtd) { - printk("Unable to allocate CM-X270 NAND MTD device structure.\n"); - return -ENOMEM; + pr_debug("Unable to allocate CM-X270 NAND MTD device structure.\n"); + ret = -ENOMEM; + goto err_kzalloc; } cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12); if (!cmx270_nand_io) { - printk("Unable to ioremap NAND device\n"); + pr_debug("Unable to ioremap NAND device\n"); ret = -EINVAL; - goto err1; + goto err_ioremap; } /* Get pointer to private data */ @@ -209,9 +217,9 @@ static int cmx270_init(void) /* Scan to find existence of the device */ if (nand_scan (cmx270_nand_mtd, 1)) { - printk(KERN_NOTICE "No NAND device\n"); + pr_notice("No NAND device\n"); ret = -ENXIO; - goto err2; + goto err_scan; } #ifdef CONFIG_MTD_CMDLINE_PARTS @@ -229,18 +237,22 @@ static int cmx270_init(void) } /* Register the partitions */ - printk(KERN_NOTICE "Using %s partition definition\n", part_type); + pr_notice("Using %s partition definition\n", part_type); ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); if (ret) - goto err2; + goto err_scan; /* Return happy */ return 0; -err2: +err_scan: iounmap(cmx270_nand_io); -err1: +err_ioremap: kfree(cmx270_nand_mtd); +err_kzalloc: + gpio_free(GPIO_NAND_RB); +err_gpio_request: + gpio_free(GPIO_NAND_CS); return ret; @@ -255,6 +267,9 @@ static void cmx270_cleanup(void) /* Release resources, unregister device */ nand_release(cmx270_nand_mtd); + gpio_free(GPIO_NAND_RB); + gpio_free(GPIO_NAND_CS); + iounmap(cmx270_nand_io); /* Free the MTD device structure */ diff --git a/drivers/pcmcia/pxa2xx_cm_x270.c b/drivers/pcmcia/pxa2xx_cm_x270.c index f123fce65f2..bb95db7d2b7 100644 --- a/drivers/pcmcia/pxa2xx_cm_x270.c +++ b/drivers/pcmcia/pxa2xx_cm_x270.c @@ -5,83 +5,60 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Compulab Ltd., 2003, 2007 + * Compulab Ltd., 2003, 2007, 2008 * Mike Rapoport <mike@compulab.co.il> * */ -#include <linux/kernel.h> -#include <linux/sched.h> #include <linux/platform_device.h> #include <linux/irq.h> #include <linux/delay.h> +#include <linux/gpio.h> -#include <pcmcia/ss.h> -#include <asm/hardware.h> #include <asm/mach-types.h> - #include <asm/arch/pxa-regs.h> -#include <asm/arch/pxa2xx-gpio.h> -#include <asm/arch/cm-x270.h> #include "soc_common.h" +#define GPIO_PCMCIA_S0_CD_VALID (84) +#define GPIO_PCMCIA_S0_RDYINT (82) +#define GPIO_PCMCIA_RESET (53) + +#define PCMCIA_S0_CD_VALID IRQ_GPIO(GPIO_PCMCIA_S0_CD_VALID) +#define PCMCIA_S0_RDYINT IRQ_GPIO(GPIO_PCMCIA_S0_RDYINT) + + static struct pcmcia_irqs irqs[] = { { 0, PCMCIA_S0_CD_VALID, "PCMCIA0 CD" }, - { 1, PCMCIA_S1_CD_VALID, "PCMCIA1 CD" }, }; static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) { - GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | - GPIO_bit(GPIO49_nPWE) | - GPIO_bit(GPIO50_nPIOR) | - GPIO_bit(GPIO51_nPIOW) | - GPIO_bit(GPIO85_nPCE_1) | - GPIO_bit(GPIO54_nPCE_2); - - pxa_gpio_mode(GPIO48_nPOE_MD); - pxa_gpio_mode(GPIO49_nPWE_MD); - pxa_gpio_mode(GPIO50_nPIOR_MD); - pxa_gpio_mode(GPIO51_nPIOW_MD); - pxa_gpio_mode(GPIO85_nPCE_1_MD); - pxa_gpio_mode(GPIO54_nPCE_2_MD); - pxa_gpio_mode(GPIO55_nPREG_MD); - pxa_gpio_mode(GPIO56_nPWAIT_MD); - pxa_gpio_mode(GPIO57_nIOIS16_MD); - - /* Reset signal */ - pxa_gpio_mode(GPIO53_nPCE_2 | GPIO_OUT); - GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); - - set_irq_type(PCMCIA_S0_CD_VALID, IRQ_TYPE_EDGE_BOTH); - set_irq_type(PCMCIA_S1_CD_VALID, IRQ_TYPE_EDGE_BOTH); - - /* irq's for slots: */ - set_irq_type(PCMCIA_S0_RDYINT, IRQ_TYPE_EDGE_FALLING); - set_irq_type(PCMCIA_S1_RDYINT, IRQ_TYPE_EDGE_FALLING); - - skt->irq = (skt->nr == 0) ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT; - return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + int ret = gpio_request(GPIO_PCMCIA_RESET, "PCCard reset"); + if (ret) + return ret; + gpio_direction_output(GPIO_PCMCIA_RESET, 0); + + skt->irq = PCMCIA_S0_RDYINT; + ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); + if (!ret) + gpio_free(GPIO_PCMCIA_RESET); + + return ret; } static void cmx270_pcmcia_shutdown(struct soc_pcmcia_socket *skt) { soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); - - set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_CD_VALID), IRQ_TYPE_NONE); - set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_CD_VALID), IRQ_TYPE_NONE); - - set_irq_type(IRQ_TO_GPIO(PCMCIA_S0_RDYINT), IRQ_TYPE_NONE); - set_irq_type(IRQ_TO_GPIO(PCMCIA_S1_RDYINT), IRQ_TYPE_NONE); + gpio_free(GPIO_PCMCIA_RESET); } static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) { - state->detect = (PCC_DETECT(skt->nr) == 0) ? 1 : 0; - state->ready = (PCC_READY(skt->nr) == 0) ? 0 : 1; + state->detect = (gpio_get_value(GPIO_PCMCIA_S0_CD_VALID) == 0) ? 1 : 0; + state->ready = (gpio_get_value(GPIO_PCMCIA_S0_RDYINT) == 0) ? 0 : 1; state->bvd1 = 1; state->bvd2 = 1; state->vs_3v = 0; @@ -93,32 +70,16 @@ static void cmx270_pcmcia_socket_state(struct soc_pcmcia_socket *skt, static int cmx270_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) { - GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); - pxa_gpio_mode(GPIO49_nPWE | GPIO_OUT); - switch (skt->nr) { case 0: if (state->flags & SS_RESET) { - GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); - GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); - udelay(10); - GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); - GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); - } - break; - case 1: - if (state->flags & SS_RESET) { - GPCR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); - GPSR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); + gpio_set_value(GPIO_PCMCIA_RESET, 1); udelay(10); - GPCR(GPIO53_nPCE_2) = GPIO_bit(GPIO53_nPCE_2); - GPSR(GPIO49_nPWE) = GPIO_bit(GPIO49_nPWE); + gpio_set_value(GPIO_PCMCIA_RESET, 0); } break; } - pxa_gpio_mode(GPIO49_nPWE_MD); - return 0; } @@ -139,7 +100,7 @@ static struct pcmcia_low_level cmx270_pcmcia_ops __initdata = { .configure_socket = cmx270_pcmcia_configure_socket, .socket_init = cmx270_pcmcia_socket_init, .socket_suspend = cmx270_pcmcia_socket_suspend, - .nr = 2, + .nr = 1, }; static struct platform_device *cmx270_pcmcia_device; |