From 1d10dcd041aaeae9fd7c821005692898a0303382 Mon Sep 17 00:00:00 2001 From: "Hunter, Jon" Date: Sat, 26 Jul 2008 18:59:16 -0500 Subject: Add support for OMAP5912 and OMAP16xx to usbdcore_omap1510.c Add support to drivers/usb/usbdcore_omap1510.c for OMAP5912 and OMAP16xx devices. Signed-off-by: Jon Hunter Signed-off-by: Markus Klotzbuecher --- drivers/usb/usbdcore_omap1510.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c index 84bb936d869..4e3239f5809 100644 --- a/drivers/usb/usbdcore_omap1510.c +++ b/drivers/usb/usbdcore_omap1510.c @@ -28,7 +28,7 @@ #include -#if defined(CONFIG_OMAP1510) && defined(CONFIG_USB_DEVICE) +#if ((defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610)) && defined(CONFIG_USB_DEVICE)) #include #ifdef CONFIG_OMAP_SX1 @@ -1109,21 +1109,43 @@ int udc_init (void) */ outw ((1 << 4) | (1 << 5), CLOCK_CTRL); UDCREG (CLOCK_CTRL); + +#ifdef CONFIG_OMAP1510 + /* This code was originally implemented for OMAP1510 and + * therefore is only applicable for OMAP1510 boards. For + * OMAP5912 or OMAP16xx the register APLL_CTRL does not + * exist and DPLL_CTRL is already configured. + */ + /* Set and check APLL */ outw (0x0008, APLL_CTRL); UDCREG (APLL_CTRL); /* Set and check DPLL */ outw (0x2210, DPLL_CTRL); UDCREG (DPLL_CTRL); - /* Set and check SOFT */ - outw ((1 << 4) | (1 << 3) | 1, SOFT_REQ); +#endif + /* Set and check SOFT + * The below line of code has been changed to perform a + * read-modify-write instead of a simple write for + * configuring the SOFT_REQ register. This allows the code + * to be compatible with OMAP5912 and OMAP16xx devices + */ + outw ((1 << 4) | (1 << 3) | 1 | (inw(SOFT_REQ)), SOFT_REQ); + /* Short delay to wait for DPLL */ udelay (1000); /* Print banner with device revision */ udc_rev = inw (UDC_REV) & 0xff; +#ifdef CONFIG_OMAP1510 printf ("USB: TI OMAP1510 USB function module rev %d.%d\n", udc_rev >> 4, udc_rev & 0xf); +#endif + +#ifdef CONFIG_OMAP1610 + printf ("USB: TI OMAP5912 USB function module rev %d.%d\n", + udc_rev >> 4, udc_rev & 0xf); +#endif #ifdef CONFIG_OMAP_SX1 i2c_read (0x32, 0x04, 1, &value, 1); -- cgit v1.3.1 From fd0f2f3796ff2a7a32d35deb1b7996e485849df7 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Wed, 9 Jul 2008 21:07:38 +0900 Subject: usb: add support for R8A66597 usb controller add support for Renesas R8A66597 usb controller. This patch supports USB Host mode. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Markus Klotzbuecher --- drivers/usb/Makefile | 1 + drivers/usb/r8a66597-hcd.c | 924 +++++++++++++++++++++++++++++++++++++++++++++ drivers/usb/r8a66597.h | 663 ++++++++++++++++++++++++++++++++ include/usb.h | 2 +- 4 files changed, 1589 insertions(+), 1 deletion(-) create mode 100644 drivers/usb/r8a66597-hcd.c create mode 100644 drivers/usb/r8a66597.h (limited to 'drivers') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 252b00e6527..2bdbb59cd56 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libusb.a COBJS-y += isp116x-hcd.o COBJS-y += sl811_usb.o COBJS-y += usb_ohci.o +COBJS-y += r8a66597-hcd.o COBJS-y += usbdcore.o COBJS-y += usbdcore_ep0.o COBJS-y += usbdcore_mpc8xx.o diff --git a/drivers/usb/r8a66597-hcd.c b/drivers/usb/r8a66597-hcd.c new file mode 100644 index 00000000000..3eb4cb03f08 --- /dev/null +++ b/drivers/usb/r8a66597-hcd.c @@ -0,0 +1,924 @@ +/* + * R8A66597 HCD (Host Controller Driver) for u-boot + * + * Copyright (C) 2008 Yoshihiro Shimoda + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include + +#include "r8a66597.h" + +#if defined(CONFIG_USB_R8A66597_HCD) + +#ifdef R8A66597_DEBUG +#define R8A66597_DPRINT printf +#else +#define R8A66597_DPRINT(...) +#endif + +static const char hcd_name[] = "r8a66597_hcd"; +static unsigned short clock = CONFIG_R8A66597_XTAL; +static unsigned short vif = CONFIG_R8A66597_LDRV; +static unsigned short endian = CONFIG_R8A66597_ENDIAN; +static struct r8a66597 gr8a66597; + +static void set_devadd_reg(struct r8a66597 *r8a66597, u8 r8a66597_address, + u16 usbspd, u8 upphub, u8 hubport, int port) +{ + u16 val; + unsigned long devadd_reg = get_devadd_addr(r8a66597_address); + + val = (upphub << 11) | (hubport << 8) | (usbspd << 6) | (port & 0x0001); + r8a66597_write(r8a66597, val, devadd_reg); +} + +static int r8a66597_clock_enable(struct r8a66597 *r8a66597) +{ + u16 tmp; + int i = 0; + +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + do { + r8a66597_write(r8a66597, SCKE, SYSCFG0); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 1000) { + printf("register access fail.\n"); + return -1; + } + } while ((tmp & SCKE) != SCKE); + r8a66597_write(r8a66597, 0x04, 0x02); +#else + do { + r8a66597_write(r8a66597, USBE, SYSCFG0); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 1000) { + printf("register access fail.\n"); + return -1; + } + } while ((tmp & USBE) != USBE); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); + r8a66597_mdfy(r8a66597, clock, XTAL, SYSCFG0); + + i = 0; + r8a66597_bset(r8a66597, XCKE, SYSCFG0); + do { + udelay(1000); + tmp = r8a66597_read(r8a66597, SYSCFG0); + if (i++ > 500) { + printf("register access fail.\n"); + return -1; + } + } while ((tmp & SCKE) != SCKE); +#endif /* #if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) */ + + return 0; +} + +static void r8a66597_clock_disable(struct r8a66597 *r8a66597) +{ + r8a66597_bclr(r8a66597, SCKE, SYSCFG0); + udelay(1); +#if !defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + r8a66597_bclr(r8a66597, PLLC, SYSCFG0); + r8a66597_bclr(r8a66597, XCKE, SYSCFG0); + r8a66597_bclr(r8a66597, USBE, SYSCFG0); +#endif +} + +static void r8a66597_enable_port(struct r8a66597 *r8a66597, int port) +{ + u16 val; + + val = port ? DRPD : DCFM | DRPD; + r8a66597_bset(r8a66597, val, get_syscfg_reg(port)); + r8a66597_bset(r8a66597, HSE, get_syscfg_reg(port)); + + r8a66597_write(r8a66597, BURST | CPU_ADR_RD_WR, get_dmacfg_reg(port)); +} + +static void r8a66597_disable_port(struct r8a66597 *r8a66597, int port) +{ + u16 val, tmp; + + r8a66597_write(r8a66597, 0, get_intenb_reg(port)); + r8a66597_write(r8a66597, 0, get_intsts_reg(port)); + + r8a66597_port_power(r8a66597, port, 0); + + do { + tmp = r8a66597_read(r8a66597, SOFCFG) & EDGESTS; + udelay(640); + } while (tmp == EDGESTS); + + val = port ? DRPD : DCFM | DRPD; + r8a66597_bclr(r8a66597, val, get_syscfg_reg(port)); + r8a66597_bclr(r8a66597, HSE, get_syscfg_reg(port)); +} + +static int enable_controller(struct r8a66597 *r8a66597) +{ + int ret, port; + + ret = r8a66597_clock_enable(r8a66597); + if (ret < 0) + return ret; + + r8a66597_bset(r8a66597, vif & LDRV, PINCFG); + r8a66597_bset(r8a66597, USBE, SYSCFG0); + + r8a66597_bset(r8a66597, INTL, SOFCFG); + r8a66597_write(r8a66597, 0, INTENB0); + r8a66597_write(r8a66597, 0, INTENB1); + r8a66597_write(r8a66597, 0, INTENB2); + + r8a66597_bset(r8a66597, endian & BIGEND, CFIFOSEL); + r8a66597_bset(r8a66597, endian & BIGEND, D0FIFOSEL); + r8a66597_bset(r8a66597, endian & BIGEND, D1FIFOSEL); + r8a66597_bset(r8a66597, TRNENSEL, SOFCFG); + + for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) + r8a66597_enable_port(r8a66597, port); + + return 0; +} + +static void disable_controller(struct r8a66597 *r8a66597) +{ + int i; + + if (!(r8a66597_read(r8a66597, SYSCFG0) & USBE)) + return; + + r8a66597_write(r8a66597, 0, INTENB0); + r8a66597_write(r8a66597, 0, INTSTS0); + + r8a66597_write(r8a66597, 0, D0FIFOSEL); + r8a66597_write(r8a66597, 0, D1FIFOSEL); + r8a66597_write(r8a66597, 0, DCPCFG); + r8a66597_write(r8a66597, 0x40, DCPMAXP); + r8a66597_write(r8a66597, 0, DCPCTR); + + for (i = 0; i <= 10; i++) + r8a66597_write(r8a66597, 0, get_devadd_addr(i)); + for (i = 1; i <= 5; i++) { + r8a66597_write(r8a66597, 0, get_pipetre_addr(i)); + r8a66597_write(r8a66597, 0, get_pipetrn_addr(i)); + } + for (i = 1; i < R8A66597_MAX_NUM_PIPE; i++) { + r8a66597_write(r8a66597, 0, get_pipectr_addr(i)); + r8a66597_write(r8a66597, i, PIPESEL); + r8a66597_write(r8a66597, 0, PIPECFG); + r8a66597_write(r8a66597, 0, PIPEBUF); + r8a66597_write(r8a66597, 0, PIPEMAXP); + r8a66597_write(r8a66597, 0, PIPEPERI); + } + + for (i = 0; i < R8A66597_MAX_ROOT_HUB; i++) + r8a66597_disable_port(r8a66597, i); + + r8a66597_clock_disable(r8a66597); +} + +static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg, + u16 mask, u16 loop) +{ + u16 tmp; + int i = 0; + + do { + tmp = r8a66597_read(r8a66597, reg); + if (i++ > 1000000) { + printf("register%lx, loop %x is timeout\n", reg, loop); + break; + } + } while ((tmp & mask) != loop); +} + +static void pipe_buffer_setting(struct r8a66597 *r8a66597, + struct usb_device *dev, unsigned long pipe) +{ + u16 val = 0; + u16 pipenum, bufnum, maxpacket; + + if (usb_pipein(pipe)) { + pipenum = BULK_IN_PIPENUM; + bufnum = BULK_IN_BUFNUM; + maxpacket = dev->epmaxpacketin[usb_pipeendpoint(pipe)]; + } else { + pipenum = BULK_OUT_PIPENUM; + bufnum = BULK_OUT_BUFNUM; + maxpacket = dev->epmaxpacketout[usb_pipeendpoint(pipe)]; + } + + if (r8a66597->pipe_config & (1 << pipenum)) + return; + r8a66597->pipe_config |= (1 << pipenum); + + r8a66597_bset(r8a66597, ACLRM, get_pipectr_addr(pipenum)); + r8a66597_bclr(r8a66597, ACLRM, get_pipectr_addr(pipenum)); + r8a66597_write(r8a66597, pipenum, PIPESEL); + + /* FIXME: This driver support bulk transfer only. */ + if (!usb_pipein(pipe)) + val |= R8A66597_DIR; + else + val |= R8A66597_SHTNAK; + val |= R8A66597_BULK | R8A66597_DBLB | usb_pipeendpoint(pipe); + r8a66597_write(r8a66597, val, PIPECFG); + + r8a66597_write(r8a66597, (8 << 10) | bufnum, PIPEBUF); + r8a66597_write(r8a66597, make_devsel(usb_pipedevice(pipe)) | + maxpacket, PIPEMAXP); + r8a66597_write(r8a66597, 0, PIPEPERI); + r8a66597_write(r8a66597, SQCLR, get_pipectr_addr(pipenum)); +} + +static int send_setup_packet(struct r8a66597 *r8a66597, struct usb_device *dev, + struct devrequest *setup) +{ + int i; + unsigned short *p = (unsigned short *)setup; + unsigned long setup_addr = USBREQ; + u16 intsts1; + int timeout = 3000; + u16 devsel = setup->request == USB_REQ_SET_ADDRESS ? 0 : dev->devnum; + + r8a66597_write(r8a66597, make_devsel(devsel) | + (8 << dev->maxpacketsize), DCPMAXP); + r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); + + for (i = 0; i < 4; i++) { + r8a66597_write(r8a66597, le16_to_cpu(p[i]), setup_addr); + setup_addr += 2; + } + r8a66597_write(r8a66597, ~0x0001, BRDYSTS); + r8a66597_write(r8a66597, SUREQ, DCPCTR); + + while (1) { + intsts1 = r8a66597_read(r8a66597, INTSTS1); + if (intsts1 & SACK) + break; + if (intsts1 & SIGN) { + printf("setup packet send error\n"); + return -1; + } + if (timeout-- < 0) { + printf("setup packet timeout\n"); + return -1; + } + udelay(500); + } + + return 0; +} + +static int send_bulk_packet(struct r8a66597 *r8a66597, struct usb_device *dev, + unsigned long pipe, void *buffer, int transfer_len) +{ + u16 tmp, bufsize; + u16 *buf; + size_t size; + + R8A66597_DPRINT("%s\n", __func__); + + r8a66597_mdfy(r8a66597, MBW | BULK_OUT_PIPENUM, + MBW | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, BULK_OUT_PIPENUM); + tmp = r8a66597_read(r8a66597, CFIFOCTR); + if ((tmp & FRDY) == 0) { + printf("%s FRDY is not set (%x)\n", __func__, tmp); + return -1; + } + + /* prepare parameters */ + bufsize = dev->epmaxpacketout[usb_pipeendpoint(pipe)]; + buf = (u16 *)(buffer + dev->act_len); + size = min((int)bufsize, transfer_len - dev->act_len); + + /* write fifo */ + r8a66597_write(r8a66597, ~(1 << BULK_OUT_PIPENUM), BEMPSTS); + if (buffer) { + r8a66597_write_fifo(r8a66597, CFIFO, buf, size); + r8a66597_write(r8a66597, BVAL, CFIFOCTR); + } + + /* update parameters */ + dev->act_len += size; + + r8a66597_mdfy(r8a66597, PID_BUF, PID, + get_pipectr_addr(BULK_OUT_PIPENUM)); + + while (!(r8a66597_read(r8a66597, BEMPSTS) & (1 << BULK_OUT_PIPENUM))) + if (ctrlc()) + return -1; + r8a66597_write(r8a66597, ~(1 << BULK_OUT_PIPENUM), BEMPSTS); + + if (dev->act_len >= transfer_len) + r8a66597_mdfy(r8a66597, PID_NAK, PID, + get_pipectr_addr(BULK_OUT_PIPENUM)); + + return 0; +} + +static int receive_bulk_packet(struct r8a66597 *r8a66597, + struct usb_device *dev, + unsigned long pipe, + void *buffer, int transfer_len) +{ + u16 tmp; + u16 *buf; + const u16 pipenum = BULK_IN_PIPENUM; + int rcv_len; + int maxpacket = dev->epmaxpacketin[usb_pipeendpoint(pipe)]; + + R8A66597_DPRINT("%s\n", __func__); + + /* prepare */ + if (dev->act_len == 0) { + r8a66597_mdfy(r8a66597, PID_NAK, PID, + get_pipectr_addr(pipenum)); + r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS); + + r8a66597_write(r8a66597, TRCLR, get_pipetre_addr(pipenum)); + r8a66597_write(r8a66597, + (transfer_len + maxpacket - 1) / maxpacket, + get_pipetrn_addr(pipenum)); + r8a66597_bset(r8a66597, TRENB, get_pipetre_addr(pipenum)); + + r8a66597_mdfy(r8a66597, PID_BUF, PID, + get_pipectr_addr(pipenum)); + } + + r8a66597_mdfy(r8a66597, MBW | pipenum, MBW | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, pipenum); + + while (!(r8a66597_read(r8a66597, BRDYSTS) & (1 << pipenum))) + if (ctrlc()) + return -1; + r8a66597_write(r8a66597, ~(1 << pipenum), BRDYSTS); + + tmp = r8a66597_read(r8a66597, CFIFOCTR); + if ((tmp & FRDY) == 0) { + printf("%s FRDY is not set. (%x)\n", __func__, tmp); + return -1; + } + + buf = (u16 *)(buffer + dev->act_len); + rcv_len = tmp & DTLN; + dev->act_len += rcv_len; + + if (buffer) { + if (rcv_len == 0) + r8a66597_write(r8a66597, BCLR, CFIFOCTR); + else + r8a66597_read_fifo(r8a66597, CFIFO, buf, rcv_len); + } + + return 0; +} + +static int receive_control_packet(struct r8a66597 *r8a66597, + struct usb_device *dev, + void *buffer, int transfer_len) +{ + u16 tmp; + int rcv_len; + + /* FIXME: limit transfer size : 64byte or less */ + + r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); + r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); + r8a66597_bset(r8a66597, SQSET, DCPCTR); + r8a66597_write(r8a66597, BCLR, CFIFOCTR); + r8a66597_mdfy(r8a66597, PID_BUF, PID, DCPCTR); + + while (!(r8a66597_read(r8a66597, BRDYSTS) & 0x0001)) + if (ctrlc()) + return -1; + r8a66597_write(r8a66597, ~0x0001, BRDYSTS); + + r8a66597_mdfy(r8a66597, MBW, MBW | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); + + tmp = r8a66597_read(r8a66597, CFIFOCTR); + if ((tmp & FRDY) == 0) { + printf("%s FRDY is not set. (%x)\n", __func__, tmp); + return -1; + } + + rcv_len = tmp & DTLN; + dev->act_len += rcv_len; + + r8a66597_mdfy(r8a66597, PID_NAK, PID, DCPCTR); + + if (buffer) { + if (rcv_len == 0) + r8a66597_write(r8a66597, BCLR, DCPCTR); + else + r8a66597_read_fifo(r8a66597, CFIFO, buffer, rcv_len); + } + + return 0; +} + +static int send_status_packet(struct r8a66597 *r8a66597, + unsigned long pipe) +{ + r8a66597_bset(r8a66597, SQSET, DCPCTR); + r8a66597_mdfy(r8a66597, PID_NAK, PID, DCPCTR); + + if (usb_pipein(pipe)) { + r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); + r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); + r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); + r8a66597_write(r8a66597, BCLR | BVAL, CFIFOCTR); + } else { + r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); + r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); + r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); + r8a66597_write(r8a66597, BCLR, CFIFOCTR); + } + r8a66597_mdfy(r8a66597, PID_BUF, PID, DCPCTR); + + while (!(r8a66597_read(r8a66597, BEMPSTS) & 0x0001)) + if (ctrlc()) + return -1; + + return 0; +} + +static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port) +{ + int count = R8A66597_MAX_SAMPLING; + unsigned short syssts, old_syssts; + + R8A66597_DPRINT("%s\n", __func__); + + old_syssts = r8a66597_read(r8a66597, get_syssts_reg(port) & LNST); + while (count > 0) { + wait_ms(R8A66597_RH_POLL_TIME); + + syssts = r8a66597_read(r8a66597, get_syssts_reg(port) & LNST); + if (syssts == old_syssts) { + count--; + } else { + count = R8A66597_MAX_SAMPLING; + old_syssts = syssts; + } + } +} + +static void r8a66597_bus_reset(struct r8a66597 *r8a66597, int port) +{ + wait_ms(10); + r8a66597_mdfy(r8a66597, USBRST, USBRST | UACT, get_dvstctr_reg(port)); + wait_ms(50); + r8a66597_mdfy(r8a66597, UACT, USBRST | UACT, get_dvstctr_reg(port)); + wait_ms(50); +} + +static int check_usb_device_connecting(struct r8a66597 *r8a66597) +{ + int timeout = 10000; /* 100usec * 10000 = 1sec */ + int i; + + for (i = 0; i < 5; i++) { + /* check a usb cable connect */ + while (!(r8a66597_read(r8a66597, INTSTS1) & ATTCH)) { + if (timeout-- < 0) { + printf("%s timeout.\n", __func__); + return -1; + } + udelay(100); + } + + /* check a data line */ + r8a66597_check_syssts(r8a66597, 0); + + r8a66597_bus_reset(r8a66597, 0); + r8a66597->speed = get_rh_usb_speed(r8a66597, 0); + + if (!(r8a66597_read(r8a66597, INTSTS1) & DTCH)) { + r8a66597->port_change = USB_PORT_STAT_C_CONNECTION; + r8a66597->port_status = USB_PORT_STAT_CONNECTION | + USB_PORT_STAT_ENABLE; + return 0; /* success */ + } + + R8A66597_DPRINT("USB device has detached. retry = %d\n", i); + r8a66597_write(r8a66597, ~DTCH, INTSTS1); + } + + return -1; /* fail */ +} + +/* based on usb_ohci.c */ +#define min_t(type, x, y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +/*-------------------------------------------------------------------------* + * Virtual Root Hub + *-------------------------------------------------------------------------*/ + +/* Device descriptor */ +static __u8 root_hub_dev_des[] = +{ + 0x12, /* __u8 bLength; */ + 0x01, /* __u8 bDescriptorType; Device */ + 0x10, /* __u16 bcdUSB; v1.1 */ + 0x01, + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ + 0x00, /* __u8 bDeviceSubClass; */ + 0x00, /* __u8 bDeviceProtocol; */ + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x00, /* __u16 idVendor; */ + 0x00, + 0x00, /* __u16 idProduct; */ + 0x00, + 0x00, /* __u16 bcdDevice; */ + 0x00, + 0x00, /* __u8 iManufacturer; */ + 0x01, /* __u8 iProduct; */ + 0x00, /* __u8 iSerialNumber; */ + 0x01 /* __u8 bNumConfigurations; */ +}; + +/* Configuration descriptor */ +static __u8 root_hub_config_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x02, /* __u8 bDescriptorType; Configuration */ + 0x19, /* __u16 wTotalLength; */ + 0x00, + 0x01, /* __u8 bNumInterfaces; */ + 0x01, /* __u8 bConfigurationValue; */ + 0x00, /* __u8 iConfiguration; */ + 0x40, /* __u8 bmAttributes; */ + + 0x00, /* __u8 MaxPower; */ + + /* interface */ + 0x09, /* __u8 if_bLength; */ + 0x04, /* __u8 if_bDescriptorType; Interface */ + 0x00, /* __u8 if_bInterfaceNumber; */ + 0x00, /* __u8 if_bAlternateSetting; */ + 0x01, /* __u8 if_bNumEndpoints; */ + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ + 0x00, /* __u8 if_bInterfaceSubClass; */ + 0x00, /* __u8 if_bInterfaceProtocol; */ + 0x00, /* __u8 if_iInterface; */ + + /* endpoint */ + 0x07, /* __u8 ep_bLength; */ + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ + 0x00, + 0xff /* __u8 ep_bInterval; 255 ms */ +}; + +static unsigned char root_hub_str_index0[] = +{ + 0x04, /* __u8 bLength; */ + 0x03, /* __u8 bDescriptorType; String-descriptor */ + 0x09, /* __u8 lang ID */ + 0x04, /* __u8 lang ID */ +}; + +static unsigned char root_hub_str_index1[] = +{ + 34, /* __u8 bLength; */ + 0x03, /* __u8 bDescriptorType; String-descriptor */ + 'R', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '8', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'A', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '6', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '6', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '5', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '9', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + '7', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + ' ', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'R', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'o', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'o', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 't', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'H', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'u', /* __u8 Unicode */ + 0, /* __u8 Unicode */ + 'b', /* __u8 Unicode */ + 0, /* __u8 Unicode */ +}; + +static int r8a66597_submit_rh_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, struct devrequest *cmd) +{ + struct r8a66597 *r8a66597 = &gr8a66597; + int leni = transfer_len; + int len = 0; + int stat = 0; + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + unsigned char data[32]; + + R8A66597_DPRINT("%s\n", __func__); + + if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) { + printf("Root-Hub submit IRQ: NOT implemented"); + return 0; + } + + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = cpu_to_le16 (cmd->value); + wIndex = cpu_to_le16 (cmd->index); + wLength = cpu_to_le16 (cmd->length); + + switch (bmRType_bReq) { + case RH_GET_STATUS: + *(__u16 *)buffer = cpu_to_le16(1); + len = 2; + break; + case RH_GET_STATUS | RH_INTERFACE: + *(__u16 *)buffer = cpu_to_le16(0); + len = 2; + break; + case RH_GET_STATUS | RH_ENDPOINT: + *(__u16 *)buffer = cpu_to_le16(0); + len = 2; + break; + case RH_GET_STATUS | RH_CLASS: + *(__u32 *)buffer = cpu_to_le32(0); + len = 4; + break; + case RH_GET_STATUS | RH_OTHER | RH_CLASS: + *(__u32 *)buffer = cpu_to_le32(r8a66597->port_status | + (r8a66597->port_change << 16)); + len = 4; + break; + case RH_CLEAR_FEATURE | RH_ENDPOINT: + case RH_CLEAR_FEATURE | RH_CLASS: + break; + + case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case RH_C_PORT_CONNECTION: + r8a66597->port_change &= ~USB_PORT_STAT_C_CONNECTION; + break; + } + break; + + case RH_SET_FEATURE | RH_OTHER | RH_CLASS: + switch (wValue) { + case (RH_PORT_SUSPEND): + break; + case (RH_PORT_RESET): + r8a66597_bus_reset(r8a66597, 0); + break; + case (RH_PORT_POWER): + break; + case (RH_PORT_ENABLE): + break; + } + break; + case RH_SET_ADDRESS: + gr8a66597.rh_devnum = wValue; + break; + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case (0x01): /* device descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_dev_des), + wLength)); + memcpy(buffer, root_hub_dev_des, len); + break; + case (0x02): /* configuration descriptor */ + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_config_des), + wLength)); + memcpy(buffer, root_hub_config_des, len); + break; + case (0x03): /* string descriptors */ + if (wValue == 0x0300) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_str_index0), + wLength)); + memcpy(buffer, root_hub_str_index0, len); + } + if (wValue == 0x0301) { + len = min_t(unsigned int, + leni, + min_t(unsigned int, + sizeof(root_hub_str_index1), + wLength)); + memcpy(buffer, root_hub_str_index1, len); + } + break; + default: + stat = USB_ST_STALLED; + } + break; + + case RH_GET_DESCRIPTOR | RH_CLASS: + { + __u32 temp = 0x00000001; + + data[0] = 9; /* min length; */ + data[1] = 0x29; + data[2] = temp & RH_A_NDP; + data[3] = 0; + if (temp & RH_A_PSM) + data[3] |= 0x1; + if (temp & RH_A_NOCP) + data[3] |= 0x10; + else if (temp & RH_A_OCPM) + data[3] |= 0x8; + + /* corresponds to data[4-7] */ + data[5] = (temp & RH_A_POTPGT) >> 24; + data[7] = temp & RH_B_DR; + if (data[2] < 7) { + data[8] = 0xff; + } else { + data[0] += 2; + data[8] = (temp & RH_B_DR) >> 8; + data[10] = data[9] = 0xff; + } + + len = min_t(unsigned int, leni, + min_t(unsigned int, data[0], wLength)); + memcpy(buffer, data, len); + break; + } + + case RH_GET_CONFIGURATION: + *(__u8 *) buffer = 0x01; + len = 1; + break; + case RH_SET_CONFIGURATION: + break; + default: + dbg("unsupported root hub command"); + stat = USB_ST_STALLED; + } + + wait_ms(1); + + len = min_t(int, len, leni); + + dev->act_len = len; + dev->status = stat; + + return stat; +} + +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len) +{ + struct r8a66597 *r8a66597 = &gr8a66597; + int ret = 0; + + R8A66597_DPRINT("%s\n", __func__); + R8A66597_DPRINT("pipe = %08x, buffer = %p, len = %d, devnum = %d\n", + pipe, buffer, transfer_len, dev->devnum); + + set_devadd_reg(r8a66597, dev->devnum, r8a66597->speed, 0, 0, 0); + + pipe_buffer_setting(r8a66597, dev, pipe); + + dev->act_len = 0; + while (dev->act_len < transfer_len && ret == 0) { + if (ctrlc()) + return -1; + + if (usb_pipein(pipe)) + ret = receive_bulk_packet(r8a66597, dev, pipe, buffer, + transfer_len); + else + ret = send_bulk_packet(r8a66597, dev, pipe, buffer, + transfer_len); + } + + if (ret == 0) + dev->status = 0; + + return ret; +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, struct devrequest *setup) +{ + struct r8a66597 *r8a66597 = &gr8a66597; + u16 r8a66597_address = setup->request == USB_REQ_SET_ADDRESS ? + 0 : dev->devnum; + + R8A66597_DPRINT("%s\n", __func__); + if (usb_pipedevice(pipe) == r8a66597->rh_devnum) + return r8a66597_submit_rh_msg(dev, pipe, buffer, transfer_len, + setup); + + R8A66597_DPRINT("%s: setup\n", __func__); + set_devadd_reg(r8a66597, r8a66597_address, r8a66597->speed, 0, 0, 0); + + if (send_setup_packet(r8a66597, dev, setup) < 0) { + printf("setup packet send error\n"); + return -1; + } + + if (usb_pipein(pipe)) + if (receive_control_packet(r8a66597, dev, buffer, + transfer_len) < 0) + return -1; + + if (send_status_packet(r8a66597, pipe) < 0) + return -1; + + dev->status = 0; + + return 0; +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, int interval) +{ + /* no implement */ + R8A66597_DPRINT("%s\n", __func__); + return 0; +} + +void usb_event_poll(void) +{ + /* no implement */ + R8A66597_DPRINT("%s\n", __func__); +} + +int usb_lowlevel_init(void) +{ + struct r8a66597 *r8a66597 = &gr8a66597; + + R8A66597_DPRINT("%s\n", __func__); + + memset(r8a66597, 0, sizeof(r8a66597)); + r8a66597->reg = CONFIG_R8A66597_BASE_ADDR; + + disable_controller(r8a66597); + wait_ms(100); + + enable_controller(r8a66597); + r8a66597_port_power(r8a66597, 0 , 1); + + /* check usb device */ + check_usb_device_connecting(r8a66597); + + wait_ms(50); + + return 0; +} + +int usb_lowlevel_stop(void) +{ + disable_controller(&gr8a66597); + + return 0; +} + +#endif /* CONFIG_USB_R8A66597_HCD */ + diff --git a/drivers/usb/r8a66597.h b/drivers/usb/r8a66597.h new file mode 100644 index 00000000000..54a1f26aefc --- /dev/null +++ b/drivers/usb/r8a66597.h @@ -0,0 +1,663 @@ +/* + * R8A66597 HCD (Host Controller Driver) for u-boot + * + * Copyright (C) 2008 Yoshihiro Shimoda + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __R8A66597_H__ +#define __R8A66597_H__ + +#define SYSCFG0 0x00 +#define SYSCFG1 0x02 +#define SYSSTS0 0x04 +#define SYSSTS1 0x06 +#define DVSTCTR0 0x08 +#define DVSTCTR1 0x0A +#define TESTMODE 0x0C +#define PINCFG 0x0E +#define DMA0CFG 0x10 +#define DMA1CFG 0x12 +#define CFIFO 0x14 +#define D0FIFO 0x18 +#define D1FIFO 0x1C +#define CFIFOSEL 0x20 +#define CFIFOCTR 0x22 +#define CFIFOSIE 0x24 +#define D0FIFOSEL 0x28 +#define D0FIFOCTR 0x2A +#define D1FIFOSEL 0x2C +#define D1FIFOCTR 0x2E +#define INTENB0 0x30 +#define INTENB1 0x32 +#define INTENB2 0x34 +#define BRDYENB 0x36 +#define NRDYENB 0x38 +#define BEMPENB 0x3A +#define SOFCFG 0x3C +#define INTSTS0 0x40 +#define INTSTS1 0x42 +#define INTSTS2 0x44 +#define BRDYSTS 0x46 +#define NRDYSTS 0x48 +#define BEMPSTS 0x4A +#define FRMNUM 0x4C +#define UFRMNUM 0x4E +#define USBADDR 0x50 +#define USBREQ 0x54 +#define USBVAL 0x56 +#define USBINDX 0x58 +#define USBLENG 0x5A +#define DCPCFG 0x5C +#define DCPMAXP 0x5E +#define DCPCTR 0x60 +#define PIPESEL 0x64 +#define PIPECFG 0x68 +#define PIPEBUF 0x6A +#define PIPEMAXP 0x6C +#define PIPEPERI 0x6E +#define PIPE1CTR 0x70 +#define PIPE2CTR 0x72 +#define PIPE3CTR 0x74 +#define PIPE4CTR 0x76 +#define PIPE5CTR 0x78 +#define PIPE6CTR 0x7A +#define PIPE7CTR 0x7C +#define PIPE8CTR 0x7E +#define PIPE9CTR 0x80 +#define PIPE1TRE 0x90 +#define PIPE1TRN 0x92 +#define PIPE2TRE 0x94 +#define PIPE2TRN 0x96 +#define PIPE3TRE 0x98 +#define PIPE3TRN 0x9A +#define PIPE4TRE 0x9C +#define PIPE4TRN 0x9E +#define PIPE5TRE 0xA0 +#define PIPE5TRN 0xA2 +#define DEVADD0 0xD0 +#define DEVADD1 0xD2 +#define DEVADD2 0xD4 +#define DEVADD3 0xD6 +#define DEVADD4 0xD8 +#define DEVADD5 0xDA +#define DEVADD6 0xDC +#define DEVADD7 0xDE +#define DEVADD8 0xE0 +#define DEVADD9 0xE2 +#define DEVADDA 0xE4 + +/* System Configuration Control Register */ +#define XTAL 0xC000 /* b15-14: Crystal selection */ +#define XTAL48 0x8000 /* 48MHz */ +#define XTAL24 0x4000 /* 24MHz */ +#define XTAL12 0x0000 /* 12MHz */ +#define XCKE 0x2000 /* b13: External clock enable */ +#define PLLC 0x0800 /* b11: PLL control */ +#define SCKE 0x0400 /* b10: USB clock enable */ +#define PCSDIS 0x0200 /* b9: not CS wakeup */ +#define LPSME 0x0100 /* b8: Low power sleep mode */ +#define HSE 0x0080 /* b7: Hi-speed enable */ +#define DCFM 0x0040 /* b6: Controller function select */ +#define DRPD 0x0020 /* b5: D+/- pull down control */ +#define DPRPU 0x0010 /* b4: D+ pull up control */ +#define USBE 0x0001 /* b0: USB module operation enable */ + +/* System Configuration Status Register */ +#define OVCBIT 0x8000 /* b15-14: Over-current bit */ +#define OVCMON 0xC000 /* b15-14: Over-current monitor */ +#define SOFEA 0x0020 /* b5: SOF monitor */ +#define IDMON 0x0004 /* b3: ID-pin monitor */ +#define LNST 0x0003 /* b1-0: D+, D- line status */ +#define SE1 0x0003 /* SE1 */ +#define FS_KSTS 0x0002 /* Full-Speed K State */ +#define FS_JSTS 0x0001 /* Full-Speed J State */ +#define LS_JSTS 0x0002 /* Low-Speed J State */ +#define LS_KSTS 0x0001 /* Low-Speed K State */ +#define SE0 0x0000 /* SE0 */ + +/* Device State Control Register */ +#define EXTLP0 0x0400 /* b10: External port */ +#define VBOUT 0x0200 /* b9: VBUS output */ +#define WKUP 0x0100 /* b8: Remote wakeup */ +#define RWUPE 0x0080 /* b7: Remote wakeup sense */ +#define USBRST 0x0040 /* b6: USB reset enable */ +#define RESUME 0x0020 /* b5: Resume enable */ +#define UACT 0x0010 /* b4: USB bus enable */ +#define RHST 0x0007 /* b1-0: Reset handshake status */ +#define HSPROC 0x0004 /* HS handshake is processing */ +#define HSMODE 0x0003 /* Hi-Speed mode */ +#define FSMODE 0x0002 /* Full-Speed mode */ +#define LSMODE 0x0001 /* Low-Speed mode */ +#define UNDECID 0x0000 /* Undecided */ + +/* Test Mode Register */ +#define UTST 0x000F /* b3-0: Test select */ +#define H_TST_PACKET 0x000C /* HOST TEST Packet */ +#define H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ +#define H_TST_K 0x000A /* HOST TEST K */ +#define H_TST_J 0x0009 /* HOST TEST J */ +#define H_TST_NORMAL 0x0000 /* HOST Normal Mode */ +#define P_TST_PACKET 0x0004 /* PERI TEST Packet */ +#define P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ +#define P_TST_K 0x0002 /* PERI TEST K */ +#define P_TST_J 0x0001 /* PERI TEST J */ +#define P_TST_NORMAL 0x0000 /* PERI Normal Mode */ + +/* Data Pin Configuration Register */ +#define LDRV 0x8000 /* b15: Drive Current Adjust */ +#define VIF1 0x0000 /* VIF = 1.8V */ +#define VIF3 0x8000 /* VIF = 3.3V */ +#define INTA 0x0001 /* b1: USB INT-pin active */ + +/* DMAx Pin Configuration Register */ +#define DREQA 0x4000 /* b14: Dreq active select */ +#define BURST 0x2000 /* b13: Burst mode */ +#define DACKA 0x0400 /* b10: Dack active select */ +#define DFORM 0x0380 /* b9-7: DMA mode select */ +#define CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ +#define CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ +#define CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ +#define SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ +#define DENDA 0x0040 /* b6: Dend active select */ +#define PKTM 0x0020 /* b5: Packet mode */ +#define DENDE 0x0010 /* b4: Dend enable */ +#define OBUS 0x0004 /* b2: OUTbus mode */ + +/* CFIFO/DxFIFO Port Select Register */ +#define RCNT 0x8000 /* b15: Read count mode */ +#define REW 0x4000 /* b14: Buffer rewind */ +#define DCLRM 0x2000 /* b13: DMA buffer clear mode */ +#define DREQE 0x1000 /* b12: DREQ output enable */ +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#define MBW 0x0800 +#else +#define MBW 0x0400 /* b10: Maximum bit width for FIFO access */ +#endif +#define MBW_8 0x0000 /* 8bit */ +#define MBW_16 0x0400 /* 16bit */ +#define BIGEND 0x0100 /* b8: Big endian mode */ +#define BYTE_LITTLE 0x0000 /* little dendian */ +#define BYTE_BIG 0x0100 /* big endifan */ +#define ISEL 0x0020 /* b5: DCP FIFO port direction select */ +#define CURPIPE 0x000F /* b2-0: PIPE select */ + +/* CFIFO/DxFIFO Port Control Register */ +#define BVAL 0x8000 /* b15: Buffer valid flag */ +#define BCLR 0x4000 /* b14: Buffer clear */ +#define FRDY 0x2000 /* b13: FIFO ready */ +#define DTLN 0x0FFF /* b11-0: FIFO received data length */ + +/* Interrupt Enable Register 0 */ +#define VBSE 0x8000 /* b15: VBUS interrupt */ +#define RSME 0x4000 /* b14: Resume interrupt */ +#define SOFE 0x2000 /* b13: Frame update interrupt */ +#define DVSE 0x1000 /* b12: Device state transition interrupt */ +#define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMPE 0x0400 /* b10: Buffer empty interrupt */ +#define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDYE 0x0100 /* b8: Buffer ready interrupt */ + +/* Interrupt Enable Register 1 */ +#define OVRCRE 0x8000 /* b15: Over-current interrupt */ +#define BCHGE 0x4000 /* b14: USB us chenge interrupt */ +#define DTCHE 0x1000 /* b12: Detach sense interrupt */ +#define ATTCHE 0x0800 /* b11: Attach sense interrupt */ +#define EOFERRE 0x0040 /* b6: EOF error interrupt */ +#define SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ +#define SACKE 0x0010 /* b4: SETUP ACK interrupt */ + +/* BRDY Interrupt Enable/Status Register */ +#define BRDY9 0x0200 /* b9: PIPE9 */ +#define BRDY8 0x0100 /* b8: PIPE8 */ +#define BRDY7 0x0080 /* b7: PIPE7 */ +#define BRDY6 0x0040 /* b6: PIPE6 */ +#define BRDY5 0x0020 /* b5: PIPE5 */ +#define BRDY4 0x0010 /* b4: PIPE4 */ +#define BRDY3 0x0008 /* b3: PIPE3 */ +#define BRDY2 0x0004 /* b2: PIPE2 */ +#define BRDY1 0x0002 /* b1: PIPE1 */ +#define BRDY0 0x0001 /* b1: PIPE0 */ + +/* NRDY Interrupt Enable/Status Register */ +#define NRDY9 0x0200 /* b9: PIPE9 */ +#define NRDY8 0x0100 /* b8: PIPE8 */ +#define NRDY7 0x0080 /* b7: PIPE7 */ +#define NRDY6 0x0040 /* b6: PIPE6 */ +#define NRDY5 0x0020 /* b5: PIPE5 */ +#define NRDY4 0x0010 /* b4: PIPE4 */ +#define NRDY3 0x0008 /* b3: PIPE3 */ +#define NRDY2 0x0004 /* b2: PIPE2 */ +#define NRDY1 0x0002 /* b1: PIPE1 */ +#define NRDY0 0x0001 /* b1: PIPE0 */ + +/* BEMP Interrupt Enable/Status Register */ +#define BEMP9 0x0200 /* b9: PIPE9 */ +#define BEMP8 0x0100 /* b8: PIPE8 */ +#define BEMP7 0x0080 /* b7: PIPE7 */ +#define BEMP6 0x0040 /* b6: PIPE6 */ +#define BEMP5 0x0020 /* b5: PIPE5 */ +#define BEMP4 0x0010 /* b4: PIPE4 */ +#define BEMP3 0x0008 /* b3: PIPE3 */ +#define BEMP2 0x0004 /* b2: PIPE2 */ +#define BEMP1 0x0002 /* b1: PIPE1 */ +#define BEMP0 0x0001 /* b0: PIPE0 */ + +/* SOF Pin Configuration Register */ +#define TRNENSEL 0x0100 /* b8: Select transaction enable period */ +#define BRDYM 0x0040 /* b6: BRDY clear timing */ +#define INTL 0x0020 /* b5: Interrupt sense select */ +#define EDGESTS 0x0010 /* b4: */ +#define SOFMODE 0x000C /* b3-2: SOF pin select */ +#define SOF_125US 0x0008 /* SOF OUT 125us Frame Signal */ +#define SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ +#define SOF_DISABLE 0x0000 /* SOF OUT Disable */ + +/* Interrupt Status Register 0 */ +#define VBINT 0x8000 /* b15: VBUS interrupt */ +#define RESM 0x4000 /* b14: Resume interrupt */ +#define SOFR 0x2000 /* b13: SOF frame update interrupt */ +#define DVST 0x1000 /* b12: Device state transition interrupt */ +#define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ +#define BEMP 0x0400 /* b10: Buffer empty interrupt */ +#define NRDY 0x0200 /* b9: Buffer not ready interrupt */ +#define BRDY 0x0100 /* b8: Buffer ready interrupt */ +#define VBSTS 0x0080 /* b7: VBUS input port */ +#define DVSQ 0x0070 /* b6-4: Device state */ +#define DS_SPD_CNFG 0x0070 /* Suspend Configured */ +#define DS_SPD_ADDR 0x0060 /* Suspend Address */ +#define DS_SPD_DFLT 0x0050 /* Suspend Default */ +#define DS_SPD_POWR 0x0040 /* Suspend Powered */ +#define DS_SUSP 0x0040 /* Suspend */ +#define DS_CNFG 0x0030 /* Configured */ +#define DS_ADDS 0x0020 /* Address */ +#define DS_DFLT 0x0010 /* Default */ +#define DS_POWR 0x0000 /* Powered */ +#define DVSQS 0x0030 /* b5-4: Device state */ +#define VALID 0x0008 /* b3: Setup packet detected flag */ +#define CTSQ 0x0007 /* b2-0: Control transfer stage */ +#define CS_SQER 0x0006 /* Sequence error */ +#define CS_WRND 0x0005 /* Control write nodata status stage */ +#define CS_WRSS 0x0004 /* Control write status stage */ +#define CS_WRDS 0x0003 /* Control write data stage */ +#define CS_RDSS 0x0002 /* Control read status stage */ +#define CS_RDDS 0x0001 /* Control read data stage */ +#define CS_IDST 0x0000 /* Idle or setup stage */ + +/* Interrupt Status Register 1 */ +#define OVRCR 0x8000 /* b15: Over-current interrupt */ +#define BCHG 0x4000 /* b14: USB bus chenge interrupt */ +#define DTCH 0x1000 /* b12: Detach sense interrupt */ +#define ATTCH 0x0800 /* b11: Attach sense interrupt */ +#define EOFERR 0x0040 /* b6: EOF-error interrupt */ +#define SIGN 0x0020 /* b5: Setup ignore interrupt */ +#define SACK 0x0010 /* b4: Setup acknowledge interrupt */ + +/* Frame Number Register */ +#define OVRN 0x8000 /* b15: Overrun error */ +#define CRCE 0x4000 /* b14: Received data error */ +#define FRNM 0x07FF /* b10-0: Frame number */ + +/* Micro Frame Number Register */ +#define UFRNM 0x0007 /* b2-0: Micro frame number */ + +/* Default Control Pipe Maxpacket Size Register */ +/* Pipe Maxpacket Size Register */ +#define DEVSEL 0xF000 /* b15-14: Device address select */ +#define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ + +/* Default Control Pipe Control Register */ +#define BSTS 0x8000 /* b15: Buffer status */ +#define SUREQ 0x4000 /* b14: Send USB request */ +#define CSCLR 0x2000 /* b13: complete-split status clear */ +#define CSSTS 0x1000 /* b12: complete-split status */ +#define SUREQCLR 0x0800 /* b11: stop setup request */ +#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define PBUSY 0x0020 /* b5: pipe busy */ +#define PINGE 0x0010 /* b4: ping enable */ +#define CCPL 0x0004 /* b2: Enable control transfer complete */ +#define PID 0x0003 /* b1-0: Response PID */ +#define PID_STALL11 0x0003 /* STALL */ +#define PID_STALL 0x0002 /* STALL */ +#define PID_BUF 0x0001 /* BUF */ +#define PID_NAK 0x0000 /* NAK */ + +/* Pipe Window Select Register */ +#define PIPENM 0x0007 /* b2-0: Pipe select */ + +/* Pipe Configuration Register */ +#define R8A66597_TYP 0xC000 /* b15-14: Transfer type */ +#define R8A66597_ISO 0xC000 /* Isochronous */ +#define R8A66597_INT 0x8000 /* Interrupt */ +#define R8A66597_BULK 0x4000 /* Bulk */ +#define R8A66597_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ +#define R8A66597_DBLB 0x0200 /* b9: Double buffer mode select */ +#define R8A66597_CNTMD 0x0100 /* b8: Continuous transfer mode select */ +#define R8A66597_SHTNAK 0x0080 /* b7: Transfer end NAK */ +#define R8A66597_DIR 0x0010 /* b4: Transfer direction select */ +#define R8A66597_EPNUM 0x000F /* b3-0: Eendpoint number select */ + +/* Pipe Buffer Configuration Register */ +#define BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ +#define BUFNMB 0x007F /* b6-0: Pipe buffer number */ +#define PIPE0BUF 256 +#define PIPExBUF 64 + +/* Pipe Maxpacket Size Register */ +#define MXPS 0x07FF /* b10-0: Maxpacket size */ + +/* Pipe Cycle Configuration Register */ +#define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ +#define IITV 0x0007 /* b2-0: Isochronous interval */ + +/* Pipex Control Register */ +#define BSTS 0x8000 /* b15: Buffer status */ +#define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ +#define CSCLR 0x2000 /* b13: complete-split status clear */ +#define CSSTS 0x1000 /* b12: complete-split status */ +#define ATREPM 0x0400 /* b10: Auto repeat mode */ +#define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ +#define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ +#define SQSET 0x0080 /* b7: Sequence toggle bit set */ +#define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ +#define PBUSY 0x0020 /* b5: pipe busy */ +#define PID 0x0003 /* b1-0: Response PID */ + +/* PIPExTRE */ +#define TRENB 0x0200 /* b9: Transaction counter enable */ +#define TRCLR 0x0100 /* b8: Transaction counter clear */ + +/* PIPExTRN */ +#define TRNCNT 0xFFFF /* b15-0: Transaction counter */ + +/* DEVADDx */ +#define UPPHUB 0x7800 +#define HUBPORT 0x0700 +#define USBSPD 0x00C0 +#define RTPORT 0x0001 + +#define R8A66597_MAX_NUM_PIPE 10 +#define R8A66597_BUF_BSIZE 8 +#define R8A66597_MAX_DEVICE 10 +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) +#define R8A66597_MAX_ROOT_HUB 1 +#else +#define R8A66597_MAX_ROOT_HUB 2 +#endif +#define R8A66597_MAX_SAMPLING 5 +#define R8A66597_RH_POLL_TIME 10 + +#define BULK_IN_PIPENUM 3 +#define BULK_IN_BUFNUM 8 + +#define BULK_OUT_PIPENUM 4 +#define BULK_OUT_BUFNUM 40 + +#define check_bulk_or_isoc(pipenum) ((pipenum >= 1 && pipenum <= 5)) +#define check_interrupt(pipenum) ((pipenum >= 6 && pipenum <= 9)) +#define make_devsel(addr) (addr << 12) + +struct r8a66597 { + unsigned long reg; + unsigned short pipe_config; /* bit field */ + unsigned short port_status; + unsigned short port_change; + u16 speed; /* HSMODE or FSMODE or LSMODE */ + unsigned char rh_devnum; +}; + +static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset) +{ + return inw(r8a66597->reg + offset); +} + +static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, + unsigned long offset, void *buf, + int len) +{ + int i; +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + unsigned long fifoaddr = r8a66597->reg + offset; + unsigned long count; + unsigned long *p = buf; + + count = len / 4; + for (i = 0; i < count; i++) + inl(p[i], r8a66597->reg + offset); + + if (len & 0x00000003) { + unsigned long tmp = inl(fifoaddr); + memcpy((unsigned char *)buf + count * 4, &tmp, len & 0x03); + } +#else + unsigned short *p = buf; + + len = (len + 1) / 2; + for (i = 0; i < len; i++) + p[i] = inw(r8a66597->reg + offset); +#endif +} + +static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val, + unsigned long offset) +{ + outw(val, r8a66597->reg + offset); +} + +static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, + unsigned long offset, void *buf, + int len) +{ + int i; + unsigned long fifoaddr = r8a66597->reg + offset; +#if defined(CONFIG_SUPERH_ON_CHIP_R8A66597) + unsigned long count; + unsigned char *pb; + unsigned long *p = buf; + + count = len / 4; + for (i = 0; i < count; i++) + outl(p[i], fifoaddr); + + if (len & 0x00000003) { + pb = (unsigned char *)buf + count * 4; + for (i = 0; i < (len & 0x00000003); i++) { + if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND) + outb(pb[i], fifoaddr + i); + else + outb(pb[i], fifoaddr + 3 - i); + } + } +#else + int odd = len & 0x0001; + unsigned short *p = buf; + + len = len / 2; + for (i = 0; i < len; i++) + outw(p[i], fifoaddr); + + if (odd) { + unsigned char *pb = (unsigned char *)(buf + len); + outb(*pb, fifoaddr); + } +#endif +} + +static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, + u16 val, u16 pat, unsigned long offset) +{ + u16 tmp; + tmp = r8a66597_read(r8a66597, offset); + tmp = tmp & (~pat); + tmp = tmp | val; + r8a66597_write(r8a66597, tmp, offset); +} + +#define r8a66597_bclr(r8a66597, val, offset) \ + r8a66597_mdfy(r8a66597, 0, val, offset) +#define r8a66597_bset(r8a66597, val, offset) \ + r8a66597_mdfy(r8a66597, val, 0, offset) + +static inline unsigned long get_syscfg_reg(int port) +{ + return port == 0 ? SYSCFG0 : SYSCFG1; +} + +static inline unsigned long get_syssts_reg(int port) +{ + return port == 0 ? SYSSTS0 : SYSSTS1; +} + +static inline unsigned long get_dvstctr_reg(int port) +{ + return port == 0 ? DVSTCTR0 : DVSTCTR1; +} + +static inline unsigned long get_dmacfg_reg(int port) +{ + return port == 0 ? DMA0CFG : DMA1CFG; +} + +static inline unsigned long get_intenb_reg(int port) +{ + return port == 0 ? INTENB1 : INTENB2; +} + +static inline unsigned long get_intsts_reg(int port) +{ + return port == 0 ? INTSTS1 : INTSTS2; +} + +static inline u16 get_rh_usb_speed(struct r8a66597 *r8a66597, int port) +{ + unsigned long dvstctr_reg = get_dvstctr_reg(port); + + return r8a66597_read(r8a66597, dvstctr_reg) & RHST; +} + +static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port, + int power) +{ + unsigned long dvstctr_reg = get_dvstctr_reg(port); + + if (power) + r8a66597_bset(r8a66597, VBOUT, dvstctr_reg); + else + r8a66597_bclr(r8a66597, VBOUT, dvstctr_reg); +} + +#define get_pipectr_addr(pipenum) (PIPE1CTR + (pipenum - 1) * 2) +#define get_pipetre_addr(pipenum) (PIPE1TRE + (pipenum - 1) * 4) +#define get_pipetrn_addr(pipenum) (PIPE1TRN + (pipenum - 1) * 4) +#define get_devadd_addr(address) (DEVADD0 + address * 2) + + +/* USB HUB CONSTANTS (not OHCI-specific; see hub.h, based on usb_ohci.h) */ + +/* destination of request */ +#define RH_INTERFACE 0x01 +#define RH_ENDPOINT 0x02 +#define RH_OTHER 0x03 + +#define RH_CLASS 0x20 +#define RH_VENDOR 0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP 0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION 0x00 +#define RH_PORT_ENABLE 0x01 +#define RH_PORT_SUSPEND 0x02 +#define RH_PORT_OVER_CURRENT 0x03 +#define RH_PORT_RESET 0x04 +#define RH_PORT_POWER 0x08 +#define RH_PORT_LOW_SPEED 0x09 + +#define RH_C_PORT_CONNECTION 0x10 +#define RH_C_PORT_ENABLE 0x11 +#define RH_C_PORT_SUSPEND 0x12 +#define RH_C_PORT_OVER_CURRENT 0x13 +#define RH_C_PORT_RESET 0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER 0x00 +#define RH_C_HUB_OVER_CURRENT 0x01 + +#define RH_DEVICE_REMOTE_WAKEUP 0x00 +#define RH_ENDPOINT_STALL 0x01 + +#define RH_ACK 0x01 +#define RH_REQ_ERR -1 +#define RH_NACK 0x00 + + +/* OHCI ROOT HUB REGISTER MASKS */ + +/* roothub.portstatus [i] bits */ +#define RH_PS_CCS 0x00000001 /* current connect status */ +#define RH_PS_PES 0x00000002 /* port enable status*/ +#define RH_PS_PSS 0x00000004 /* port suspend status */ +#define RH_PS_POCI 0x00000008 /* port over current indicator */ +#define RH_PS_PRS 0x00000010 /* port reset status */ +#define RH_PS_PPS 0x00000100 /* port power status */ +#define RH_PS_LSDA 0x00000200 /* low speed device attached */ +#define RH_PS_CSC 0x00010000 /* connect status change */ +#define RH_PS_PESC 0x00020000 /* port enable status change */ +#define RH_PS_PSSC 0x00040000 /* port suspend status change */ +#define RH_PS_OCIC 0x00080000 /* over current indicator change */ +#define RH_PS_PRSC 0x00100000 /* port reset status change */ + +/* roothub.status bits */ +#define RH_HS_LPS 0x00000001 /* local power status */ +#define RH_HS_OCI 0x00000002 /* over current indicator */ +#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ +#define RH_HS_LPSC 0x00010000 /* local power status change */ +#define RH_HS_OCIC 0x00020000 /* over current indicator change */ +#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ + +/* roothub.b masks */ +#define RH_B_DR 0x0000ffff /* device removable flags */ +#define RH_B_PPCM 0xffff0000 /* port power control mask */ + +/* roothub.a masks */ +#define RH_A_NDP (0xff << 0) /* number of downstream ports */ +#define RH_A_PSM (1 << 8) /* power switching mode */ +#define RH_A_NPS (1 << 9) /* no power switching */ +#define RH_A_DT (1 << 10) /* device type (mbz) */ +#define RH_A_OCPM (1 << 11) /* over current protection mode */ +#define RH_A_NOCP (1 << 12) /* no over current protection */ +#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ + + +#endif /* __R8A66597_H__ */ + diff --git a/include/usb.h b/include/usb.h index 5a6ffddec80..e68e98eadc7 100644 --- a/include/usb.h +++ b/include/usb.h @@ -171,7 +171,7 @@ struct usb_device { #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \ defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \ - defined(CONFIG_USB_ISP116X_HCD) + defined(CONFIG_USB_ISP116X_HCD) || defined(CONFIG_USB_R8A66597_HCD) int usb_lowlevel_init(void); int usb_lowlevel_stop(void); -- cgit v1.3.1 From d5d28fe4aad5f4535400647a5617c11039506467 Mon Sep 17 00:00:00 2001 From: David Saada Date: Mon, 31 Mar 2008 02:37:38 -0700 Subject: QE UEC: Add MII Commands Add MII commands to the UEC driver. Note that once a UEC device is selected, any device on its MDIO bus can be addressed. Signed-off-by: David Saada Signed-off-by: Ben Warren --- drivers/qe/uec.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'drivers') diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index d2c430b8a6f..049a74d5cb6 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -29,6 +29,7 @@ #include "uccf.h" #include "uec.h" #include "uec_phy.h" +#include "miiphy.h" #if defined(CONFIG_QE) @@ -125,6 +126,17 @@ static uec_info_t eth4_uec_info = { }; #endif +#define MAXCONTROLLERS (4) + +static struct eth_device *devlist[MAXCONTROLLERS]; + +static int uec_miiphy_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); +static int uec_miiphy_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value); +u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); +void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); + static int uec_mac_enable(uec_private_t *uec, comm_dir_e mode) { uec_t *uec_regs; @@ -1334,6 +1346,8 @@ int uec_initialize(int index) return -EINVAL; } + devlist[index] = dev; + uec->uec_info = uec_info; sprintf(dev->name, "FSL UEC%d", index); @@ -1356,6 +1370,45 @@ int uec_initialize(int index) return err; } +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ + && !defined(BITBANGMII) + miiphy_register(dev->name, uec_miiphy_read, uec_miiphy_write); +#endif + return 1; } + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ + && !defined(BITBANGMII) + +/* + * Read a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + *value = uec_read_phy_reg(devlist[0], addr, reg); + + return 0; +} + +/* + * Write a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + uec_write_phy_reg(devlist[0], addr, reg, value); + + return 0; +} + +#endif + #endif /* CONFIG_QE */ -- cgit v1.3.1 From d9d78ee46d9a396d0a81d00c2b003a9bd32c2e61 Mon Sep 17 00:00:00 2001 From: Ben Warren Date: Thu, 7 Aug 2008 23:26:35 -0700 Subject: QE UEC: Fix compiler warnings Moved static functions earlier in file so forward declarations are not needed. Signed-off-by: Ben Warren --- drivers/qe/uec.c | 69 +++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 049a74d5cb6..ba89247e4fc 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -130,10 +130,6 @@ static uec_info_t eth4_uec_info = { static struct eth_device *devlist[MAXCONTROLLERS]; -static int uec_miiphy_read(char *devname, unsigned char addr, - unsigned char reg, unsigned short *value); -static int uec_miiphy_write(char *devname, unsigned char addr, - unsigned char reg, unsigned short value); u16 phy_read (struct uec_mii_info *mii_info, u16 regnum); void phy_write (struct uec_mii_info *mii_info, u16 regnum, u16 val); @@ -641,6 +637,39 @@ static void phy_change(struct eth_device *dev) adjust_link(dev); } +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ + && !defined(BITBANGMII) + +/* + * Read a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + *value = uec_read_phy_reg(devlist[0], addr, reg); + + return 0; +} + +/* + * Write a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + uec_write_phy_reg(devlist[0], addr, reg, value); + + return 0; +} + +#endif + static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr) { uec_t *uec_regs; @@ -1378,37 +1407,5 @@ int uec_initialize(int index) return 1; } -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \ - && !defined(BITBANGMII) - -/* - * Read a MII PHY register. - * - * Returns: - * 0 on success - */ -static int uec_miiphy_read(char *devname, unsigned char addr, - unsigned char reg, unsigned short *value) -{ - *value = uec_read_phy_reg(devlist[0], addr, reg); - - return 0; -} - -/* - * Write a MII PHY register. - * - * Returns: - * 0 on success - */ -static int uec_miiphy_write(char *devname, unsigned char addr, - unsigned char reg, unsigned short value) -{ - uec_write_phy_reg(devlist[0], addr, reg, value); - - return 0; -} - -#endif #endif /* CONFIG_QE */ -- cgit v1.3.1 From 2a112b234d879f6390503a5f4e38246acce9d0b0 Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Fri, 8 Aug 2008 16:39:54 +0200 Subject: CFI: allow for dynamically determined flash sizes and addresses The CFI driver allowed only for static initializers in the CFG_FLASH_BANKS_LIST definition, i. e. it did not allow to map several flash banks contiguously if the bank sizes were not known in advance, which kind of violates U-Boot's design philosophy. (will be used for example by the TQM8xxL boards) Signed-off-by: Wolfgang Denk --- drivers/mtd/cfi_flash.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 12647ef9861..479075ccb19 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -158,13 +158,13 @@ static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT }; /* use CFG_MAX_FLASH_BANKS_DETECT if defined */ #ifdef CFG_MAX_FLASH_BANKS_DETECT -static ulong bank_base[CFG_MAX_FLASH_BANKS_DETECT] = CFG_FLASH_BANKS_LIST; -flash_info_t flash_info[CFG_MAX_FLASH_BANKS_DETECT]; /* FLASH chips info */ +# define CFI_MAX_FLASH_BANKS CFG_MAX_FLASH_BANKS_DETECT #else -static ulong bank_base[CFG_MAX_FLASH_BANKS] = CFG_FLASH_BANKS_LIST; -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* FLASH chips info */ +# define CFI_MAX_FLASH_BANKS CFG_MAX_FLASH_BANKS #endif +flash_info_t flash_info[CFI_MAX_FLASH_BANKS]; /* FLASH chips info */ + /* * Check if chip width is defined. If not, start detecting with 8bit. */ @@ -1912,12 +1912,14 @@ unsigned long flash_init (void) char *s = getenv("unlock"); #endif +#define BANK_BASE(i) (((unsigned long [CFI_MAX_FLASH_BANKS])CFG_FLASH_BANKS_LIST)[i]) + /* Init: no FLASHes known */ for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { flash_info[i].flash_id = FLASH_UNKNOWN; - if (!flash_detect_legacy (bank_base[i], i)) - flash_get_size (bank_base[i], i); + if (!flash_detect_legacy (BANK_BASE(i), i)) + flash_get_size (BANK_BASE(i), i); size += flash_info[i].size; if (flash_info[i].flash_id == FLASH_UNKNOWN) { #ifndef CFG_FLASH_QUIET_TEST -- cgit v1.3.1 From f77d92a3f56d88e63cc02226a1204b3bdbac6961 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Sat, 9 Aug 2008 01:39:09 +0400 Subject: DataFlash: AT45DB021 fix and AT45DB081 support Fix for page size of AT45DB021. Also adding bigger AT45DB081 which comes with some newer boards. Signed-off-by: Sergey Lapin --- drivers/mtd/dataflash.c | 15 ++++++++++++++- include/dataflash.h | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/dataflash.c b/drivers/mtd/dataflash.c index 0ad48cdae91..049da69fec3 100644 --- a/drivers/mtd/dataflash.c +++ b/drivers/mtd/dataflash.c @@ -56,7 +56,7 @@ int AT91F_DataflashInit (void) switch (dfcode) { case AT45DB021: dataflash_info[i].Device.pages_number = 1024; - dataflash_info[i].Device.pages_size = 263; + dataflash_info[i].Device.pages_size = 264; dataflash_info[i].Device.page_offset = 9; dataflash_info[i].Device.byte_mask = 0x300; dataflash_info[i].Device.cs = cs[i].cs; @@ -65,6 +65,19 @@ int AT91F_DataflashInit (void) dataflash_info[i].id = dfcode; found[i] += dfcode;; break; + + case AT45DB081: + dataflash_info[i].Device.pages_number = 4096; + dataflash_info[i].Device.pages_size = 264; + dataflash_info[i].Device.page_offset = 9; + dataflash_info[i].Device.byte_mask = 0x300; + dataflash_info[i].Device.cs = cs[i].cs; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i].addr; + dataflash_info[i].id = dfcode; + found[i] += dfcode;; + break; + case AT45DB161: dataflash_info[i].Device.pages_number = 4096; dataflash_info[i].Device.pages_size = 528; diff --git a/include/dataflash.h b/include/dataflash.h index 80f0633aa94..de041397d35 100644 --- a/include/dataflash.h +++ b/include/dataflash.h @@ -135,9 +135,9 @@ struct dataflash_addr { int cs; }; /*-------------------------------------------------------------------------------------------------*/ - #define AT45DB161 0x2c #define AT45DB021 0x14 +#define AT45DB081 0x24 #define AT45DB321 0x34 #define AT45DB642 0x3c #define AT45DB128 0x10 -- cgit v1.3.1 From d9015f6a50d7258125349ef5c2af836458a0029a Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 8 Aug 2008 18:00:39 +0200 Subject: video: fix bug in logo_plot If logo_plot() should ever be called with x starting position other than zero and for pixel depths greater than 8bpp, logo colors distortion will be observed. This patch fixes the issue. Signed-off-by: Anatolij Gustschin --- drivers/video/cfb_console.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 68b9861d41f..97a37ba50c7 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -1071,7 +1071,9 @@ void logo_plot (void *screen, int width, int x, int y) int ycount = VIDEO_LOGO_HEIGHT; unsigned char r, g, b, *logo_red, *logo_blue, *logo_green; unsigned char *source; - unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x); + unsigned char *dest = (unsigned char *)screen + + ((y * width * VIDEO_PIXEL_SIZE) + + x * VIDEO_PIXEL_SIZE); #ifdef CONFIG_VIDEO_BMP_LOGO source = bmp_logo_bitmap; -- cgit v1.3.1 From e84d568fa2a9f4ce7888141e71676368ef6b3f25 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Fri, 8 Aug 2008 18:00:40 +0200 Subject: video: fix bug in cfb_console code FILL_15BIT_555RGB macro extension for pixel swapping by commit bed53753dd1d7e6bcbea4339be0fb7760214cc35 introduced a bug in cfb_console: Bitmaps with odd-numbered width won't be rendered correctly and even U-Boot crashes are observed on some platforms while repeated rendering of such bitmaps with "bmp display". Also if a bitmap is rendered to an odd-numbered x starting position, the same problem occurs. This patch is an attempt to fix it. Signed-off-by: Anatolij Gustschin --- drivers/video/cfb_console.c | 59 +++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index 97a37ba50c7..d313e9098c9 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -751,24 +751,10 @@ void video_puts (const char *s) fb ++; \ } -#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP) #define FILL_15BIT_555RGB(r,g,b) { \ *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \ fb += 2; \ } -#else -static int tgl; -static unsigned short p0; -#define FILL_15BIT_555RGB(r,g,b) { \ - if (!tgl++) { \ - p0 = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \ - } else { \ - tgl=0; \ - *(unsigned long *)(fb-2) = (SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3)))<<16) | p0; \ - } \ - fb += 2; \ -} -#endif #define FILL_16BIT_565RGB(r,g,b) { \ *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \ @@ -796,6 +782,20 @@ static unsigned short p0; } #endif +#if defined(VIDEO_FB_16BPP_PIXEL_SWAP) +static void inline fill_555rgb_pswap(uchar *fb, int x, + u8 r, u8 g, u8 b) +{ + ushort *dst = (ushort *)fb; + ushort color = (ushort)(((r >> 3) << 10) | + ((g >> 3) << 5) | + (b >> 3)); + if (x & 1) + *(--dst) = color; + else + *(++dst) = color; +} +#endif /* * Display the BMP file located at address bmp_image. @@ -927,11 +927,20 @@ int video_display_bitmap (ulong bmp_image, int x, int y) break; case GDF_15BIT_555RGB: while (ycount--) { +#if defined(VIDEO_FB_16BPP_PIXEL_SWAP) + int xpos = x; +#endif WATCHDOG_RESET (); xcount = width; while (xcount--) { cte = bmp->color_table[*bmap++]; +#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP) FILL_15BIT_555RGB (cte.red, cte.green, cte.blue); +#else + fill_555rgb_pswap (fb, xpos++, cte.red, + cte.green, cte.blue); + fb += 2; +#endif } bmap += padded_line; fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; @@ -993,10 +1002,19 @@ int video_display_bitmap (ulong bmp_image, int x, int y) break; case GDF_15BIT_555RGB: while (ycount--) { +#if defined(VIDEO_FB_16BPP_PIXEL_SWAP) + int xpos = x; +#endif WATCHDOG_RESET (); xcount = width; while (xcount--) { +#if !defined(VIDEO_FB_16BPP_PIXEL_SWAP) FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]); +#else + fill_555rgb_pswap (fb, xpos++, bmap[2], + bmap[1], bmap[0]); + fb += 2; +#endif bmap += 3; } bmap += padded_line; @@ -1103,6 +1121,9 @@ void logo_plot (void *screen, int width, int x, int y) } while (ycount--) { +#if defined(VIDEO_FB_16BPP_PIXEL_SWAP) + int xpos = x; +#endif xcount = VIDEO_LOGO_WIDTH; while (xcount--) { r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET]; @@ -1121,15 +1142,7 @@ void logo_plot (void *screen, int width, int x, int y) *(unsigned short *) dest = SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3))); #else - { - if (!tgl++) { - p0 = SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3))); - } else { - *(unsigned long *)(dest-2) = - (SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)))<<16) | p0; - tgl=0; - } - } + fill_555rgb_pswap (dest, xpos++, r, g, b); #endif break; case GDF_16BIT_565RGB: -- cgit v1.3.1 From 4d57b0fb2927d4f50d834884b4ec4a7ca01708b0 Mon Sep 17 00:00:00 2001 From: Steve Sakoman Date: Mon, 11 Aug 2008 20:26:16 +0200 Subject: OneNAND: Remove unused parameters to onenand_verify_page The block and page parameters of onenand_verify_page() are not used. This causes a compiler error when CONFIG_MTD_ONENAND_VERIFY_WRITE is enabled. Signed-off-by: Steve Sakoman Signed-off-by: Dirk Behme --- drivers/mtd/onenand/onenand_base.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index d32e3825580..a7054aebca6 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -680,13 +680,11 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, * onenand_verify_page - [GENERIC] verify the chip contents after a write * @param mtd MTD device structure * @param buf the databuffer to verify - * @param block block address - * @param page page address * * Check DataRAM area directly */ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf, - loff_t addr, int block, int page) + loff_t addr) { struct onenand_chip *this = mtd->priv; void __iomem *dataram0, *dataram1; @@ -783,7 +781,7 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, written += thislen; /* Only check verify write turn on */ - ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page); + ret = onenand_verify_page(mtd, (u_char *) buf, to); if (ret) { MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_ecc: verify failed %d\n", ret); -- cgit v1.3.1 From 3cf8a234b8e8c02e4da1f23566043bc288b05220 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 11 Aug 2008 09:16:25 -0500 Subject: Fix compile error related to r8a66597-hcd & usb When building the 8544DS board we get this error: In file included from r8a66597-hcd.c:22: u-boot/include/usb.h:190:2: error: #error USB Lowlevel not defined make[1]: *** [r8a66597-hcd.o] Error 1 The cleanest fix is to only build r8a66597-hcd.c if CONFIG_USB_R8A66597_HCD is set. Signed-off-by: Kumar Gala --- drivers/usb/Makefile | 3 ++- drivers/usb/r8a66597-hcd.c | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 2bdbb59cd56..c67a490f0a9 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -25,10 +25,11 @@ include $(TOPDIR)/config.mk LIB := $(obj)libusb.a +COBJS-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o + COBJS-y += isp116x-hcd.o COBJS-y += sl811_usb.o COBJS-y += usb_ohci.o -COBJS-y += r8a66597-hcd.o COBJS-y += usbdcore.o COBJS-y += usbdcore_ep0.o COBJS-y += usbdcore_mpc8xx.o diff --git a/drivers/usb/r8a66597-hcd.c b/drivers/usb/r8a66597-hcd.c index 3eb4cb03f08..0d3931e10f3 100644 --- a/drivers/usb/r8a66597-hcd.c +++ b/drivers/usb/r8a66597-hcd.c @@ -24,8 +24,6 @@ #include "r8a66597.h" -#if defined(CONFIG_USB_R8A66597_HCD) - #ifdef R8A66597_DEBUG #define R8A66597_DPRINT printf #else @@ -919,6 +917,3 @@ int usb_lowlevel_stop(void) return 0; } - -#endif /* CONFIG_USB_R8A66597_HCD */ - -- cgit v1.3.1 From cd82919e6c8a73b363a26f34b734923844e52d1c Mon Sep 17 00:00:00 2001 From: Wolfgang Denk Date: Tue, 12 Aug 2008 16:08:38 +0200 Subject: Coding style cleanup, update CHANGELOG, prepare release Signed-off-by: Wolfgang Denk --- CHANGELOG | 588 +++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- drivers/usb/r8a66597.h | 4 - include/configs/FPS850L.h | 2 +- include/configs/FPS860L.h | 2 +- include/configs/TQM823L.h | 2 +- include/configs/TQM823M.h | 2 +- include/configs/TQM850L.h | 2 +- include/configs/TQM850M.h | 2 +- include/configs/TQM855L.h | 2 +- include/configs/TQM855M.h | 2 +- include/configs/TQM860L.h | 2 +- include/configs/TQM860M.h | 2 +- include/configs/TQM862L.h | 2 +- include/configs/TQM862M.h | 2 +- include/configs/TQM866M.h | 2 +- include/configs/virtlab2.h | 2 +- 17 files changed, 603 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/CHANGELOG b/CHANGELOG index 7ff1a8af936..aa1bdc31f8d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,579 @@ +commit 17e900b8c0f38d922da47073246219dce2a847f2 +Author: Wolfgang Denk +Date: Tue Aug 12 14:54:04 2008 +0200 + + MVBC_P: fix compile problem + + Signed-off-by: Wolfgang Denk + +commit 52b047ae48219b59bebe37ba743ab103fd4f8316 +Author: Wolfgang Denk +Date: Tue Aug 12 12:10:11 2008 +0200 + + MPC8272ADS: fix build error: 'bd_t' has no member named 'pci_clk' + + Signed-off-by: Wolfgang Denk + +commit c9c101c660b3d1995045c61c7c6041f52b6cf335 +Author: Wolfgang Denk +Date: Tue Aug 12 00:36:53 2008 +0200 + + ads5121: fix compiler warnings (unused variables) + + Signed-off-by: Wolfgang Denk + +commit 902ca09246039964d59bbcb519b1e1b5aed01308 +Author: Kumar Gala +Date: Mon Aug 11 11:29:28 2008 -0500 + + 85xx: Rename CONFIG_NR_CPUS to CONFIG_NUM_CPUS + + Use CONFIG_NUM_CPUS to match existing define used by 86xx. + + Signed-off-by: Kumar Gala + Acked-by: Jon Loeliger + +commit 3216ca9692ff80d7c638723ef448f3d36301d9e7 +Author: Kumar Gala +Date: Mon Aug 11 09:20:53 2008 -0500 + + Fix fallout from autostart revert + + The autostart revert caused a bit of duplicated code as well as + code that was using images->autostart that needs to get removed so + we can build again. + + Signed-off-by: Kumar Gala + +commit 3cf8a234b8e8c02e4da1f23566043bc288b05220 +Author: Kumar Gala +Date: Mon Aug 11 09:16:25 2008 -0500 + + Fix compile error related to r8a66597-hcd & usb + + When building the 8544DS board we get this error: + + In file included from r8a66597-hcd.c:22: + u-boot/include/usb.h:190:2: error: #error USB Lowlevel not defined + make[1]: *** [r8a66597-hcd.o] Error 1 + + The cleanest fix is to only build r8a66597-hcd.c if CONFIG_USB_R8A66597_HCD + is set. + + Signed-off-by: Kumar Gala + +commit 2d0daa03612338a813e3c9d22680e54eabfea378 +Author: Becky Bruce +Date: Mon Aug 4 14:02:26 2008 -0500 + + POWERPC 86xx: Move BAT setup code to C + + This is needed because we will be possibly be locating + devices at physical addresses above 32bits, and the asm + preprocessing does not appear to deal with ULL constants + properly. We now call write_bat in lib_ppc/bat_rw.c. + + Signed-off-by: Becky Bruce + Acked-by: Jon Loeliger + +commit 9de67149db576c91b9c2a0a182652331e7e44211 +Author: Becky Bruce +Date: Mon Aug 4 14:01:53 2008 -0500 + + POWERPC: Add synchronization to write_bat in lib_ppc/bat_rw.c + + Perform sync/isync as required by the architecture. + + Signed-off-by: Becky Bruce + Acked-by: Jon Loeliger + +commit 23f935c073e7578c6066804fd2f9ee116cae6ffe +Author: Becky Bruce +Date: Mon Aug 4 14:01:16 2008 -0500 + + POWERPC: 86xx - add missing CONFIG_HIGH_BATS to sbc8641d config + + Signed-off-by: Becky Bruce + Acked-by: Jon Loeliger + +commit 5276a3584d26a9533404f0ec00c3b61cf9a97939 +Author: Magnus Lilja +Date: Sun Aug 3 21:44:10 2008 +0200 + + i.MX31: Fix mx31_gpio_mux() function and MUX_-macros. + + Correct the mx31_gpio_mux() function to allow changing all i.MX31 IOMUX + contacts instead of only the first 256 ones as is the case prior to + this patch. + + Add missing MUX_* macros and update board files to use the new macros. + + Signed-off-by: Magnus Lilja + +commit b6b183c5b2fffd4c456b7e3fcb064cceb47fe7ac +Author: Magnus Lilja +Date: Sun Aug 3 21:43:37 2008 +0200 + + i.MX31: Fix IOMUX related typos + + Correct the names of some IOMUX macros. + + Signed-off-by: Magnus Lilja + +commit 4d57b0fb2927d4f50d834884b4ec4a7ca01708b0 +Author: Steve Sakoman +Date: Mon Aug 11 20:26:16 2008 +0200 + + OneNAND: Remove unused parameters to onenand_verify_page + + The block and page parameters of onenand_verify_page() are not used. This causes a compiler error when CONFIG_MTD_ONENAND_VERIFY_WRITE is enabled. + + Signed-off-by: Steve Sakoman + Signed-off-by: Dirk Behme + +commit e84d568fa2a9f4ce7888141e71676368ef6b3f25 +Author: Anatolij Gustschin +Date: Fri Aug 8 18:00:40 2008 +0200 + + video: fix bug in cfb_console code + + FILL_15BIT_555RGB macro extension for pixel swapping + by commit bed53753dd1d7e6bcbea4339be0fb7760214cc35 + introduced a bug in cfb_console: + + Bitmaps with odd-numbered width won't be rendered + correctly and even U-Boot crashes are observed on + some platforms while repeated rendering of such + bitmaps with "bmp display". Also if a bitmap is + rendered to an odd-numbered x starting position, + the same problem occurs. This patch is an attempt + to fix it. + + Signed-off-by: Anatolij Gustschin + +commit d9015f6a50d7258125349ef5c2af836458a0029a +Author: Anatolij Gustschin +Date: Fri Aug 8 18:00:39 2008 +0200 + + video: fix bug in logo_plot + + If logo_plot() should ever be called with x starting + position other than zero and for pixel depths greater + than 8bpp, logo colors distortion will be observed. + This patch fixes the issue. + + Signed-off-by: Anatolij Gustschin + +commit 406819ae94f79f5b59e01d163380ca7d83709251 +Author: Wolfgang Denk +Date: Mon Aug 11 00:17:52 2008 +0200 + + MAINTAINERS: sort entries + + Signed-off-by: Wolfgang Denk + +commit cfc442d7913d4d1c3a9bf494f90c012c2f8c3bdc +Author: Roy Zang +Date: Thu Aug 7 18:19:28 2008 +0800 + + Add mpc7448hpc2 maintainer information + + Signed-off-by: Roy Zang + +commit a9fe0c3e7ca48afa50d6a0db99fa91e7282d73d8 +Author: Gururaja Hebbar K R +Date: Thu Aug 7 13:13:27 2008 +0530 + + common/cmd_load.c - Minor code & Coding Style cleanup + + - os_data_header Variable is a carry over feature + & unused. So removed all instance of this variable + - Minor Code Style Update + + Signed-off-by: Gururaja Hebbar + Acked-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 0d28f34bbe56d0971bd603789dcc6fe7adf11f14 +Author: Magnus Lilja +Date: Wed Aug 6 19:32:33 2008 +0200 + + Update the U-Boot wiki URL. + + Signed-off-by: Magnus Lilja + +commit aa5ffa16d7e4c461b7b77bf8e79d2ef5638cf754 +Author: dirk.behme@googlemail.com +Date: Sun Aug 10 17:56:36 2008 +0200 + + OneNAND: Remove base address offset usage + + While locally preparing some U-Boot patches for ARM based OMAP3 boards, some + using OneNAND and some using NAND, we found some differences in OneNAND and + NAND command address handling. + + As this might confuse users (it already confused us), we like to align OneNAND + and NAND address handling. + + The issue is that cmd_onenand.c subtracts the onenand base address from the + addresses you type into the u-boot command line so, unlike nand, you can't + use addresses relative to the start of the onenand part e.g. this won't work: + + onenand read 82000000 280000 400000 + + you have to use: + + onenand read 82000000 20280000 400000 + + Looking at recent git, the only board currently using OneNAND is Apollon, and + for this the OneNAND base address is 0 (apollon.h) + + #define CFG_ONENAND_BASE 0x00000000 + + so patch below won't break any existing boards and will align OneNAND and NAND + handling on boards where OneNAND base address is != 0. + + Signed-off-by: Steve Sakoman + Signed-off-by: Manikandan Pillai + Signed-off-by: Dirk Behme + +commit c11528083ef6e55e76df742228c26e39d151813d +Author: Kumar Gala +Date: Thu Aug 7 09:28:20 2008 -0500 + + mpc85xx: workaround old binutils bug + + The recent change to move the .bss outside of the image gives older + binutils (ld from eldk4.1/binutils-2.16) some headache: + + ppc_85xx-ld: u-boot: Not enough room for program headers (allocated 3, need 4) + ppc_85xx-ld: final link failed: Bad value + + We workaround it by being explicit about the program headers and not + assigning the .bss to a program header. + + Signed-off-by: Kumar Gala + +commit 0bf202ec586d4466c900e987720fa635c594d689 +Author: Wolfgang Denk +Date: Sun Aug 10 01:26:26 2008 +0200 + + Revert "[new uImage] Add autostart flag to bootm_headers structure" + + This reverts commit f5614e7926863bf0225ec860d9b319741a9c4004. + + The commit was based on a misunderstanding of the (documented) + meaning of the 'autostart' environment variable. It might cause + boards to hang if 'autostart' was used, with the potential to brick + them. Go back to the documented behaviour. + + Conflicts: + + common/cmd_bootm.c + common/image.c + include/image.h + + Signed-off-by: Wolfgang Denk + +commit 29f8f58ff40c67f7f2e11afd1715173094e52ac2 +Author: Wolfgang Denk +Date: Sat Aug 9 23:17:32 2008 +0200 + + TQM8xx{L,M}: try to normalize config files for TQM8xx? based board + + - enable CFI driver where this was forgotten + - enable mtdparts support + - adjust default environment + etc. + + Signed-off-by: Wolfgang Denk + +commit 41266c9b5a5f873df3ec891bb0907616958b5602 +Author: Peter Tyser +Date: Tue Aug 5 10:51:57 2008 -0500 + + FIT: Fix handling of images without ramdisks + + boot_get_ramdisk() should not treat the case when a FIT image does + not contain a ramdisk as an error. + + Signed-off-by: Peter Tyser + Acked-by: Michal Simek + +commit f77d92a3f56d88e63cc02226a1204b3bdbac6961 +Author: Sergey Lapin +Date: Sat Aug 9 01:39:09 2008 +0400 + + DataFlash: AT45DB021 fix and AT45DB081 support + + Fix for page size of AT45DB021. Also adding bigger AT45DB081 + which comes with some newer boards. + + Signed-off-by: Sergey Lapin + +commit ba9324451b662dd393afa53e5cc36fc5d3d10966 +Author: Nobuhiro Iwamatsu +Date: Fri Aug 8 16:30:23 2008 +0900 + + sh: Update sh7763rdp config + + Add sh_eth support to sh7763rdp. + + Signed-off-by: Nobuhiro Iwamatsu + +commit 21f971ec265f6042ec21636d55d06a6bc0751077 +Author: Wolfgang Denk +Date: Mon Jul 7 01:22:29 2008 +0200 + + TQM823L: re-enable logo support; update LCD_INFO text + + Signed-off-by: Wolfgang Denk + +commit 3b8d17f0f082073346c0df017c9dfd6acdb40d6d +Author: Wolfgang Denk +Date: Fri Aug 8 16:41:56 2008 +0200 + + TQM8xxL: fix support for second flash bank + + When switching the TQM8xxL modules to use the CFI flash driver, + support for the second flash bank was broken because the CFI driver + did not support dynamically sized banks. This gets fixed now. + + Signed-off-by: Wolfgang Denk + +commit 2a112b234d879f6390503a5f4e38246acce9d0b0 +Author: Wolfgang Denk +Date: Fri Aug 8 16:39:54 2008 +0200 + + CFI: allow for dynamically determined flash sizes and addresses + + The CFI driver allowed only for static initializers in the + CFG_FLASH_BANKS_LIST definition, i. e. it did not allow to map + several flash banks contiguously if the bank sizes were not known in + advance, which kind of violates U-Boot's design philosophy. + + (will be used for example by the TQM8xxL boards) + + Signed-off-by: Wolfgang Denk + +commit d9d78ee46d9a396d0a81d00c2b003a9bd32c2e61 +Author: Ben Warren +Date: Thu Aug 7 23:26:35 2008 -0700 + + QE UEC: Fix compiler warnings + + Moved static functions earlier in file so forward declarations are not needed. + + Signed-off-by: Ben Warren + +commit d5d28fe4aad5f4535400647a5617c11039506467 +Author: David Saada +Date: Mon Mar 31 02:37:38 2008 -0700 + + QE UEC: Add MII Commands + + Add MII commands to the UEC driver. Note that once a UEC device is selected, + any device on its MDIO bus can be addressed. + + Signed-off-by: David Saada + Signed-off-by: Ben Warren + +commit fd0f2f3796ff2a7a32d35deb1b7996e485849df7 +Author: Yoshihiro Shimoda +Date: Wed Jul 9 21:07:38 2008 +0900 + + usb: add support for R8A66597 usb controller + + add support for Renesas R8A66597 usb controller. + This patch supports USB Host mode. + + Signed-off-by: Yoshihiro Shimoda + Signed-off-by: Markus Klotzbuecher + +commit 1d10dcd041aaeae9fd7c821005692898a0303382 +Author: Hunter, Jon +Date: Sat Jul 26 18:59:16 2008 -0500 + + Add support for OMAP5912 and OMAP16xx to usbdcore_omap1510.c + + Add support to drivers/usb/usbdcore_omap1510.c for OMAP5912 and OMAP16xx devices. + + Signed-off-by: Jon Hunter + Signed-off-by: Markus Klotzbuecher + +commit eab1007334b93a6209f1ec33615e26ef5311ede7 +Author: Steven A. Falco +Date: Wed Aug 6 15:42:52 2008 -0400 + + ppc4xx: Sequoia has two UARTs in "4-pin" mode. Configure the GPIOs as per schematic. + + The Sequoia board has two UARTs in "4-pin" mode. This patch modifies the GPIO + configuration to match the schematic, and also sets the SDR0_PFC1 register to + select the corresponding mode for the UARTs. + + Signed-off-by: Steven A. Falco + Signed-off-by: Stefan Roese + +commit 6689484ccd43189322aaa5a1c6cd02cdd511ad7d +Author: Kenneth Johansson +Date: Tue Jul 15 12:13:38 2008 +0200 + + mpc5121: Move iopin features from board specific to common files. + + And in the process eliminate some duplicate register defines. + + Signed-off-by: Kenneth Johansson + +commit ef11df6b66ecf5797e94ba322254b8fb7a4e2e12 +Author: John Rigby +Date: Tue Aug 5 17:38:57 2008 -0600 + + mpc5121: squash some fdt fixup errors + + On ADS5121 when booting linux the following errors are seen: + Unable to update property /soc5121@80000000:bus-frequency, err=FDT_ERR_NOTFOUND + Unable to update property /soc5121@80000000/ethernet@2800:local-mac-address, err=FDT_ERR_NOTFOUND + Unable to update property /soc5121@80000000/ethernet@2800:address, err=FDT_ERR_NOTFOUND + + This is caused by ft_cpu_setup trying to deal with + both old and new soc node naming. This patch + fixes this by being smarter about what to + fixup. + + Also do soc node fixups by compatible instead of by path. + A new board config called OF_SOC_COMPAT defined + to be "fsl,mpc5121-immr" replaces the old + OF_SOC node path that was defined to be "soc@80000000". + + Old device trees still work, but the compatiblity + is conditional on CONFIG_OF_SUPPORT_OLD_DEVICE_TREES + which is on by default in include/configs/ads5121.h. + + Signed-off-by: John Rigby + +commit 81091f58f0c58ecd26c5b05de2ae20ca6cdb521c +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Aug 2 23:48:30 2008 +0200 + + drivers/serial: Move conditional compilation to Makefile for CONFIG_* macros + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 4cd7e6528f61ec669755c3754bb4f9779874fab3 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Aug 2 23:48:32 2008 +0200 + + nios2/sysid: fix printf warning + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 66da6fa0e35e7ee56628c85981709afe7180fc8e +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Aug 2 23:48:33 2008 +0200 + + Fix remaining build issues with MPC8xx FADS boards. + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 81d3f1fdddafd1eb53bbca8739f488d417eb3dd2 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Aug 2 23:48:31 2008 +0200 + + nios2: fix phys_addr_t and phys_size_t support + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 5fa62000db6d0b46ecdeadbeb50faf5197db49ef +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Sat Aug 2 23:48:34 2008 +0200 + + mvbc_p: Fix problem with '#if (CONFIG_CMD_KGDB)' + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit 1464eff77e7fdaed609ecf263a2423c9dcf96b1f +Author: Mark Jackson +Date: Fri Aug 1 09:48:29 2008 +0100 + + Fix bitmap display for atmel lcd controller + + The current lcd_display_bitmap() function does not work properly + for the Atmel LCD controller. + + 2 fixes need to be done:- + + (a) when setting the colour map, use the lcd_setcolreg() function + as provided by the Atmel driver + (b) the data is never actually written to the lcd framebuffer !! + + Signed-off-by: Mark Jackson + +commit 2a433c66b1e2770349fe4911be23c375f053ebd8 +Author: Jean-Christophe PLAGNIOL-VILLARD +Date: Fri Aug 1 08:40:34 2008 +0200 + + qemu_mips: update README to follow qemu update about default machine + + Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD + +commit ac169d645f5f0e0b9a232563099209e92a355d8e +Author: TsiChung Liew +Date: Thu Jul 31 19:53:21 2008 -0500 + + ColdFire: Fix compilation issue caused by a missing function + + Implement usec2ticks() which is used by fsl_i2c.c in + lib_m68k/time.c + + Signed-off-by: TsiChung Liew + +commit 01ae85b58b51d2fb1fac5b93095f6042cf48ae7b +Author: TsiChung Liew +Date: Thu Jul 31 19:53:06 2008 -0500 + + Fix compilation error for TASREG + + TASREG is ColdFire platform, the include ppc4xx.h in + board/esd/common/flash.c causes conflict. + + Signed-off-by: TsiChung Liew + +commit 35d3bd3cc35c508a6823dac77e0fd126808e4fc7 +Author: TsiChung Liew +Date: Thu Jul 31 19:52:36 2008 -0500 + + Fix compilation error for MCF5275 + + Rename OBJ to COBJ in board/platform/Makefile + + Signed-off-by: TsiChung Liew + +commit 5c40548f01218360a1f1395198c50ff45f3035b5 +Author: TsiChung Liew +Date: Thu Jul 31 19:52:28 2008 -0500 + + Fix compile error caused by incorrect function return type + + Rename int mii_init(void) to void mii_init(void) for idmr + ColdFire platform + + Signed-off-by: TsiChung Liew + +commit a58c78067c928976c082c758d3987e89ead5b191 +Author: Wolfgang Denk +Date: Fri Aug 1 12:06:22 2008 +0200 + + Fix build issues with MPC8xx FADS boards. + + Signed-off-by: Wolfgang Denk + +commit 4b50cd12a3b3c644153c4cf393f4a4c12289e5aa +Author: Wolfgang Denk +Date: Thu Jul 31 17:54:03 2008 +0200 + + Prepare v1.3.4-rc2: update CHANGELOG + + Signed-off-by: Wolfgang Denk + commit a48311557db6e7e9473a6163b44bb1e6c6ed64c4 Author: Mark Jackson Date: Thu Jul 31 16:09:00 2008 +0100 @@ -5117,6 +5693,18 @@ Date: Mon May 5 14:06:11 2008 +0200 Signed-off-by: Jens Gehrlein Signed-off-by: Ben Warren +commit 6324e5bec8825f7fee3026ffbd394454ae8b53fb +Author: Christian Eggers +Date: Wed May 21 21:29:10 2008 +0200 + + Fix endianess conversion in usb_ohci.c + + Sorry, I forgot this line: + + Signed-off-by: Christian Eggers + + I think this must be swapped (result may be equal). + commit c918261c6d9f265f88baf70f8a73dfe6f0cb9596 Author: Christian Eggers Date: Wed May 21 22:12:00 2008 +0200 diff --git a/Makefile b/Makefile index 3179c6725b9..082b08e2c4c 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ VERSION = 1 PATCHLEVEL = 3 SUBLEVEL = 4 -EXTRAVERSION = -rc2 +EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) VERSION_FILE = $(obj)include/version_autogenerated.h diff --git a/drivers/usb/r8a66597.h b/drivers/usb/r8a66597.h index 54a1f26aefc..9af6446c134 100644 --- a/drivers/usb/r8a66597.h +++ b/drivers/usb/r8a66597.h @@ -593,7 +593,6 @@ static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port, /* Our Vendor Specific Request */ #define RH_SET_EP 0x2000 - /* Hub port features */ #define RH_PORT_CONNECTION 0x00 #define RH_PORT_ENABLE 0x01 @@ -620,7 +619,6 @@ static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port, #define RH_REQ_ERR -1 #define RH_NACK 0x00 - /* OHCI ROOT HUB REGISTER MASKS */ /* roothub.portstatus [i] bits */ @@ -658,6 +656,4 @@ static inline void r8a66597_port_power(struct r8a66597 *r8a66597, int port, #define RH_A_NOCP (1 << 12) /* no over current protection */ #define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - #endif /* __R8A66597_H__ */ - diff --git a/include/configs/FPS850L.h b/include/configs/FPS850L.h index 66db2964952..79b71db75a6 100644 --- a/include/configs/FPS850L.h +++ b/include/configs/FPS850L.h @@ -221,7 +221,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/FPS860L.h b/include/configs/FPS860L.h index 84607ccc32d..ec757e2ff65 100644 --- a/include/configs/FPS860L.h +++ b/include/configs/FPS860L.h @@ -221,7 +221,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM823L.h b/include/configs/TQM823L.h index f807271ba65..9cc196410c3 100644 --- a/include/configs/TQM823L.h +++ b/include/configs/TQM823L.h @@ -235,7 +235,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM823M.h b/include/configs/TQM823M.h index 431ae8c5a23..5edd37935d5 100644 --- a/include/configs/TQM823M.h +++ b/include/configs/TQM823M.h @@ -231,7 +231,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM850L.h b/include/configs/TQM850L.h index 7946c13a1ce..9edf0d8072f 100644 --- a/include/configs/TQM850L.h +++ b/include/configs/TQM850L.h @@ -220,7 +220,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM850M.h b/include/configs/TQM850M.h index 777776d421b..e2c1ce80fad 100644 --- a/include/configs/TQM850M.h +++ b/include/configs/TQM850M.h @@ -220,7 +220,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM855L.h b/include/configs/TQM855L.h index 0549cbd94a6..dd19d4e5785 100644 --- a/include/configs/TQM855L.h +++ b/include/configs/TQM855L.h @@ -225,7 +225,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM855M.h b/include/configs/TQM855M.h index bc092b7f211..8a1c350cce3 100644 --- a/include/configs/TQM855M.h +++ b/include/configs/TQM855M.h @@ -260,7 +260,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h index 065156fe313..803cdb854c4 100644 --- a/include/configs/TQM860L.h +++ b/include/configs/TQM860L.h @@ -224,7 +224,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM860M.h b/include/configs/TQM860M.h index ff610bfe3ce..071da1e607d 100644 --- a/include/configs/TQM860M.h +++ b/include/configs/TQM860M.h @@ -225,7 +225,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h index 33ff8a909aa..d34f6bea649 100644 --- a/include/configs/TQM862L.h +++ b/include/configs/TQM862L.h @@ -228,7 +228,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM862M.h b/include/configs/TQM862M.h index 1ec44319eef..9270e449834 100644 --- a/include/configs/TQM862M.h +++ b/include/configs/TQM862M.h @@ -229,7 +229,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h index 0cee9f4fe4f..d916d533728 100644 --- a/include/configs/TQM866M.h +++ b/include/configs/TQM866M.h @@ -269,7 +269,7 @@ "128k(dtb)," \ "1920k(kernel)," \ "5632(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block diff --git a/include/configs/virtlab2.h b/include/configs/virtlab2.h index 54d9421d717..f1048861d86 100644 --- a/include/configs/virtlab2.h +++ b/include/configs/virtlab2.h @@ -229,7 +229,7 @@ "128k(dtb)," \ "1664k(kernel)," \ "2m(rootfs)," \ - "4m(data)" + "4m(data)" /*----------------------------------------------------------------------- * Hardware Information Block -- cgit v1.3.1 From cfa460adfdefcc30d104e1a9ee44994ee349bb7b Mon Sep 17 00:00:00 2001 From: William Juul Date: Wed, 31 Oct 2007 13:53:06 +0100 Subject: Update MTD to that of Linux 2.6.22.1 A lot changed in the Linux MTD code, since it was last ported from Linux to U-Boot. This patch takes U-Boot NAND support to the level of Linux 2.6.22.1 and will enable support for very large NAND devices (4KB pages) and ease the compatibility between U-Boot and Linux filesystems. This patch is tested on two custom boards with PPC and ARM processors running YAFFS in U-Boot and Linux using gcc-4.1.2 cross compilers. MAKEALL ppc/arm has some issues: * DOC/OneNand/nand_spl is not building (I have not tried porting these parts, and since I do not have any HW and I am not familiar with this code/HW I think its best left to someone else.) Except for the issues mentioned above, I have ported all drivers necessary to run MAKEALL ppc/arm without errors and warnings. Many drivers were trivial to port, but some were not so trivial. The following drivers must be examined carefully and maybe rewritten to some degree: cpu/ppc4xx/ndfc.c cpu/arm926ejs/davinci/nand.c board/delta/nand.c board/zylonite/nand.c Signed-off-by: William Juul Signed-off-by: Stig Olsen Signed-off-by: Scott Wood --- board/bf537-stamp/nand.c | 43 +- board/dave/PPChameleonEVB/nand.c | 49 +- board/delta/nand.c | 41 +- board/esd/common/esd405ep_nand.c | 42 +- board/freescale/m5329evb/nand.c | 42 +- board/nc650/nand.c | 78 +- board/netstar/nand.c | 20 +- board/prodrive/alpr/nand.c | 59 +- board/prodrive/pdnb3/nand.c | 53 +- board/sc3/sc3nand.c | 44 +- board/tqc/tqm8272/tqm8272.c | 34 +- board/zylonite/nand.c | 39 +- common/cmd_doc.c | 4 + common/cmd_nand.c | 273 ++- cpu/arm926ejs/davinci/nand.c | 41 +- cpu/ppc4xx/ndfc.c | 57 +- drivers/mtd/nand/diskonchip.c | 554 +++--- drivers/mtd/nand/nand_base.c | 3513 +++++++++++++++++++------------------- drivers/mtd/nand/nand_bbt.c | 548 ++++-- drivers/mtd/nand/nand_ecc.c | 21 +- drivers/mtd/nand/nand_ids.c | 91 +- drivers/mtd/nand/nand_util.c | 359 ++-- include/common.h | 2 + include/linux/err.h | 45 + include/linux/mtd/blktrans.h | 81 + include/linux/mtd/compat.h | 7 +- include/linux/mtd/doc2000.h | 217 ++- include/linux/mtd/inftl-user.h | 91 + include/linux/mtd/jffs2-user.h | 35 + include/linux/mtd/mtd-abi.h | 137 +- include/linux/mtd/mtd.h | 150 +- include/linux/mtd/nand.h | 450 +++-- include/linux/mtd/nftl-user.h | 76 + include/linux/mtd/nftl.h | 93 +- include/linux/mtd/ubi-header.h | 360 ++++ include/linux/mtd/ubi-user.h | 161 ++ include/nand.h | 3 +- 37 files changed, 4653 insertions(+), 3260 deletions(-) create mode 100644 include/linux/err.h create mode 100644 include/linux/mtd/blktrans.h create mode 100644 include/linux/mtd/inftl-user.h create mode 100644 include/linux/mtd/jffs2-user.h create mode 100644 include/linux/mtd/nftl-user.h create mode 100644 include/linux/mtd/ubi-header.h create mode 100644 include/linux/mtd/ubi-user.h (limited to 'drivers') diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index 6ff0f4f96c4..bdf1d6ee456 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -37,34 +37,29 @@ /* * hardware specific access to control-lines */ -static void bfin_hwcontrol(struct mtd_info *mtd, int cmd) +static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { register struct nand_chip *this = mtd->priv; + u32 IO_ADDR_W = (u32) this->IO_ADDR_W; - switch (cmd) { - - case NAND_CTL_SETCLE: - this->IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_CLE; - break; - case NAND_CTL_CLRCLE: - this->IO_ADDR_W = CFG_NAND_BASE; - break; - - case NAND_CTL_SETALE: - this->IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_ALE; - break; - case NAND_CTL_CLRALE: - this->IO_ADDR_W = CFG_NAND_BASE; - break; - case NAND_CTL_SETNCE: - case NAND_CTL_CLRNCE: - break; + if (ctrl & NAND_CTRL_CHANGE) { + if( ctrl & NAND_CLE ) + IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_CLE; + else + IO_ADDR_W = CFG_NAND_BASE; + if( ctrl & NAND_ALE ) + IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_ALE; + else + IO_ADDR_W = CFG_NAND_BASE; + this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } - this->IO_ADDR_R = this->IO_ADDR_W; /* Drain the writebuffer */ SSYNC(); + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } int bfin_device_ready(struct mtd_info *mtd) @@ -79,11 +74,11 @@ int bfin_device_ready(struct mtd_info *mtd) * argument are board-specific (per include/linux/mtd/nand.h): * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - hwcontrol: hardwarespecific function for accesing control-lines + * - cmd_ctrl: hardwarespecific function for accesing control-lines * - dev_ready: hardwarespecific function for accesing device ready/busy line * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must * only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines + * - ecc.mode: mode of ecc, see defines * - chip_delay: chip dependent delay for transfering data from array to * read regs (tR) * - options: various chip options. They can partly be set to inform @@ -98,8 +93,8 @@ void board_nand_init(struct nand_chip *nand) *PORT(CONFIG_NAND_GPIO_PORT, IO_DIR) &= ~BFIN_NAND_READY; *PORT(CONFIG_NAND_GPIO_PORT, IO_INEN) |= BFIN_NAND_READY; - nand->hwcontrol = bfin_hwcontrol; - nand->eccmode = NAND_ECC_SOFT; + nand->cmd_ctrl = bfin_hwcontrol; + nand->ecc.mode = NAND_ECC_SOFT; nand->dev_ready = bfin_device_ready; nand->chip_delay = 30; } diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index 09c0b043e7f..4bc4257c889 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -21,7 +21,7 @@ */ #include - +#include #if defined(CONFIG_CMD_NAND) @@ -31,31 +31,28 @@ * hardware specific access to control-lines * function borrowed from Linux 2.6 (drivers/mtd/nand/ppchameleonevb.c) */ -static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtdinfo->priv; + struct nand_chip *this = mtd->priv; ulong base = (ulong) this->IO_ADDR_W; - switch(cmd) { - case NAND_CTL_SETCLE: - MACRO_NAND_CTL_SETCLE((unsigned long)base); - break; - case NAND_CTL_CLRCLE: - MACRO_NAND_CTL_CLRCLE((unsigned long)base); - break; - case NAND_CTL_SETALE: - MACRO_NAND_CTL_SETALE((unsigned long)base); - break; - case NAND_CTL_CLRALE: - MACRO_NAND_CTL_CLRALE((unsigned long)base); - break; - case NAND_CTL_SETNCE: - MACRO_NAND_ENABLE_CE((unsigned long)base); - break; - case NAND_CTL_CLRNCE: - MACRO_NAND_DISABLE_CE((unsigned long)base); - break; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + MACRO_NAND_CTL_SETCLE((unsigned long)base); + else + MACRO_NAND_CTL_CLRCLE((unsigned long)base); + if ( ctrl & NAND_ALE ) + MACRO_NAND_CTL_CLRCLE((unsigned long)base); + else + MACRO_NAND_CTL_CLRALE((unsigned long)base); + if ( ctrl & NAND_NCE ) + MACRO_NAND_ENABLE_CE((unsigned long)base); + else + MACRO_NAND_DISABLE_CE((unsigned long)base); } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } @@ -92,11 +89,11 @@ static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo) * argument are board-specific (per include/linux/mtd/nand.h): * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - hwcontrol: hardwarespecific function for accesing control-lines + * - cmd_ctrl: hardwarespecific function for accesing control-lines * - dev_ready: hardwarespecific function for accesing device ready/busy line * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must * only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines + * - ecc.mode: mode of ecc, see defines * - chip_delay: chip dependent delay for transfering data from array to * read regs (tR) * - options: various chip options. They can partly be set to inform @@ -108,9 +105,9 @@ static int ppchameleonevb_device_ready(struct mtd_info *mtdinfo) int board_nand_init(struct nand_chip *nand) { - nand->hwcontrol = ppchameleonevb_hwcontrol; + nand->cmd_ctrl = ppchameleonevb_hwcontrol; nand->dev_ready = ppchameleonevb_device_ready; - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; nand->chip_delay = NAND_BIG_DELAY_US; nand->options = NAND_SAMSUNG_LP_OPTIONS; return 0; diff --git a/board/delta/nand.c b/board/delta/nand.c index 5024056bc34..51520f5fb03 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -69,7 +69,7 @@ static struct nand_oobinfo delta_oob = { /* * not required for Monahans DFC */ -static void dfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void dfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { return; } @@ -110,30 +110,6 @@ static void dfc_write_buf(struct mtd_info *mtd, const u_char *buf, int len) } -/* - * These functions are quite problematic for the DFC. Luckily they are - * not used in the current nand code, except for nand_command, which - * we've defined our own anyway. The problem is, that we always need - * to write 4 bytes to the DFC Data Buffer, but in these functions we - * don't know if to buffer the bytes/half words until we've gathered 4 - * bytes or if to send them straight away. - * - * Solution: Don't use these with Mona's DFC and complain loudly. - */ -static void dfc_write_word(struct mtd_info *mtd, u16 word) -{ - printf("dfc_write_word: WARNING, this function does not work with the Monahans DFC!\n"); -} -static void dfc_write_byte(struct mtd_info *mtd, u_char byte) -{ - printf("dfc_write_byte: WARNING, this function does not work with the Monahans DFC!\n"); -} - -/* The original: - * static void dfc_read_buf(struct mtd_info *mtd, const u_char *buf, int len) - * - * Shouldn't this be "u_char * const buf" ? - */ static void dfc_read_buf(struct mtd_info *mtd, u_char* const buf, int len) { int i=0, j; @@ -168,7 +144,7 @@ static void dfc_read_buf(struct mtd_info *mtd, u_char* const buf, int len) */ static u16 dfc_read_word(struct mtd_info *mtd) { - printf("dfc_write_byte: UNIMPLEMENTED.\n"); + printf("dfc_read_word: UNIMPLEMENTED.\n"); return 0; } @@ -289,9 +265,10 @@ static void dfc_new_cmd(void) /* this function is called after Programm and Erase Operations to * check for success or failure */ -static int dfc_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int dfc_wait(struct mtd_info *mtd, struct nand_chip *this) { unsigned long ndsr=0, event=0; + int state = this->state; if(state == FL_WRITING) { event = NDSR_CS0_CMDD | NDSR_CS0_BBD; @@ -439,7 +416,7 @@ static void dfc_gpio_init(void) * - dev_ready: hardwarespecific function for accesing device ready/busy line * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must * only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines + * - ecc.mode: mode of ecc, see defines * - chip_delay: chip dependent delay for transfering data from array to * read regs (tR) * - options: various chip options. They can partly be set to inform @@ -561,20 +538,18 @@ int board_nand_init(struct nand_chip *nand) /* wait(10); */ - nand->hwcontrol = dfc_hwcontrol; + nand->cmd_ctrl = dfc_hwcontrol; /* nand->dev_ready = dfc_device_ready; */ - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; nand->options = NAND_BUSWIDTH_16; nand->waitfunc = dfc_wait; nand->read_byte = dfc_read_byte; - nand->write_byte = dfc_write_byte; nand->read_word = dfc_read_word; - nand->write_word = dfc_write_word; nand->read_buf = dfc_read_buf; nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; - nand->autooob = &delta_oob; +// nand->autooob = &delta_oob; nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/board/esd/common/esd405ep_nand.c b/board/esd/common/esd405ep_nand.c index 7bf68473d28..4bf81ab4aac 100644 --- a/board/esd/common/esd405ep_nand.c +++ b/board/esd/common/esd405ep_nand.c @@ -30,28 +30,26 @@ /* * hardware specific access to control-lines */ -static void esd405ep_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch(cmd) { - case NAND_CTL_SETCLE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CLE); - break; - case NAND_CTL_CLRCLE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CLE); - break; - case NAND_CTL_SETALE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_ALE); - break; - case NAND_CTL_CLRALE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_ALE); - break; - case NAND_CTL_SETNCE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CE); - break; - case NAND_CTL_CLRNCE: - out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); - break; + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CLE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CLE); + if ( ctrl & NAND_ALE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_ALE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_ALE); + if ( ctrl & NAND_NCE ) + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CFG_NAND_CE); + else + out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } @@ -77,9 +75,9 @@ int board_nand_init(struct nand_chip *nand) /* * Initialize nand_chip structure */ - nand->hwcontrol = esd405ep_nand_hwcontrol; + nand->cmd_ctrl = esd405ep_nand_hwcontrol; nand->dev_ready = esd405ep_nand_device_ready; - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; nand->chip_delay = NAND_BIG_DELAY_US; nand->options = NAND_SAMSUNG_LP_OPTIONS; return 0; diff --git a/board/freescale/m5329evb/nand.c b/board/freescale/m5329evb/nand.c index 344a614895d..f84912e37ec 100644 --- a/board/freescale/m5329evb/nand.c +++ b/board/freescale/m5329evb/nand.c @@ -40,36 +40,26 @@ DECLARE_GLOBAL_DATA_PTR; #define SET_ALE 0x08 #define CLR_ALE ~SET_ALE -static void nand_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtdinfo->priv; - volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; +/* volatile fbcs_t *fbcs = (fbcs_t *) MMAP_FBCS; TODO: handle wp */ u32 nand_baseaddr = (u32) this->IO_ADDR_W; - switch (cmd) { - case NAND_CTL_SETNCE: - case NAND_CTL_CLRNCE: - break; - case NAND_CTL_SETCLE: - nand_baseaddr |= SET_CLE; - break; - case NAND_CTL_CLRCLE: - nand_baseaddr &= CLR_CLE; - break; - case NAND_CTL_SETALE: - nand_baseaddr |= SET_ALE; - break; - case NAND_CTL_CLRALE: - nand_baseaddr |= CLR_ALE; - break; - case NAND_CTL_SETWP: - fbcs->csmr2 |= FBCS_CSMR_WP; - break; - case NAND_CTL_CLRWP: - fbcs->csmr2 &= ~FBCS_CSMR_WP; - break; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + nand_baseaddr |= SET_CLE; + else + nand_baseaddr &= CLR_CLE; + if ( ctrl & NAND_ALE ) + nand_baseaddr |= SET_ALE; + else + nand_baseaddr &= CLR_ALE; } this->IO_ADDR_W = (void __iomem *)(nand_baseaddr); + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } static void nand_write_byte(struct mtd_info *mtdinfo, u_char byte) @@ -103,8 +93,8 @@ int board_nand_init(struct nand_chip *nand) gpio->podr_timer = 0; nand->chip_delay = 50; - nand->eccmode = NAND_ECC_SOFT; - nand->hwcontrol = nand_hwcontrol; + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = nand_hwcontrol; nand->read_byte = nand_read_byte; nand->write_byte = nand_write_byte; nand->dev_ready = nand_dev_ready; diff --git a/board/nc650/nand.c b/board/nc650/nand.c index 8617f7445f3..faec6053f7e 100644 --- a/board/nc650/nand.c +++ b/board/nc650/nand.c @@ -22,7 +22,7 @@ */ #include - +#include #if defined(CONFIG_CMD_NAND) @@ -32,57 +32,49 @@ /* * hardware specific access to control-lines */ -static void nc650_hwcontrol(struct mtd_info *mtd, int cmd) +static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - switch(cmd) { - case NAND_CTL_SETCLE: - this->IO_ADDR_W += 2; - break; - case NAND_CTL_CLRCLE: - this->IO_ADDR_W -= 2; - break; - case NAND_CTL_SETALE: - this->IO_ADDR_W += 1; - break; - case NAND_CTL_CLRALE: - this->IO_ADDR_W -= 1; - break; - case NAND_CTL_SETNCE: - case NAND_CTL_CLRNCE: - /* nop */ - break; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + this->IO_ADDR_W += 2; + else + this->IO_ADDR_W -= 2; + if ( ctrl & NAND_ALE ) + this->IO_ADDR_W += 1; + else + this->IO_ADDR_W -= 1; } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } #elif defined(CONFIG_IDS852_REV2) /* * hardware specific access to control-lines */ -static void nc650_hwcontrol(struct mtd_info *mtd, int cmd) +static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - switch(cmd) { - case NAND_CTL_SETCLE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0xa) = 0; - break; - case NAND_CTL_CLRCLE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0x8) = 0; - break; - case NAND_CTL_SETALE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0x9) = 0; - break; - case NAND_CTL_CLRALE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0x8) = 0; - break; - case NAND_CTL_SETNCE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0x8) = 0; - break; - case NAND_CTL_CLRNCE: - *(((volatile __u8 *) this->IO_ADDR_W) + 0xc) = 0; - break; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + writeb(0, (volatile __u8 *) this->IO_ADDR_W + 0xa); + else + writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0x8); + if ( ctrl & NAND_ALE ) + writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0x9); + else + writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0x8); + if ( ctrl & NAND_NCE ) + writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0x8); + else + writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0xc); } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } #else #error Unknown IDS852 module revision @@ -93,11 +85,11 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd) * argument are board-specific (per include/linux/mtd/nand.h): * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - hwcontrol: hardwarespecific function for accesing control-lines + * - cmd_ctrl: hardwarespecific function for accesing control-lines * - dev_ready: hardwarespecific function for accesing device ready/busy line * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must * only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines + * - eccm.ode: mode of ecc, see defines * - chip_delay: chip dependent delay for transfering data from array to * read regs (tR) * - options: various chip options. They can partly be set to inform @@ -109,8 +101,8 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd) int board_nand_init(struct nand_chip *nand) { - nand->hwcontrol = nc650_hwcontrol; - nand->eccmode = NAND_ECC_SOFT; + nand->cmd_ctrl = nc650_hwcontrol; + nand->ecc.mode = NAND_ECC_SOFT; nand->chip_delay = 12; /* nand->options = NAND_SAMSUNG_LP_OPTIONS;*/ return 0; diff --git a/board/netstar/nand.c b/board/netstar/nand.c index b76d2a3324a..302d78efef1 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -21,6 +21,7 @@ */ #include +#include #if defined(CONFIG_CMD_NAND) @@ -32,24 +33,29 @@ #define MASK_CLE 0x02 #define MASK_ALE 0x04 -static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd) +static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; ulong IO_ADDR_W = (ulong) this->IO_ADDR_W; IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); - switch (cmd) { - case NAND_CTL_SETCLE: IO_ADDR_W |= MASK_CLE; break; - case NAND_CTL_SETALE: IO_ADDR_W |= MASK_ALE; break; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + IO_ADDR_W |= MASK_CLE; + if ( ctrl & NAND_ALE ) + IO_ADDR_W |= MASK_ALE; } - this->IO_ADDR_W = (void *) IO_ADDR_W; + this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } int board_nand_init(struct nand_chip *nand) { nand->options = NAND_SAMSUNG_LP_OPTIONS; - nand->eccmode = NAND_ECC_SOFT; - nand->hwcontrol = netstar_nand_hwcontrol; + nand->ecc.mode = NAND_ECC_SOFT; + nand->cmd_ctrl = netstar_nand_hwcontrol; nand->chip_delay = 400; return 0; } diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index 097e1837197..3224d3dd638 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -56,43 +56,24 @@ static struct alpr_ndfc_regs *alpr_ndfc = NULL; * * There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte). */ -static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd) -{ - switch (cmd) { - case NAND_CTL_SETCLE: - hwctl |= 0x1; - break; - case NAND_CTL_CLRCLE: - hwctl &= ~0x1; - break; - case NAND_CTL_SETALE: - hwctl |= 0x2; - break; - case NAND_CTL_CLRALE: - hwctl &= ~0x2; - break; - case NAND_CTL_SETNCE: - break; - case NAND_CTL_CLRNCE: - writeb(0x00, &(alpr_ndfc->term)); - break; - } -} +static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; -static void alpr_nand_write_byte(struct mtd_info *mtd, u_char byte) -{ - struct nand_chip *nand = mtd->priv; - - if (hwctl & 0x1) - /* - * IO_ADDR_W used as CMD[i] reg to support multiple NAND - * chips. - */ - writeb(byte, nand->IO_ADDR_W); - else if (hwctl & 0x2) { - writeb(byte, &(alpr_ndfc->addr_wait)); - } else - writeb(byte, &(alpr_ndfc->data)); + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + hwctl |= 0x1; + else + hwctl &= ~0x1; + if ( ctrl & NAND_ALE ) + hwctl |= 0x2; + else + hwctl &= ~0x2; + if ( (ctrl & NAND_NCE) != NAND_NCE) + writeb(0x00, &(alpr_ndfc->term)); + } + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } static u_char alpr_nand_read_byte(struct mtd_info *mtd) @@ -158,12 +139,10 @@ int board_nand_init(struct nand_chip *nand) { alpr_ndfc = (struct alpr_ndfc_regs *)CFG_NAND_BASE; - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; /* Reference hardware control function */ - nand->hwcontrol = alpr_nand_hwcontrol; - /* Set command delay time */ - nand->write_byte = alpr_nand_write_byte; + nand->cmd_ctrl = alpr_nand_hwcontrol; nand->read_byte = alpr_nand_read_byte; nand->write_buf = alpr_nand_write_buf; nand->read_buf = alpr_nand_read_buf; diff --git a/board/prodrive/pdnb3/nand.c b/board/prodrive/pdnb3/nand.c index b1e7041046f..281ae70af61 100644 --- a/board/prodrive/pdnb3/nand.c +++ b/board/prodrive/pdnb3/nand.c @@ -52,40 +52,26 @@ static struct pdnb3_ndfc_regs *pdnb3_ndfc; * * There is one NAND devices on the board, a Hynix HY27US08561A (32 MByte). */ -static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd) +static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch (cmd) { - case NAND_CTL_SETCLE: - hwctl |= 0x1; - break; - case NAND_CTL_CLRCLE: - hwctl &= ~0x1; - break; - - case NAND_CTL_SETALE: - hwctl |= 0x2; - break; - case NAND_CTL_CLRALE: - hwctl &= ~0x2; - break; - - case NAND_CTL_SETNCE: - break; - case NAND_CTL_CLRNCE: - writeb(0x00, &(pdnb3_ndfc->term)); - break; + struct nand_chip *this = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + hwctl |= 0x1; + else + hwctl &= ~0x1; + if ( ctrl & NAND_ALE ) + hwctl |= 0x2; + else + hwctl &= ~0x2; + if ( (ctrl & NAND_NCE) != NAND_NCE) + writeb(0x00, &(pdnb3_ndfc->term)); } + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } -static void pdnb3_nand_write_byte(struct mtd_info *mtd, u_char byte) -{ - if (hwctl & 0x1) - writeb(byte, &(pdnb3_ndfc->cmd)); - else if (hwctl & 0x2) - writeb(byte, &(pdnb3_ndfc->addr)); - else - writeb(byte, &(pdnb3_ndfc->data)); -} static u_char pdnb3_nand_read_byte(struct mtd_info *mtd) { @@ -152,16 +138,13 @@ int board_nand_init(struct nand_chip *nand) { pdnb3_ndfc = (struct pdnb3_ndfc_regs *)CFG_NAND_BASE; - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; /* Set address of NAND IO lines (Using Linear Data Access Region) */ nand->IO_ADDR_R = (void __iomem *) ((ulong) pdnb3_ndfc + 0x4); nand->IO_ADDR_W = (void __iomem *) ((ulong) pdnb3_ndfc + 0x4); /* Reference hardware control function */ - nand->hwcontrol = pdnb3_nand_hwcontrol; - /* Set command delay time */ - nand->hwcontrol = pdnb3_nand_hwcontrol; - nand->write_byte = pdnb3_nand_write_byte; + nand->cmd_ctrl = pdnb3_nand_hwcontrol; nand->read_byte = pdnb3_nand_read_byte; nand->write_buf = pdnb3_nand_write_buf; nand->read_buf = pdnb3_nand_read_buf; diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c index 009567b50bf..2f2e7458975 100644 --- a/board/sc3/sc3nand.c +++ b/board/sc3/sc3nand.c @@ -39,30 +39,26 @@ static void *sc3_io_base; static void *sc3_control_base = (void *)0xEF600700; -static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd) +static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch (cmd) { - case NAND_CTL_SETCLE: - set_bit (SC3_NAND_CLE, sc3_control_base); - break; - case NAND_CTL_CLRCLE: - clear_bit (SC3_NAND_CLE, sc3_control_base); - break; - - case NAND_CTL_SETALE: - set_bit (SC3_NAND_ALE, sc3_control_base); - break; - case NAND_CTL_CLRALE: - clear_bit (SC3_NAND_ALE, sc3_control_base); - break; - - case NAND_CTL_SETNCE: - set_bit (SC3_NAND_CE, sc3_control_base); - break; - case NAND_CTL_CLRNCE: - clear_bit (SC3_NAND_CE, sc3_control_base); - break; + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + set_bit (SC3_NAND_CLE, sc3_control_base); + else + clear_bit (SC3_NAND_CLE, sc3_control_base); + if ( ctrl & NAND_ALE ) + set_bit (SC3_NAND_ALE, sc3_control_base); + else + clear_bit (SC3_NAND_ALE, sc3_control_base); + if ( ctrl & NAND_NCE ) + set_bit (SC3_NAND_CE, sc3_control_base); + else + clear_bit (SC3_NAND_CE, sc3_control_base); } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } static int sc3_nand_dev_ready(struct mtd_info *mtd) @@ -79,14 +75,14 @@ static void sc3_select_chip(struct mtd_info *mtd, int chip) int board_nand_init(struct nand_chip *nand) { - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; sc3_io_base = (void *) CFG_NAND_BASE; /* Set address of NAND IO lines (Using Linear Data Access Region) */ nand->IO_ADDR_R = (void __iomem *) sc3_io_base; nand->IO_ADDR_W = (void __iomem *) sc3_io_base; /* Reference hardware control function */ - nand->hwcontrol = sc3_nand_hwcontrol; + nand->cmd_ctrl = sc3_nand_hwcontrol; nand->dev_ready = sc3_nand_dev_ready; nand->select_chip = sc3_select_chip; return 0; diff --git a/board/tqc/tqm8272/tqm8272.c b/board/tqc/tqm8272/tqm8272.c index cde02961bea..5148f3de5fc 100644 --- a/board/tqc/tqm8272/tqm8272.c +++ b/board/tqc/tqm8272/tqm8272.c @@ -1068,24 +1068,22 @@ int update_flash_size (int flash_size) static u8 hwctl = 0; -static void upmnand_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void upmnand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch (cmd) { - case NAND_CTL_SETCLE: - hwctl |= 0x1; - break; - case NAND_CTL_CLRCLE: - hwctl &= ~0x1; - break; - - case NAND_CTL_SETALE: - hwctl |= 0x2; - break; - - case NAND_CTL_CLRALE: - hwctl &= ~0x2; - break; + struct nand_chip *this = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + hwctl |= 0x1; + else + hwctl &= ~0x1; + if ( ctrl & NAND_ALE ) + hwctl |= 0x2; + else + hwctl &= ~0x2; } + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } static void upmnand_write_byte(struct mtd_info *mtdinfo, u_char byte) @@ -1188,9 +1186,9 @@ int board_nand_init(struct nand_chip *nand) memctl->memc_br3 = CFG_NAND_BR; memctl->memc_mbmr = (MxMR_OP_NORM); - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; - nand->hwcontrol = upmnand_hwcontrol; + nand->cmd_ctrl = upmnand_hwcontrol; nand->read_byte = upmnand_read_byte; nand->write_byte = upmnand_write_byte; nand->dev_ready = tqm8272_dev_ready; diff --git a/board/zylonite/nand.c b/board/zylonite/nand.c index ca165784324..47d5d4b0d73 100644 --- a/board/zylonite/nand.c +++ b/board/zylonite/nand.c @@ -69,7 +69,7 @@ static struct nand_oobinfo delta_oob = { /* * not required for Monahans DFC */ -static void dfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void dfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { return; } @@ -110,25 +110,6 @@ static void dfc_write_buf(struct mtd_info *mtd, const u_char *buf, int len) } -/* - * These functions are quite problematic for the DFC. Luckily they are - * not used in the current nand code, except for nand_command, which - * we've defined our own anyway. The problem is, that we always need - * to write 4 bytes to the DFC Data Buffer, but in these functions we - * don't know if to buffer the bytes/half words until we've gathered 4 - * bytes or if to send them straight away. - * - * Solution: Don't use these with Mona's DFC and complain loudly. - */ -static void dfc_write_word(struct mtd_info *mtd, u16 word) -{ - printf("dfc_write_word: WARNING, this function does not work with the Monahans DFC!\n"); -} -static void dfc_write_byte(struct mtd_info *mtd, u_char byte) -{ - printf("dfc_write_byte: WARNING, this function does not work with the Monahans DFC!\n"); -} - /* The original: * static void dfc_read_buf(struct mtd_info *mtd, const u_char *buf, int len) * @@ -168,7 +149,7 @@ static void dfc_read_buf(struct mtd_info *mtd, u_char* const buf, int len) */ static u16 dfc_read_word(struct mtd_info *mtd) { - printf("dfc_write_byte: UNIMPLEMENTED.\n"); + printf("dfc_read_word: UNIMPLEMENTED.\n"); return 0; } @@ -289,9 +270,10 @@ static void dfc_new_cmd(void) /* this function is called after Programm and Erase Operations to * check for success or failure */ -static int dfc_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int dfc_wait(struct mtd_info *mtd, struct nand_chip *this) { unsigned long ndsr=0, event=0; + int state = this->state; if(state == FL_WRITING) { event = NDSR_CS0_CMDD | NDSR_CS0_BBD; @@ -435,11 +417,11 @@ static void dfc_gpio_init(void) * argument are board-specific (per include/linux/mtd/nand_new.h): * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - hwcontrol: hardwarespecific function for accesing control-lines + * - cmd_ctrl: hardwarespecific function for accesing control-lines * - dev_ready: hardwarespecific function for accesing device ready/busy line * - enable_hwecc?: function to enable (reset) hardware ecc generator. Must * only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines + * - ecc.mode: mode of ecc, see defines * - chip_delay: chip dependent delay for transfering data from array to * read regs (tR) * - options: various chip options. They can partly be set to inform @@ -560,21 +542,18 @@ int board_nand_init(struct nand_chip *nand) /* wait 10 us due to cmd buffer clear reset */ /* wait(10); */ - - nand->hwcontrol = dfc_hwcontrol; + nand->cmd_ctrl = dfc_hwcontrol; /* nand->dev_ready = dfc_device_ready; */ - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; nand->options = NAND_BUSWIDTH_16; nand->waitfunc = dfc_wait; nand->read_byte = dfc_read_byte; - nand->write_byte = dfc_write_byte; nand->read_word = dfc_read_word; - nand->write_word = dfc_write_word; nand->read_buf = dfc_read_buf; nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; - nand->autooob = &delta_oob; +// nand->autooob = &delta_oob; nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/common/cmd_doc.c b/common/cmd_doc.c index d7b2f535f3d..9d5b3001cc9 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -14,6 +14,7 @@ #include #include +#if 0 #ifdef CFG_DOC_SUPPORT_2000 #define DoC_is_2000(doc) (doc->ChipID == DOC_ChipID_Doc2k) #else @@ -1629,3 +1630,6 @@ void doc_probe(unsigned long physadr) puts ("No DiskOnChip found\n"); } } +#else +void doc_probe(unsigned long physadr) {} +#endif diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 9e38bf768f9..3e76d8207d6 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -18,6 +18,7 @@ * */ #include +#include #if defined(CONFIG_CMD_NAND) @@ -34,7 +35,7 @@ int mtdparts_init(void); int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, - u8 *part_num, struct part_info **part); + u8 *part_num, struct part_info **part); #endif static int nand_dump_oob(nand_info_t *nand, ulong off) @@ -47,32 +48,38 @@ static int nand_dump(nand_info_t *nand, ulong off) int i; u_char *buf, *p; - buf = malloc(nand->oobblock + nand->oobsize); + buf = malloc(nand->writesize + nand->oobsize); if (!buf) { puts("No memory for page buffer\n"); return 1; } - off &= ~(nand->oobblock - 1); - i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize); + off &= ~(nand->writesize - 1); +#if 0 + i = nand_read_raw(nand, buf, off, nand->writesize, nand->oobsize); +#else + size_t dummy; + loff_t addr = (loff_t) off; + i = nand->read(nand, addr, nand->writesize, &dummy, buf); +#endif if (i < 0) { printf("Error (%d) reading page %08lx\n", i, off); free(buf); return 1; } printf("Page %08lx dump:\n", off); - i = nand->oobblock >> 4; p = buf; + i = nand->writesize >> 4; p = buf; while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], + p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); p += 16; } puts("OOB:\n"); i = nand->oobsize >> 3; while (i--) { - printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + printf("\t%02x %02x %02x %02x %02x %02x %02x %02x\n", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); p += 8; } free(buf); @@ -155,7 +162,7 @@ out: int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - int i, dev, ret; + int i, dev, ret = 0; ulong addr, off; size_t size; char *cmd, *s; @@ -182,8 +189,8 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { if (nand_info[i].name) printf("Device %d: %s, sector size %u KiB\n", - i, nand_info[i].name, - nand_info[i].erasesize >> 10); + i, nand_info[i].name, + nand_info[i].erasesize >> 10); } return 0; } @@ -192,11 +199,11 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (argc < 3) { if ((nand_curr_device < 0) || - (nand_curr_device >= CFG_MAX_NAND_DEVICE)) + (nand_curr_device >= CFG_MAX_NAND_DEVICE)) puts("\nno devices available\n"); else printf("\nDevice %d: %s\n", nand_curr_device, - nand_info[nand_curr_device].name); + nand_info[nand_curr_device].name); return 0; } dev = (int)simple_strtoul(argv[2], NULL, 10); @@ -219,11 +226,11 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 && - strncmp(cmd, "dump", 4) != 0 && - strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && - strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && - strcmp(cmd, "biterr") != 0 && - strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) + strncmp(cmd, "dump", 4) != 0 && + strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 && + strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 && + strcmp(cmd, "biterr") != 0 && + strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 ) goto usage; /* the following commands operate on the current device */ @@ -250,7 +257,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) { nand_erase_options_t opts; /* "clean" at index 2 means request to write cleanmarker */ - int clean = argc > 2 && !strcmp("clean", argv[2]); + int clean = !strcmp("clean", argv[2]); int o = clean ? 3 : 2; int scrub = !strcmp(cmd, "scrub"); @@ -260,6 +267,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) return 1; memset(&opts, 0, sizeof(opts)); + opts.offset = off; opts.length = size; opts.jffs2 = clean; @@ -320,40 +328,41 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; - + s = strchr(cmd, '.'); if (s != NULL && - (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { + (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { if (read) { /* read */ nand_read_options_t opts; memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = size; - opts.offset = off; - opts.quiet = quiet; - ret = nand_read_opts(nand, &opts); + opts.buffer = (u_char*) addr; + opts.length = size; + opts.offset = off; + opts.quiet = quiet; +// ret = nand_read_opts(nand, &opts); } else { /* write */ - nand_write_options_t opts; + mtd_oob_ops_t opts; memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = size; - opts.offset = off; - /* opts.forcejffs2 = 1; */ - opts.pad = 1; - opts.blockalign = 1; - opts.quiet = quiet; - ret = nand_write_opts(nand, &opts); + opts.datbuf = (u_char*) addr; + opts.len = size; + opts.ooblen = 64; + opts.mode = MTD_OOB_AUTO; + ret = nand_write_opts(nand, off, &opts); } } else if (s != NULL && !strcmp(s, ".oob")) { - /* read out-of-band data */ + /* out-of-band data */ + mtd_oob_ops_t ops = { + .oobbuf = (u8 *)addr, + .ooblen = size, + .mode = MTD_OOB_RAW + }; + if (read) - ret = nand->read_oob(nand, off, size, &size, - (u_char *) addr); + ret = nand->read_oob(nand, off, &ops); else - ret = nand->write_oob(nand, off, size, &size, - (u_char *) addr); + ret = nand->write_oob(nand, off, &ops); } else { if (read) ret = nand_read(nand, off, &size, (u_char *)addr); @@ -397,44 +406,44 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (status) { - ulong block_start = 0; +// ulong block_start = 0; ulong off; - int last_status = -1; +// int last_status = -1; struct nand_chip *nand_chip = nand->priv; /* check the WP bit */ nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1); printf("device is %swrite protected\n", (nand_chip->read_byte(nand) & 0x80 ? - "NOT " : "" ) ); - - for (off = 0; off < nand->size; off += nand->oobblock) { - int s = nand_get_lock_status(nand, off); - - /* print message only if status has changed - * or at end of chip - */ - if (off == nand->size - nand->oobblock - || (s != last_status && off != 0)) { - - printf("%08lx - %08lx: %8lu pages %s%s%s\n", - block_start, - off-1, - (off-block_start)/nand->oobblock, - ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), - ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), - ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); - } - - last_status = s; - } - } else { - if (!nand_lock(nand, tight)) { - puts("NAND flash successfully locked\n"); - } else { - puts("Error locking NAND flash\n"); - return 1; + "NOT " : "" ) ); + + for (off = 0; off < nand->size; off += nand->writesize) { +// int s = nand_get_lock_status(nand, off); +// +// /* print message only if status has changed +// * or at end of chip +// */ +// if (off == nand->size - nand->writesize +// || (s != last_status && off != 0)) { +// +// printf("%08lx - %08lx: %8d pages %s%s%s\n", +// block_start, +// off-1, +// (off-block_start)/nand->writesize, +// ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), +// ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), +// ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); +// } +// +// last_status = s; } + } else { +// if (!nand_lock(nand, tight)) { +// puts("NAND flash successfully locked\n"); +// } else { +// puts("Error locking NAND flash\n"); +// return 1; +// } } return 0; } @@ -443,13 +452,13 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) return 1; - if (!nand_unlock(nand, off, size)) { - puts("NAND flash successfully unlocked\n"); - } else { - puts("Error unlocking NAND flash, " - "write and erase will probably fail\n"); - return 1; - } +// if (!nand_unlock(nand, off, size)) { +// puts("NAND flash successfully unlocked\n"); +// } else { +// puts("Error unlocking NAND flash, " +// "write and erase will probably fail\n"); +// return 1; +// } return 0; } @@ -459,24 +468,26 @@ usage: } U_BOOT_CMD(nand, 5, 1, do_nand, - "nand - NAND sub-system\n", - "info - show available NAND devices\n" - "nand device [dev] - show or set current device\n" - "nand read[.jffs2] - addr off|partition size\n" - "nand write[.jffs2] - addr off|partition size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\n" - "nand erase [clean] [off size] - erase `size' bytes from\n" - " offset `off' (entire device if not specified)\n" - "nand bad - show bad blocks\n" - "nand dump[.oob] off - dump page\n" - "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" - "nand markbad off - mark bad block at offset (UNSAFE)\n" - "nand biterr off - make a bit error at offset (UNSAFE)\n" - "nand lock [tight] [status] - bring nand to lock state or display locked pages\n" - "nand unlock [offset] [size] - unlock section\n"); + "nand - NAND sub-system\n", + "info - show available NAND devices\n" + "nand device [dev] - show or set current device\n" + "nand read[.jffs2] - addr off|partition size\n" + "nand write[.jffs2] - addr off|partition size\n" + " read/write 'size' bytes starting at offset 'off'\n" + " to/from memory address 'addr'\n" + "nand erase [clean] [off size] - erase 'size' bytes from\n" + " offset 'off' (entire device if not specified)\n" + "nand bad - show bad blocks\n" + "nand dump[.oob] off - dump page\n" + "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n" + "nand markbad off - mark bad block at offset (UNSAFE)\n" + "nand biterr off - make a bit error at offset (UNSAFE)\n" + "nand lock [tight] [status]\n" + " bring nand to lock state or display locked pages\n" + "nand unlock [offset] [size] - unlock section\n"); static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, - ulong offset, ulong addr, char *cmd) + ulong offset, ulong addr, char *cmd) { int r; char *ep, *s; @@ -494,19 +505,8 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset); - cnt = nand->oobblock; - if (jffs2) { - nand_read_options_t opts; - memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = cnt; - opts.offset = offset; - opts.quiet = 1; - r = nand_read_opts(nand, &opts); - } else { - r = nand_read(nand, offset, &cnt, (u_char *) addr); - } - + cnt = nand->writesize; + r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { puts("** Read error\n"); show_boot_progress (-56); @@ -537,18 +537,7 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand, return 1; } - if (jffs2) { - nand_read_options_t opts; - memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = cnt; - opts.offset = offset; - opts.quiet = 1; - r = nand_read_opts(nand, &opts); - } else { - r = nand_read(nand, offset, &cnt, (u_char *) addr); - } - + r = nand_read(nand, offset, &cnt, (u_char *) addr); if (r) { puts("** Read error\n"); show_boot_progress (-58); @@ -614,7 +603,7 @@ int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else addr = CFG_LOAD_ADDR; return nand_load_image(cmdtp, &nand_info[dev->id->num], - part->offset, addr, argv[0]); + part->offset, addr, argv[0]); } } #endif @@ -704,8 +693,8 @@ void archflashwp(void *archdata, int wp); #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) -#undef NAND_DEBUG -#undef PSYCHO_DEBUG +#undef NAND_DEBUG +#undef PSYCHO_DEBUG /* ****************** WARNING ********************* * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will @@ -720,16 +709,16 @@ void archflashwp(void *archdata, int wp); * and attempting to program or erase bad blocks can affect * the data in _other_ (good) blocks. */ -#define ALLOW_ERASE_BAD_DEBUG 0 +#define ALLOW_ERASE_BAD_DEBUG 0 #define CONFIG_MTD_NAND_ECC /* enable ECC */ #define CONFIG_MTD_NAND_ECC_JFFS2 /* bits for nand_legacy_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 -#define NANDRW_JFFS2_SKIP 0x04 +#define NANDRW_READ 0x01 +#define NANDRW_WRITE 0x00 +#define NANDRW_JFFS2 0x02 +#define NANDRW_JFFS2_SKIP 0x04 /* * Imports from nand_legacy.c @@ -737,15 +726,15 @@ void archflashwp(void *archdata, int wp); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; extern int curr_device; extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, - size_t len, int clean); + size_t len, int clean); extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, - size_t len, size_t *retlen, u_char *buf); + size_t len, size_t *retlen, u_char *buf); extern void nand_print(struct nand_chip *nand); extern void nand_print_bad(struct nand_chip *nand); extern int nand_read_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, u_char *buf); + size_t len, size_t *retlen, u_char *buf); extern int nand_write_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, const u_char *buf); + size_t len, size_t *retlen, const u_char *buf); int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) @@ -878,7 +867,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) else if (cmdtail && !strcmp (cmdtail, ".i")) { cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */ if (cmd & NANDRW_READ) - cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ + cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */ } #endif /* CFG_NAND_SKIP_BAD_DOT_I */ else if (cmdtail) { @@ -928,7 +917,7 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nand, 5, 1, do_nand, + nand, 5, 1, do_nand, "nand - legacy NAND sub-system\n", "info - show available NAND devices\n" "nand device [dev] - show or set current device\n" @@ -992,7 +981,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) dev = simple_strtoul(boot_device, &ep, 16); if ((dev >= CFG_MAX_NAND_DEVICE) || - (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { + (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) { printf ("\n** Device %d not available\n", dev); show_boot_progress (-55); return 1; @@ -1000,11 +989,11 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (55); printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n", - dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, - offset); + dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR, + offset); if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset, - SECTORSIZE, NULL, (u_char *)addr)) { + SECTORSIZE, NULL, (u_char *)addr)) { printf ("** Read error on %d\n", dev); show_boot_progress (-56); return 1; @@ -1035,8 +1024,8 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) show_boot_progress (57); if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, - offset + SECTORSIZE, cnt, NULL, - (u_char *)(addr+SECTORSIZE))) { + offset + SECTORSIZE, cnt, NULL, + (u_char *)(addr+SECTORSIZE))) { printf ("** Read error on %d\n", dev); show_boot_progress (-58); return 1; @@ -1077,7 +1066,7 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } U_BOOT_CMD( - nboot, 4, 1, do_nandboot, + nboot, 4, 1, do_nandboot, "nboot - boot from NAND device\n", "loadAddr dev\n" ); diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 36468e6c3a0..43041b635c0 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -42,6 +42,7 @@ */ #include +#include #ifdef CFG_USE_NAND #if !defined(CFG_NAND_LEGACY) @@ -52,23 +53,23 @@ extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; -static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd) +static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; u_int32_t IO_ADDR_W = (u_int32_t)this->IO_ADDR_W; IO_ADDR_W &= ~(MASK_ALE|MASK_CLE); - switch (cmd) { - case NAND_CTL_SETCLE: + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) IO_ADDR_W |= MASK_CLE; - break; - case NAND_CTL_SETALE: + if ( ctrl & NAND_ALE ) IO_ADDR_W |= MASK_ALE; - break; + this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } - this->IO_ADDR_W = (void *)IO_ADDR_W; + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } /* Set WP on deselect, write enable on select */ @@ -145,7 +146,7 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u int region, n; struct nand_chip *this = mtd->priv; - n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + n = (this->ecc.size/512); region = 1; while (n--) { @@ -281,7 +282,7 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char * int block_count = 0, i, rc; this = mtd->priv; - block_count = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1; + block_count = (this->ecc.size/512); for (i = 0; i < block_count; i++) { if (memcmp(read_ecc, calc_ecc, 3) != 0) { rc = nand_davinci_compare_ecc(read_ecc, calc_ecc, dat); @@ -306,7 +307,7 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd) return(emif_addr->NANDFSR & 0x1); } -static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this, int state) +static int nand_davinci_waitfunc(struct mtd_info *mtd, struct nand_chip *this) { while(!nand_davinci_dev_ready(mtd)) {;} *NAND_CE0CLE = NAND_STATUS; @@ -362,22 +363,26 @@ int board_nand_init(struct nand_chip *nand) #endif #ifdef CFG_NAND_HW_ECC #ifdef CFG_NAND_LARGEPAGE - nand->eccmode = NAND_ECC_HW12_2048; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 2048; + nand->ecc.bytes = 12; #elif defined(CFG_NAND_SMALLPAGE) - nand->eccmode = NAND_ECC_HW3_512; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 512; + nand->ecc.bytes = 3; #else #error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" #endif - nand->autooob = &davinci_nand_oobinfo; - nand->calculate_ecc = nand_davinci_calculate_ecc; - nand->correct_data = nand_davinci_correct_data; - nand->enable_hwecc = nand_davinci_enable_hwecc; +// nand->autooob = &davinci_nand_oobinfo; + nand->ecc.calculate = nand_davinci_calculate_ecc; + nand->ecc.correct = nand_davinci_correct_data; + nand->ecc.hwctl = nand_davinci_enable_hwecc; #else - nand->eccmode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; #endif /* Set address of hardware control function */ - nand->hwcontrol = nand_davinci_hwcontrol; + nand->cmd_ctrl = nand_davinci_hwcontrol; nand->dev_ready = nand_davinci_dev_ready; nand->waitfunc = nand_davinci_waitfunc; diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 5b2ae88d93b..7818eb9c54b 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -46,38 +46,22 @@ static u8 hwctl = 0; -static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd) +static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - switch (cmd) { - case NAND_CTL_SETCLE: - hwctl |= 0x1; - break; - - case NAND_CTL_CLRCLE: - hwctl &= ~0x1; - break; - - case NAND_CTL_SETALE: - hwctl |= 0x2; - break; - - case NAND_CTL_CLRALE: - hwctl &= ~0x2; - break; + struct nand_chip *this = mtd->priv; + + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_CLE ) + hwctl |= 0x1; + else + hwctl &= ~0x1; + if ( ctrl & NAND_ALE ) + hwctl |= 0x2; + else + hwctl &= ~0x2; } -} - -static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte) -{ - struct nand_chip *this = mtdinfo->priv; - ulong base = (ulong) this->IO_ADDR_W & 0xfffffffc; - - if (hwctl & 0x1) - out_8((u8 *)(base + NDFC_CMD), byte); - else if (hwctl & 0x2) - out_8((u8 *)(base + NDFC_ALE), byte); - else - out_8((u8 *)(base + NDFC_DATA), byte); + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); } static u_char ndfc_read_byte(struct mtd_info *mtdinfo) @@ -194,16 +178,17 @@ int board_nand_init(struct nand_chip *nand) int cs = (ulong)nand->IO_ADDR_W & 0x00000003; ulong base = (ulong)nand->IO_ADDR_W & 0xfffffffc; - nand->hwcontrol = ndfc_hwcontrol; + nand->cmd_ctrl = ndfc_hwcontrol; nand->read_byte = ndfc_read_byte; nand->read_buf = ndfc_read_buf; - nand->write_byte = ndfc_write_byte; nand->dev_ready = ndfc_dev_ready; - nand->eccmode = NAND_ECC_HW3_256; - nand->enable_hwecc = ndfc_enable_hwecc; - nand->calculate_ecc = ndfc_calculate_ecc; - nand->correct_data = nand_correct_data; + nand->ecc.correct = nand_correct_data; + nand->ecc.hwctl = ndfc_enable_hwecc; + nand->ecc.calculate = ndfc_calculate_ecc; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 256; + nand->ecc.bytes = 3; #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index fdd85c159d7..a03f982be5f 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -16,7 +16,7 @@ * * Interface to generic NAND code for M-Systems DiskOnChip devices * - * $Id: diskonchip.c,v 1.45 2005/01/05 18:05:14 dwmw2 Exp $ + * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $ */ #include @@ -39,13 +39,13 @@ #include /* Where to look for the devices? */ -#ifndef CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS -#define CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS 0 +#ifndef CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS +#define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0 #endif static unsigned long __initdata doc_locations[] = { #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) -#ifdef CONFIG_MTD_DISKONCHIP_PROBE_HIGH +#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, @@ -65,7 +65,7 @@ static unsigned long __initdata doc_locations[] = { 0xff000000, #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C) 0xff000000, -##else +#else #warning Unknown architecture for DiskOnChip. No default probe locations defined #endif 0xffffffff }; @@ -77,7 +77,7 @@ struct doc_priv { unsigned long physadr; u_char ChipID; u_char CDSNControl; - int chips_per_floor; /* The number of chips detected on each floor */ + int chips_per_floor; /* The number of chips detected on each floor */ int curfloor; int curchip; int mh0_page; @@ -85,14 +85,10 @@ struct doc_priv { struct mtd_info *nextdoc; }; -/* Max number of eraseblocks to scan (from start of device) for the (I)NFTL - MediaHeader. The spec says to just keep going, I think, but that's just - silly. */ -#define MAX_MEDIAHEADER_SCAN 8 - /* This is the syndrome computed by the HW ecc generator upon reading an empty page, one with all 0xff for data and stored ecc code. */ static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; + /* This is the ecc value computed by the HW ecc generator upon writing an empty page, one with all 0xff for data. */ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; @@ -103,35 +99,36 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; #define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) #define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) -static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int bitmask); static void doc200x_select_chip(struct mtd_info *mtd, int chip); -static int debug=0; +static int debug = 0; module_param(debug, int, 0); -static int try_dword=1; +static int try_dword = 1; module_param(try_dword, int, 0); -static int no_ecc_failures=0; +static int no_ecc_failures = 0; module_param(no_ecc_failures, int, 0); -#ifdef CONFIG_MTD_PARTITIONS -static int no_autopart=0; +static int no_autopart = 0; module_param(no_autopart, int, 0); -#endif -#ifdef MTD_NAND_DISKONCHIP_BBTWRITE -static int inftl_bbt_write=1; +static int show_firmware_partition = 0; +module_param(show_firmware_partition, int, 0); + +#ifdef CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE +static int inftl_bbt_write = 1; #else -static int inftl_bbt_write=0; +static int inftl_bbt_write = 0; #endif module_param(inftl_bbt_write, int, 0); -static unsigned long doc_config_location = CONFIG_MTD_DISKONCHIP_PROBE_ADDRESS; +static unsigned long doc_config_location = CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS; module_param(doc_config_location, ulong, 0); MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe for DiskOnChip"); - /* Sector size for HW ECC */ #define SECTOR_SIZE 512 /* The sector bytes are packed into NB_DATA 10 bit words */ @@ -155,7 +152,7 @@ static struct rs_control *rs_decoder; * some comments, improved a minor bit and converted it to make use * of the generic Reed-Solomon libary. tglx */ -static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) +static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc) { int i, j, nerr, errpos[8]; uint8_t parity; @@ -176,11 +173,11 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] * where x = alpha^(FCR + i) */ - for(j = 1; j < NROOTS; j++) { - if(ds[j] == 0) + for (j = 1; j < NROOTS; j++) { + if (ds[j] == 0) continue; tmp = rs->index_of[ds[j]]; - for(i = 0; i < NROOTS; i++) + for (i = 0; i < NROOTS; i++) s[i] ^= rs->alpha_to[rs_modnn(rs, tmp + (FCR + i) * j)]; } @@ -201,7 +198,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) * but they are given by the design of the de/encoder circuit * in the DoC ASIC's. */ - for(i = 0;i < nerr; i++) { + for (i = 0; i < nerr; i++) { int index, bitpos, pos = 1015 - errpos[i]; uint8_t val; if (pos >= NB_DATA && pos < 1019) @@ -213,8 +210,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) can be modified since pos is even */ index = (pos >> 3) ^ 1; bitpos = pos & 7; - if ((index >= 0 && index < SECTOR_SIZE) || - index == (SECTOR_SIZE + 1)) { + if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) { val = (uint8_t) (errval[i] >> (2 + bitpos)); parity ^= val; if (index < SECTOR_SIZE) @@ -224,9 +220,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc) bitpos = (bitpos + 10) & 7; if (bitpos == 0) bitpos = 8; - if ((index >= 0 && index < SECTOR_SIZE) || - index == (SECTOR_SIZE + 1)) { - val = (uint8_t)(errval[i] << (8 - bitpos)); + if ((index >= 0 && index < SECTOR_SIZE) || index == (SECTOR_SIZE + 1)) { + val = (uint8_t) (errval[i] << (8 - bitpos)); parity ^= val; if (index < SECTOR_SIZE) data[index] ^= val; @@ -261,7 +256,8 @@ static int _DoC_WaitReady(struct doc_priv *doc) void __iomem *docptr = doc->virtadr; unsigned long timeo = jiffies + (HZ * 10); - if(debug) printk("_DoC_WaitReady...\n"); + if (debug) + printk("_DoC_WaitReady...\n"); /* Out-of-line routine to wait for chip response */ if (DoC_is_MillenniumPlus(doc)) { while ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { @@ -306,7 +302,8 @@ static inline int DoC_WaitReady(struct doc_priv *doc) DoC_Delay(doc, 2); } - if(debug) printk("DoC_WaitReady OK\n"); + if (debug) + printk("DoC_WaitReady OK\n"); return ret; } @@ -316,7 +313,8 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; - if(debug)printk("write_byte %02x\n", datum); + if (debug) + printk("write_byte %02x\n", datum); WriteDOC(datum, docptr, CDSNSlowIO); WriteDOC(datum, docptr, 2k_CDSN_IO); } @@ -331,37 +329,39 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) ReadDOC(docptr, CDSNSlowIO); DoC_Delay(doc, 2); ret = ReadDOC(docptr, 2k_CDSN_IO); - if (debug) printk("read_byte returns %02x\n", ret); + if (debug) + printk("read_byte returns %02x\n", ret); return ret; } -static void doc2000_writebuf(struct mtd_info *mtd, - const u_char *buf, int len) +static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - if (debug)printk("writebuf of %d bytes: ", len); - for (i=0; i < len; i++) { + if (debug) + printk("writebuf of %d bytes: ", len); + for (i = 0; i < len; i++) { WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i); if (debug && i < 16) printk("%02x ", buf[i]); } - if (debug) printk("\n"); + if (debug) + printk("\n"); } -static void doc2000_readbuf(struct mtd_info *mtd, - u_char *buf, int len) +static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - if (debug)printk("readbuf of %d bytes: ", len); + if (debug) + printk("readbuf of %d bytes: ", len); - for (i=0; i < len; i++) { + for (i = 0; i < len; i++) { buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i); } } @@ -374,28 +374,28 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, void __iomem *docptr = doc->virtadr; int i; - if (debug) printk("readbuf_dword of %d bytes: ", len); + if (debug) + printk("readbuf_dword of %d bytes: ", len); - if (unlikely((((unsigned long)buf)|len) & 3)) { - for (i=0; i < len; i++) { - *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); + if (unlikely((((unsigned long)buf) | len) & 3)) { + for (i = 0; i < len; i++) { + *(uint8_t *) (&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i); } } else { - for (i=0; i < len; i+=4) { - *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); + for (i = 0; i < len; i += 4) { + *(uint32_t*) (&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i); } } } -static int doc2000_verifybuf(struct mtd_info *mtd, - const u_char *buf, int len) +static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - for (i=0; i < len; i++) + for (i = 0; i < len; i++) if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO)) return -EFAULT; return 0; @@ -408,12 +408,15 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) uint16_t ret; doc200x_select_chip(mtd, nr); - doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); - this->write_byte(mtd, NAND_CMD_READID); - doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); - doc200x_hwcontrol(mtd, NAND_CTL_SETALE); - this->write_byte(mtd, 0); - doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); + doc200x_hwcontrol(mtd, NAND_CMD_READID, + NAND_CTRL_CLE | NAND_CTRL_CHANGE); + doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); + doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + + /* We cant' use dev_ready here, but at least we wait for the + * command to complete + */ + udelay(50); ret = this->read_byte(mtd) << 8; ret |= this->read_byte(mtd); @@ -426,12 +429,13 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) } ident; void __iomem *docptr = doc->virtadr; - doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); - doc2000_write_byte(mtd, NAND_CMD_READID); - doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); - doc200x_hwcontrol(mtd, NAND_CTL_SETALE); - doc2000_write_byte(mtd, 0); - doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); + doc200x_hwcontrol(mtd, NAND_CMD_READID, + NAND_CTRL_CLE | NAND_CTRL_CHANGE); + doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); + doc200x_hwcontrol(mtd, NAND_CMD_NONE, + NAND_NCE | NAND_CTRL_CHANGE); + + udelay(50); ident.dword = readl(docptr + DoC_2k_CDSN_IO); if (((ident.byte[0] << 8) | ident.byte[1]) == ret) { @@ -465,7 +469,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd) printk(KERN_DEBUG "Detected %d chips per floor.\n", i); } -static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) { struct doc_priv *doc = this->priv; @@ -496,30 +500,28 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; - /*ReadDOC(docptr, CDSNSlowIO); */ + //ReadDOC(docptr, CDSNSlowIO); /* 11.4.5 -- delay twice to allow extended length cycle */ DoC_Delay(doc, 2); ReadDOC(docptr, ReadPipeInit); - /*return ReadDOC(docptr, Mil_CDSN_IO); */ + //return ReadDOC(docptr, Mil_CDSN_IO); return ReadDOC(docptr, LastDataRead); } -static void doc2001_writebuf(struct mtd_info *mtd, - const u_char *buf, int len) +static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - for (i=0; i < len; i++) + for (i = 0; i < len; i++) WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); /* Terminate write pipeline */ WriteDOC(0x00, docptr, WritePipeTerm); } -static void doc2001_readbuf(struct mtd_info *mtd, - u_char *buf, int len) +static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -529,15 +531,14 @@ static void doc2001_readbuf(struct mtd_info *mtd, /* Start read pipeline */ ReadDOC(docptr, ReadPipeInit); - for (i=0; i < len-1; i++) + for (i = 0; i < len - 1; i++) buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff)); /* Terminate read pipeline */ buf[i] = ReadDOC(docptr, LastDataRead); } -static int doc2001_verifybuf(struct mtd_info *mtd, - const u_char *buf, int len) +static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -547,7 +548,7 @@ static int doc2001_verifybuf(struct mtd_info *mtd, /* Start read pipeline */ ReadDOC(docptr, ReadPipeInit); - for (i=0; i < len-1; i++) + for (i = 0; i < len - 1; i++) if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { ReadDOC(docptr, LastDataRead); return i; @@ -567,81 +568,84 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) ReadDOC(docptr, Mplus_ReadPipeInit); ReadDOC(docptr, Mplus_ReadPipeInit); ret = ReadDOC(docptr, Mplus_LastDataRead); - if (debug) printk("read_byte returns %02x\n", ret); + if (debug) + printk("read_byte returns %02x\n", ret); return ret; } -static void doc2001plus_writebuf(struct mtd_info *mtd, - const u_char *buf, int len) +static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - if (debug)printk("writebuf of %d bytes: ", len); - for (i=0; i < len; i++) { + if (debug) + printk("writebuf of %d bytes: ", len); + for (i = 0; i < len; i++) { WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i); if (debug && i < 16) printk("%02x ", buf[i]); } - if (debug) printk("\n"); + if (debug) + printk("\n"); } -static void doc2001plus_readbuf(struct mtd_info *mtd, - u_char *buf, int len) +static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - if (debug)printk("readbuf of %d bytes: ", len); + if (debug) + printk("readbuf of %d bytes: ", len); /* Start read pipeline */ ReadDOC(docptr, Mplus_ReadPipeInit); ReadDOC(docptr, Mplus_ReadPipeInit); - for (i=0; i < len-2; i++) { + for (i = 0; i < len - 2; i++) { buf[i] = ReadDOC(docptr, Mil_CDSN_IO); if (debug && i < 16) printk("%02x ", buf[i]); } /* Terminate read pipeline */ - buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead); + buf[len - 2] = ReadDOC(docptr, Mplus_LastDataRead); if (debug && i < 16) - printk("%02x ", buf[len-2]); - buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead); + printk("%02x ", buf[len - 2]); + buf[len - 1] = ReadDOC(docptr, Mplus_LastDataRead); if (debug && i < 16) - printk("%02x ", buf[len-1]); - if (debug) printk("\n"); + printk("%02x ", buf[len - 1]); + if (debug) + printk("\n"); } -static int doc2001plus_verifybuf(struct mtd_info *mtd, - const u_char *buf, int len) +static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; int i; - if (debug)printk("verifybuf of %d bytes: ", len); + if (debug) + printk("verifybuf of %d bytes: ", len); /* Start read pipeline */ ReadDOC(docptr, Mplus_ReadPipeInit); ReadDOC(docptr, Mplus_ReadPipeInit); - for (i=0; i < len-2; i++) + for (i = 0; i < len - 2; i++) if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) { ReadDOC(docptr, Mplus_LastDataRead); ReadDOC(docptr, Mplus_LastDataRead); return i; } - if (buf[len-2] != ReadDOC(docptr, Mplus_LastDataRead)) - return len-2; - if (buf[len-1] != ReadDOC(docptr, Mplus_LastDataRead)) - return len-1; + if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead)) + return len - 2; + if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead)) + return len - 1; return 0; } @@ -652,7 +656,8 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) void __iomem *docptr = doc->virtadr; int floor = 0; - if(debug)printk("select chip (%d)\n", chip); + if (debug) + printk("select chip (%d)\n", chip); if (chip == -1) { /* Disable flash internally */ @@ -661,7 +666,7 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) } floor = chip / doc->chips_per_floor; - chip -= (floor * doc->chips_per_floor); + chip -= (floor * doc->chips_per_floor); /* Assert ChipEnable and deassert WriteProtect */ WriteDOC((DOC_FLASH_CE), docptr, Mplus_FlashSelect); @@ -678,65 +683,54 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip) void __iomem *docptr = doc->virtadr; int floor = 0; - if(debug)printk("select chip (%d)\n", chip); + if (debug) + printk("select chip (%d)\n", chip); if (chip == -1) return; floor = chip / doc->chips_per_floor; - chip -= (floor * doc->chips_per_floor); + chip -= (floor * doc->chips_per_floor); /* 11.4.4 -- deassert CE before changing chip */ - doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); + doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); WriteDOC(floor, docptr, FloorSelect); WriteDOC(chip, docptr, CDSNDeviceSelect); - doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); + doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); doc->curchip = chip; doc->curfloor = floor; } -static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) +#define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE) + +static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, + unsigned int ctrl) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; - switch(cmd) { - case NAND_CTL_SETNCE: - doc->CDSNControl |= CDSN_CTRL_CE; - break; - case NAND_CTL_CLRNCE: - doc->CDSNControl &= ~CDSN_CTRL_CE; - break; - case NAND_CTL_SETCLE: - doc->CDSNControl |= CDSN_CTRL_CLE; - break; - case NAND_CTL_CLRCLE: - doc->CDSNControl &= ~CDSN_CTRL_CLE; - break; - case NAND_CTL_SETALE: - doc->CDSNControl |= CDSN_CTRL_ALE; - break; - case NAND_CTL_CLRALE: - doc->CDSNControl &= ~CDSN_CTRL_ALE; - break; - case NAND_CTL_SETWP: - doc->CDSNControl |= CDSN_CTRL_WP; - break; - case NAND_CTL_CLRWP: - doc->CDSNControl &= ~CDSN_CTRL_WP; - break; + if (ctrl & NAND_CTRL_CHANGE) { + doc->CDSNControl &= ~CDSN_CTRL_MSK; + doc->CDSNControl |= ctrl & CDSN_CTRL_MSK; + if (debug) + printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); + WriteDOC(doc->CDSNControl, docptr, CDSNControl); + /* 11.4.3 -- 4 NOPs after CSDNControl write */ + DoC_Delay(doc, 4); + } + if (cmd != NAND_CMD_NONE) { + if (DoC_is_2000(doc)) + doc2000_write_byte(mtd, cmd); + else + doc2001_write_byte(mtd, cmd); } - if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); - WriteDOC(doc->CDSNControl, docptr, CDSNControl); - /* 11.4.3 -- 4 NOPs after CSDNControl write */ - DoC_Delay(doc, 4); } -static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) +static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -757,9 +751,9 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col if (command == NAND_CMD_SEQIN) { int readcmd; - if (column >= mtd->oobblock) { + if (column >= mtd->writesize) { /* OOB area */ - column -= mtd->oobblock; + column -= mtd->writesize; readcmd = NAND_CMD_READOOB; } else if (column < 256) { /* First 256 bytes --> READ0 */ @@ -783,25 +777,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col WriteDOC(column, docptr, Mplus_FlashAddress); } if (page_addr != -1) { - WriteDOC((unsigned char) (page_addr & 0xff), docptr, Mplus_FlashAddress); - WriteDOC((unsigned char) ((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress); + WriteDOC((unsigned char)(page_addr & 0xff), docptr, Mplus_FlashAddress); + WriteDOC((unsigned char)((page_addr >> 8) & 0xff), docptr, Mplus_FlashAddress); /* One more address cycle for higher density devices */ if (this->chipsize & 0x0c000000) { - WriteDOC((unsigned char) ((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress); + WriteDOC((unsigned char)((page_addr >> 16) & 0x0f), docptr, Mplus_FlashAddress); printk("high density\n"); } } WriteDOC(0, docptr, Mplus_WritePipeTerm); WriteDOC(0, docptr, Mplus_WritePipeTerm); /* deassert ALE */ - if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || command == NAND_CMD_READOOB || command == NAND_CMD_READID) + if (command == NAND_CMD_READ0 || command == NAND_CMD_READ1 || + command == NAND_CMD_READOOB || command == NAND_CMD_READID) WriteDOC(0, docptr, Mplus_FlashControl); } /* * program and erase have their own busy handlers * status and sequential in needs no delay - */ + */ switch (command) { case NAND_CMD_PAGEPROG: @@ -818,26 +813,26 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col WriteDOC(NAND_CMD_STATUS, docptr, Mplus_FlashCmd); WriteDOC(0, docptr, Mplus_WritePipeTerm); WriteDOC(0, docptr, Mplus_WritePipeTerm); - while ( !(this->read_byte(mtd) & 0x40)); + while (!(this->read_byte(mtd) & 0x40)) ; return; - /* This applies to read commands */ + /* This applies to read commands */ default: /* * If we don't have access to the busy pin, we apply the given * command delay - */ + */ if (!this->dev_ready) { - udelay (this->chip_delay); + udelay(this->chip_delay); return; } } /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ - ndelay (100); + ndelay(100); /* wait until command is processed */ - while (!this->dev_ready(mtd)); + while (!this->dev_ready(mtd)) ; } static int doc200x_dev_ready(struct mtd_info *mtd) @@ -850,23 +845,25 @@ static int doc200x_dev_ready(struct mtd_info *mtd) /* 11.4.2 -- must NOP four times before checking FR/B# */ DoC_Delay(doc, 4); if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) { - if(debug) + if (debug) printk("not ready\n"); return 0; } - if (debug)printk("was ready\n"); + if (debug) + printk("was ready\n"); return 1; } else { /* 11.4.2 -- must NOP four times before checking FR/B# */ DoC_Delay(doc, 4); if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) { - if(debug) + if (debug) printk("not ready\n"); return 0; } /* 11.4.2 -- Must NOP twice if it's ready */ DoC_Delay(doc, 2); - if (debug)printk("was ready\n"); + if (debug) + printk("was ready\n"); return 1; } } @@ -885,7 +882,7 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ - switch(mode) { + switch (mode) { case NAND_ECC_READ: WriteDOC(DOC_ECC_RESET, docptr, ECCConf); WriteDOC(DOC_ECC_EN, docptr, ECCConf); @@ -904,7 +901,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) void __iomem *docptr = doc->virtadr; /* Prime the ECC engine */ - switch(mode) { + switch (mode) { case NAND_ECC_READ: WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf); WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf); @@ -917,8 +914,7 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) } /* This code is only called on write */ -static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, - unsigned char *ecc_code) +static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -962,7 +958,8 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, often. It could be optimized away by examining the data in the writebuf routine, and remembering the result. */ for (i = 0; i < 512; i++) { - if (dat[i] == 0xff) continue; + if (dat[i] == 0xff) + continue; emptymatch = 0; break; } @@ -970,17 +967,20 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, /* If emptymatch still =1, we do have an all-0xff data buffer. Return all-0xff ecc value instead of the computed one, so it'll look just like a freshly-erased page. */ - if (emptymatch) memset(ecc_code, 0xff, 6); + if (emptymatch) + memset(ecc_code, 0xff, 6); #endif return 0; } -static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) +static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, + u_char *read_ecc, u_char *isnull) { int i, ret = 0; struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; + uint8_t calc_ecc[6]; volatile u_char dummy; int emptymatch = 1; @@ -1013,18 +1013,20 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ all-0xff data and stored ecc block. Check the stored ecc. */ if (emptymatch) { for (i = 0; i < 6; i++) { - if (read_ecc[i] == 0xff) continue; + if (read_ecc[i] == 0xff) + continue; emptymatch = 0; break; } } /* If emptymatch still =1, check the data block. */ if (emptymatch) { - /* Note: this somewhat expensive test should not be triggered - often. It could be optimized away by examining the data in - the readbuf routine, and remembering the result. */ + /* Note: this somewhat expensive test should not be triggered + often. It could be optimized away by examining the data in + the readbuf routine, and remembering the result. */ for (i = 0; i < 512; i++) { - if (dat[i] == 0xff) continue; + if (dat[i] == 0xff) + continue; emptymatch = 0; break; } @@ -1033,7 +1035,8 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ erased block, in which case the ECC will not come out right. We'll suppress the error and tell the caller everything's OK. Because it is. */ - if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); + if (!emptymatch) + ret = doc_ecc_decode(rs_decoder, dat, calc_ecc); if (ret > 0) printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); } @@ -1048,13 +1051,22 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ return ret; } -/*u_char mydatabuf[528]; */ - -static struct nand_oobinfo doc200x_oobinfo = { - .useecc = MTD_NANDECC_AUTOPLACE, +//u_char mydatabuf[528]; + +/* The strange out-of-order .oobfree list below is a (possibly unneeded) + * attempt to retain compatibility. It used to read: + * .oobfree = { {8, 8} } + * Since that leaves two bytes unusable, it was changed. But the following + * scheme might affect existing jffs2 installs by moving the cleanmarker: + * .oobfree = { {6, 10} } + * jffs2 seems to handle the above gracefully, but the current scheme seems + * safer. The only problem with it is that any code that parses oobfree must + * be able to handle out-of-order segments. + */ +static struct nand_ecclayout doc200x_oobinfo = { .eccbytes = 6, .eccpos = {0, 1, 2, 3, 4, 5}, - .oobfree = { {8, 8} } + .oobfree = {{8, 8}, {6, 2}} }; /* Find the (I)NFTL Media Header, and optionally also the mirror media header. @@ -1063,28 +1075,28 @@ static struct nand_oobinfo doc200x_oobinfo = { either "ANAND" or "BNAND". If findmirror=1, also look for the mirror media header. The page #s of the found media headers are placed in mh0_page and mh1_page in the DOC private structure. */ -static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, - const char *id, int findmirror) +static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - unsigned offs, end = (MAX_MEDIAHEADER_SCAN << this->phys_erase_shift); + unsigned offs; int ret; size_t retlen; - end = min(end, mtd->size); /* paranoia */ - for (offs = 0; offs < end; offs += mtd->erasesize) { - ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); - if (retlen != mtd->oobblock) continue; + for (offs = 0; offs < mtd->size; offs += mtd->erasesize) { + ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf); + if (retlen != mtd->writesize) + continue; if (ret) { - printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", - offs); + printk(KERN_WARNING "ECC error scanning DOC at 0x%x\n", offs); } - if (memcmp(buf, id, 6)) continue; + if (memcmp(buf, id, 6)) + continue; printk(KERN_INFO "Found DiskOnChip %s Media Header at 0x%x\n", id, offs); if (doc->mh0_page == -1) { doc->mh0_page = offs >> this->page_shift; - if (!findmirror) return 1; + if (!findmirror) + return 1; continue; } doc->mh1_page = offs >> this->page_shift; @@ -1097,8 +1109,8 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, /* Only one mediaheader was found. We want buf to contain a mediaheader on return, so we'll have to re-read the one we found. */ offs = doc->mh0_page << this->page_shift; - ret = mtd->read(mtd, offs, mtd->oobblock, &retlen, buf); - if (retlen != mtd->oobblock) { + ret = mtd->read(mtd, offs, mtd->writesize, &retlen, buf); + if (retlen != mtd->writesize) { /* Insanity. Give up. */ printk(KERN_ERR "Read DiskOnChip Media Header once, but can't reread it???\n"); return 0; @@ -1106,8 +1118,7 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, return 1; } -static inline int __init nftl_partscan(struct mtd_info *mtd, - struct mtd_partition *parts) +static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -1115,19 +1126,23 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, u_char *buf; struct NFTLMediaHeader *mh; const unsigned psize = 1 << this->page_shift; + int numparts = 0; unsigned blocks, maxblocks; int offs, numheaders; - buf = kmalloc(mtd->oobblock, GFP_KERNEL); + buf = kmalloc(mtd->writesize, GFP_KERNEL); if (!buf) { printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); return 0; } - if (!(numheaders=find_media_headers(mtd, buf, "ANAND", 1))) goto out; - mh = (struct NFTLMediaHeader *) buf; + if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1))) + goto out; + mh = (struct NFTLMediaHeader *)buf; + + mh->NumEraseUnits = le16_to_cpu(mh->NumEraseUnits); + mh->FirstPhysicalEUN = le16_to_cpu(mh->FirstPhysicalEUN); + mh->FormattedSize = le32_to_cpu(mh->FormattedSize); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " DataOrgID = %s\n" " NumEraseUnits = %d\n" " FirstPhysicalEUN = %d\n" @@ -1136,7 +1151,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, mh->DataOrgID, mh->NumEraseUnits, mh->FirstPhysicalEUN, mh->FormattedSize, mh->UnitSizeFactor); -/*#endif */ blocks = mtd->size >> this->phys_erase_shift; maxblocks = min(32768U, mtd->erasesize - psize); @@ -1145,8 +1159,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, /* Auto-determine UnitSizeFactor. The constraints are: - There can be at most 32768 virtual blocks. - There can be at most (virtual block size - page size) - virtual blocks (because MediaHeader+BBT must fit in 1). - */ + virtual blocks (because MediaHeader+BBT must fit in 1). + */ mh->UnitSizeFactor = 0xff; while (blocks > maxblocks) { blocks >>= 1; @@ -1179,31 +1193,35 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, offs <<= this->page_shift; offs += mtd->erasesize; - /*parts[0].name = " DiskOnChip Boot / Media Header partition"; */ - /*parts[0].offset = 0; */ - /*parts[0].size = offs; */ + if (show_firmware_partition == 1) { + parts[0].name = " DiskOnChip Firmware / Media Header partition"; + parts[0].offset = 0; + parts[0].size = offs; + numparts = 1; + } + + parts[numparts].name = " DiskOnChip BDTL partition"; + parts[numparts].offset = offs; + parts[numparts].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; - parts[0].name = " DiskOnChip BDTL partition"; - parts[0].offset = offs; - parts[0].size = (mh->NumEraseUnits - numheaders) << this->bbt_erase_shift; + offs += parts[numparts].size; + numparts++; - offs += parts[0].size; if (offs < mtd->size) { - parts[1].name = " DiskOnChip Remainder partition"; - parts[1].offset = offs; - parts[1].size = mtd->size - offs; - ret = 2; - goto out; + parts[numparts].name = " DiskOnChip Remainder partition"; + parts[numparts].offset = offs; + parts[numparts].size = mtd->size - offs; + numparts++; } - ret = 1; -out: + + ret = numparts; + out: kfree(buf); return ret; } /* This is a stripped-down copy of the code in inftlmount.c */ -static inline int __init inftl_partscan(struct mtd_info *mtd, - struct mtd_partition *parts) +static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) { struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; @@ -1220,15 +1238,16 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, if (inftl_bbt_write) end -= (INFTL_BBT_RESERVED_BLOCKS << this->phys_erase_shift); - buf = kmalloc(mtd->oobblock, GFP_KERNEL); + buf = kmalloc(mtd->writesize, GFP_KERNEL); if (!buf) { printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); return 0; } - if (!find_media_headers(mtd, buf, "BNAND", 0)) goto out; + if (!find_media_headers(mtd, buf, "BNAND", 0)) + goto out; doc->mh1_page = doc->mh0_page + (4096 >> this->page_shift); - mh = (struct INFTLMediaHeader *) buf; + mh = (struct INFTLMediaHeader *)buf; mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks); mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions); @@ -1237,8 +1256,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, mh->FormatFlags = le32_to_cpu(mh->FormatFlags); mh->PercentUsed = le32_to_cpu(mh->PercentUsed); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " bootRecordID = %s\n" " NoOfBootImageBlocks = %d\n" " NoOfBinaryPartitions = %d\n" @@ -1256,7 +1273,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, ((unsigned char *) &mh->OsakVersion)[2] & 0xf, ((unsigned char *) &mh->OsakVersion)[3] & 0xf, mh->PercentUsed); -/*#endif */ vshift = this->phys_erase_shift + mh->BlockMultiplierBits; @@ -1282,8 +1298,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, ip->spareUnits = le32_to_cpu(ip->spareUnits); ip->Reserved0 = le32_to_cpu(ip->Reserved0); -/*#ifdef CONFIG_MTD_DEBUG_VERBOSE */ -/* if (CONFIG_MTD_DEBUG_VERBOSE >= 2) */ printk(KERN_INFO " PARTITION[%d] ->\n" " virtualUnits = %d\n" " firstUnit = %d\n" @@ -1293,16 +1307,14 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, i, ip->virtualUnits, ip->firstUnit, ip->lastUnit, ip->flags, ip->spareUnits); -/*#endif */ -/* - if ((i == 0) && (ip->firstUnit > 0)) { + if ((show_firmware_partition == 1) && + (i == 0) && (ip->firstUnit > 0)) { parts[0].name = " DiskOnChip IPL / Media Header partition"; parts[0].offset = 0; parts[0].size = mtd->erasesize * ip->firstUnit; numparts = 1; } -*/ if (ip->flags & INFTL_BINARY) parts[numparts].name = " DiskOnChip BDK partition"; @@ -1311,8 +1323,10 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, parts[numparts].offset = ip->firstUnit << vshift; parts[numparts].size = (1 + ip->lastUnit - ip->firstUnit) << vshift; numparts++; - if (ip->lastUnit > lastvunit) lastvunit = ip->lastUnit; - if (ip->flags & INFTL_LAST) break; + if (ip->lastUnit > lastvunit) + lastvunit = ip->lastUnit; + if (ip->flags & INFTL_LAST) + break; } lastvunit++; if ((lastvunit << vshift) < end) { @@ -1322,7 +1336,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, numparts++; } ret = numparts; -out: + out: kfree(buf); return ret; } @@ -1334,11 +1348,12 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd) struct doc_priv *doc = this->priv; struct mtd_partition parts[2]; - memset((char *) parts, 0, sizeof(parts)); + memset((char *)parts, 0, sizeof(parts)); /* On NFTL, we have to find the media headers before we can read the BBTs, since they're stored in the media header eraseblocks. */ numparts = nftl_partscan(mtd, parts); - if (!numparts) return -EIO; + if (!numparts) + return -EIO; this->bbt_td->options = NAND_BBT_ABSPAGE | NAND_BBT_8BIT | NAND_BBT_SAVECONTENT | NAND_BBT_WRITE | NAND_BBT_VERSION; @@ -1385,8 +1400,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) this->bbt_td->pages[0] = 2; this->bbt_md = NULL; } else { - this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | - NAND_BBT_VERSION; + this->bbt_td->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION; if (inftl_bbt_write) this->bbt_td->options |= NAND_BBT_WRITE; this->bbt_td->offs = 8; @@ -1396,8 +1410,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) this->bbt_td->reserved_block_code = 0x01; this->bbt_td->pattern = "MSYS_BBT"; - this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | - NAND_BBT_VERSION; + this->bbt_md->options = NAND_BBT_LASTBLOCK | NAND_BBT_8BIT | NAND_BBT_VERSION; if (inftl_bbt_write) this->bbt_md->options |= NAND_BBT_WRITE; this->bbt_md->offs = 8; @@ -1412,12 +1425,13 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) At least as nand_bbt.c is currently written. */ if ((ret = nand_scan_bbt(mtd, NULL))) return ret; - memset((char *) parts, 0, sizeof(parts)); + memset((char *)parts, 0, sizeof(parts)); numparts = inftl_partscan(mtd, parts); /* At least for now, require the INFTL Media Header. We could probably do without it for non-INFTL use, since all it gives us is autopartitioning, but I want to give it more thought. */ - if (!numparts) return -EIO; + if (!numparts) + return -EIO; add_mtd_device(mtd); #ifdef CONFIG_MTD_PARTITIONS if (!no_autopart) @@ -1431,7 +1445,6 @@ static inline int __init doc2000_init(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - this->write_byte = doc2000_write_byte; this->read_byte = doc2000_read_byte; this->write_buf = doc2000_writebuf; this->read_buf = doc2000_readbuf; @@ -1449,7 +1462,6 @@ static inline int __init doc2001_init(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - this->write_byte = doc2001_write_byte; this->read_byte = doc2001_read_byte; this->write_buf = doc2001_writebuf; this->read_buf = doc2001_readbuf; @@ -1481,16 +1493,15 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; struct doc_priv *doc = this->priv; - this->write_byte = NULL; this->read_byte = doc2001plus_read_byte; this->write_buf = doc2001plus_writebuf; this->read_buf = doc2001plus_readbuf; this->verify_buf = doc2001plus_verifybuf; this->scan_bbt = inftl_scan_bbt; - this->hwcontrol = NULL; + this->cmd_ctrl = NULL; this->select_chip = doc2001plus_select_chip; this->cmdfunc = doc2001plus_command; - this->enable_hwecc = doc2001plus_enable_hwecc; + this->ecc.hwctl = doc2001plus_enable_hwecc; doc->chips_per_floor = 1; mtd->name = "DiskOnChip Millennium Plus"; @@ -1498,7 +1509,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd) return 1; } -static inline int __init doc_probe(unsigned long physadr) +static int __init doc_probe(unsigned long physadr) { unsigned char ChipID; struct mtd_info *mtd; @@ -1527,20 +1538,16 @@ static inline int __init doc_probe(unsigned long physadr) save_control = ReadDOC(virtadr, DOCControl); /* Reset the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, - virtadr, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, - virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, virtadr, DOCControl); /* Enable the DiskOnChip ASIC */ - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, - virtadr, DOCControl); - WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, - virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl); + WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, virtadr, DOCControl); ChipID = ReadDOC(virtadr, ChipID); - switch(ChipID) { + switch (ChipID) { case DOC_ChipID_Doc2k: reg = DoC_2k_ECCStatus; break; @@ -1556,15 +1563,13 @@ static inline int __init doc_probe(unsigned long physadr) ReadDOC(virtadr, Mplus_Power); /* Reset the Millennium Plus ASIC */ - tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | - DOC_MODE_BDECT; + tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT; WriteDOC(tmp, virtadr, Mplus_DOCControl); WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); mdelay(1); /* Enable the Millennium Plus ASIC */ - tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | - DOC_MODE_BDECT; + tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT; WriteDOC(tmp, virtadr, Mplus_DOCControl); WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); mdelay(1); @@ -1588,7 +1593,7 @@ static inline int __init doc_probe(unsigned long physadr) goto notfound; } /* Check the TOGGLE bit in the ECC register */ - tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; + tmp = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; tmpb = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; tmpc = ReadDOC_(virtadr, reg) & DOC_TOGGLE_BIT; if ((tmp == tmpb) || (tmp != tmpc)) { @@ -1618,11 +1623,11 @@ static inline int __init doc_probe(unsigned long physadr) if (ChipID == DOC_ChipID_DocMilPlus16) { WriteDOC(~newval, virtadr, Mplus_AliasResolution); oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); - WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */ + WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it } else { WriteDOC(~newval, virtadr, AliasResolution); oldval = ReadDOC(doc->virtadr, AliasResolution); - WriteDOC(newval, virtadr, AliasResolution); /* restore it */ + WriteDOC(newval, virtadr, AliasResolution); // restore it } newval = ~newval; if (oldval == newval) { @@ -1634,16 +1639,13 @@ static inline int __init doc_probe(unsigned long physadr) printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); len = sizeof(struct mtd_info) + - sizeof(struct nand_chip) + - sizeof(struct doc_priv) + - (2 * sizeof(struct nand_bbt_descr)); - mtd = kmalloc(len, GFP_KERNEL); + sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); + mtd = kzalloc(len, GFP_KERNEL); if (!mtd) { printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len); ret = -ENOMEM; goto fail; } - memset(mtd, 0, len); nand = (struct nand_chip *) (mtd + 1); doc = (struct doc_priv *) (nand + 1); @@ -1655,17 +1657,19 @@ static inline int __init doc_probe(unsigned long physadr) nand->priv = doc; nand->select_chip = doc200x_select_chip; - nand->hwcontrol = doc200x_hwcontrol; + nand->cmd_ctrl = doc200x_hwcontrol; nand->dev_ready = doc200x_dev_ready; nand->waitfunc = doc200x_wait; nand->block_bad = doc200x_block_bad; - nand->enable_hwecc = doc200x_enable_hwecc; - nand->calculate_ecc = doc200x_calculate_ecc; - nand->correct_data = doc200x_correct_data; + nand->ecc.hwctl = doc200x_enable_hwecc; + nand->ecc.calculate = doc200x_calculate_ecc; + nand->ecc.correct = doc200x_correct_data; - nand->autooob = &doc200x_oobinfo; - nand->eccmode = NAND_ECC_HW6_512; - nand->options = NAND_USE_FLASH_BBT | NAND_HWECC_SYNDROME; + nand->ecc.layout = &doc200x_oobinfo; + nand->ecc.mode = NAND_ECC_HW_SYNDROME; + nand->ecc.size = 512; + nand->ecc.bytes = 6; + nand->options = NAND_USE_FLASH_BBT; doc->physadr = physadr; doc->virtadr = virtadr; @@ -1699,11 +1703,11 @@ static inline int __init doc_probe(unsigned long physadr) doclist = mtd; return 0; -notfound: + notfound: /* Put back the contents of the DOCControl register, in case it's not actually a DiskOnChip. */ WriteDOC(save_control, virtadr, DOCControl); -fail: + fail: iounmap(virtadr); return ret; } @@ -1740,7 +1744,7 @@ static int __init init_nanddoc(void) */ rs_decoder = init_rs(10, 0x409, FCR, 1, NROOTS); if (!rs_decoder) { - printk (KERN_ERR "DiskOnChip: Could not create a RS decoder\n"); + printk(KERN_ERR "DiskOnChip: Could not create a RS decoder\n"); return -ENOMEM; } @@ -1750,7 +1754,7 @@ static int __init init_nanddoc(void) if (ret < 0) goto outerr; } else { - for (i=0; (doc_locations[i] != 0xffffffff); i++) { + for (i = 0; (doc_locations[i] != 0xffffffff); i++) { doc_probe(doc_locations[i]); } } @@ -1762,7 +1766,7 @@ static int __init init_nanddoc(void) goto outerr; } return 0; -outerr: + outerr: free_rs(rs_decoder); return ret; } diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 6416d1529e9..aeb179731d6 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -10,39 +10,21 @@ * http://www.linux-mtd.infradead.org/tech/nand.html * * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) - * 2002 Thomas Gleixner (tglx@linutronix.de) + * 2002-2006 Thomas Gleixner (tglx@linutronix.de) * - * 02-08-2004 tglx: support for strange chips, which cannot auto increment - * pages on read / read_oob - * - * 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes - * pointed this out, as he marked an auto increment capable chip - * as NOAUTOINCR in the board driver. - * Make reads over block boundaries work too - * - * 04-14-2004 tglx: first working version for 2k page size chips - * - * 05-19-2004 tglx: Basic support for Renesas AG-AND chips - * - * 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared - * among multiple independend devices. Suggestions and initial patch - * from Ben Dooks - * - * Credits: + * Credits: * David Woodhouse for adding multichip support * * Aleph One Ltd. and Toby Churchill Ltd. for supporting the * rework for 2K page size chips * - * TODO: + * TODO: * Enable cached programming for 2k page size chips * Check, if mtd->ecctype should be set to MTD_ECC_HW * if we have HW ecc support. * The AG-AND chips have nice features for speed improvement, * which are not supported yet. Read / program 4 pages in one go. * - * $Id: nand_base.c,v 1.126 2004/12/13 11:22:25 lavinen Exp $ - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. @@ -51,8 +33,10 @@ /* XXX U-BOOT XXX */ #if 0 +#include #include #include +#include #include #include #include @@ -62,6 +46,7 @@ #include #include #include +#include #include #ifdef CONFIG_MTD_PARTITIONS @@ -72,10 +57,13 @@ #include +#define ENOTSUPP 524 /* Operation is not supported */ + #if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) #include #include +#include #include #include #include @@ -89,83 +77,67 @@ #endif /* Define default oob placement schemes for large and small page devices */ -static struct nand_oobinfo nand_oob_8 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_8 = { .eccbytes = 3, .eccpos = {0, 1, 2}, - .oobfree = { {3, 2}, {6, 2} } + .oobfree = { + {.offset = 3, + .length = 2}, + {.offset = 6, + .length = 2}} }; -static struct nand_oobinfo nand_oob_16 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_16 = { .eccbytes = 6, .eccpos = {0, 1, 2, 3, 6, 7}, - .oobfree = { {8, 8} } + .oobfree = { + {.offset = 8, + . length = 8}} }; -static struct nand_oobinfo nand_oob_64 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_64 = { .eccbytes = 24, .eccpos = { - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63}, - .oobfree = { {2, 38} } + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63}, + .oobfree = { + {.offset = 2, + .length = 38}} }; -static struct nand_oobinfo nand_oob_128 = { - .useecc = MTD_NANDECC_AUTOPLACE, +static struct nand_ecclayout nand_oob_128 = { .eccbytes = 48, .eccpos = { - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127}, - .oobfree = { {2, 78} } + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127}, + .oobfree = { + {.offset = 2, + .length = 78}} }; -/* This is used for padding purposes in nand_write_oob */ -static u_char *ffchars; + +static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, + int new_state); + +static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops); + +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this); /* - * NAND low-level MTD interface functions + * For devices which display every fart in the system on a seperate LED. Is + * compiled away when LED support is disabled. */ -static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len); -static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); -static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len); - -static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); -static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); -static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf); -static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf); -static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel); -static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf); /* XXX U-BOOT XXX */ #if 0 -static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t * retlen); -static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, - unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); -#endif -static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); -static void nand_sync (struct mtd_info *mtd); - -/* Some internal functions */ -static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, - struct nand_oobinfo *oobsel, int mode); -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE -static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, - u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode); -#else -#define nand_verify_pages(...) (0) +DEFINE_LED_TRIGGER(nand_led_trigger); #endif -static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state); - /** * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure @@ -174,33 +146,25 @@ static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int n */ /* XXX U-BOOT XXX */ #if 0 -static void nand_release_device (struct mtd_info *mtd) +static void nand_release_device(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; /* De-select the NAND device */ - this->select_chip(mtd, -1); - /* Do we have a hardware controller ? */ - if (this->controller) { - spin_lock(&this->controller->lock); - this->controller->active = NULL; - spin_unlock(&this->controller->lock); - } - /* Release the chip */ - spin_lock (&this->chip_lock); - this->state = FL_READY; - wake_up (&this->wq); - spin_unlock (&this->chip_lock); + chip->select_chip(mtd, -1); + + /* Release the controller and the chip */ + spin_lock(&chip->controller->lock); + chip->controller->active = NULL; + chip->state = FL_READY; + wake_up(&chip->controller->wq); + spin_unlock(&chip->controller->lock); } #else static void nand_release_device (struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; this->select_chip(mtd, -1); /* De-select the NAND device */ - if (ffchars) { - kfree(ffchars); - ffchars = NULL; - } } #endif @@ -210,23 +174,10 @@ static void nand_release_device (struct mtd_info *mtd) * * Default read function for 8bit buswith */ -static u_char nand_read_byte(struct mtd_info *mtd) -{ - struct nand_chip *this = mtd->priv; - return readb(this->IO_ADDR_R); -} - -/** - * nand_write_byte - [DEFAULT] write one byte to the chip - * @mtd: MTD device structure - * @byte: pointer to data byte to write - * - * Default write function for 8it buswith - */ -static void nand_write_byte(struct mtd_info *mtd, u_char byte) +static uint8_t nand_read_byte(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; - writeb(byte, this->IO_ADDR_W); + struct nand_chip *chip = mtd->priv; + return readb(chip->IO_ADDR_R); } /** @@ -236,24 +187,10 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte) * Default read function for 16bit buswith with * endianess conversion */ -static u_char nand_read_byte16(struct mtd_info *mtd) -{ - struct nand_chip *this = mtd->priv; - return (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); -} - -/** - * nand_write_byte16 - [DEFAULT] write one byte endianess aware to the chip - * @mtd: MTD device structure - * @byte: pointer to data byte to write - * - * Default write function for 16bit buswith with - * endianess conversion - */ -static void nand_write_byte16(struct mtd_info *mtd, u_char byte) +static uint8_t nand_read_byte16(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; - writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); + struct nand_chip *chip = mtd->priv; + return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); } /** @@ -265,40 +202,26 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte) */ static u16 nand_read_word(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; - return readw(this->IO_ADDR_R); -} - -/** - * nand_write_word - [DEFAULT] write one word to the chip - * @mtd: MTD device structure - * @word: data word to write - * - * Default write function for 16bit buswith without - * endianess conversion - */ -static void nand_write_word(struct mtd_info *mtd, u16 word) -{ - struct nand_chip *this = mtd->priv; - writew(word, this->IO_ADDR_W); + struct nand_chip *chip = mtd->priv; + return readw(chip->IO_ADDR_R); } /** * nand_select_chip - [DEFAULT] control CE line * @mtd: MTD device structure - * @chip: chipnumber to select, -1 for deselect + * @chipnr: chipnumber to select, -1 for deselect * * Default select function for 1 chip devices. */ -static void nand_select_chip(struct mtd_info *mtd, int chip) +static void nand_select_chip(struct mtd_info *mtd, int chipnr) { - struct nand_chip *this = mtd->priv; - switch(chip) { + struct nand_chip *chip = mtd->priv; + + switch (chipnr) { case -1: - this->hwcontrol(mtd, NAND_CTL_CLRNCE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); break; case 0: - this->hwcontrol(mtd, NAND_CTL_SETNCE); break; default: @@ -314,13 +237,13 @@ static void nand_select_chip(struct mtd_info *mtd, int chip) * * Default write function for 8bit buswith */ -static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; - for (i=0; iIO_ADDR_W); + for (i = 0; i < len; i++) + writeb(buf[i], chip->IO_ADDR_W); } /** @@ -331,13 +254,13 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) * * Default read function for 8bit buswith */ -static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; - for (i=0; iIO_ADDR_R); + for (i = 0; i < len; i++) + buf[i] = readb(chip->IO_ADDR_R); } /** @@ -348,15 +271,14 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) * * Default verify function for 8bit buswith */ -static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) +static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; - for (i=0; iIO_ADDR_R)) + for (i = 0; i < len; i++) + if (buf[i] != readb(chip->IO_ADDR_R)) return -EFAULT; - return 0; } @@ -368,15 +290,15 @@ static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) * * Default write function for 16bit buswith */ -static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) +static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; u16 *p = (u16 *) buf; len >>= 1; - for (i=0; iIO_ADDR_W); + for (i = 0; i < len; i++) + writew(p[i], chip->IO_ADDR_W); } @@ -388,15 +310,15 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) * * Default read function for 16bit buswith */ -static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) +static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; u16 *p = (u16 *) buf; len >>= 1; - for (i=0; iIO_ADDR_R); + for (i = 0; i < len; i++) + p[i] = readw(chip->IO_ADDR_R); } /** @@ -407,15 +329,15 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len) * * Default verify function for 16bit buswith */ -static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) +static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) { int i; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; u16 *p = (u16 *) buf; len >>= 1; - for (i=0; iIO_ADDR_R)) + for (i = 0; i < len; i++) + if (p[i] != readw(chip->IO_ADDR_R)) return -EFAULT; return 0; @@ -432,38 +354,36 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) { int page, chipnr, res = 0; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; u16 bad; - page = (int)(ofs >> this->page_shift) & this->pagemask; + page = (int)(ofs >> chip->page_shift) & chip->pagemask; if (getchip) { - chipnr = (int)(ofs >> this->chip_shift); + chipnr = (int)(ofs >> chip->chip_shift); - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_READING); + nand_get_device(chip, mtd, FL_READING); /* Select the NAND device */ - this->select_chip(mtd, chipnr); + chip->select_chip(mtd, chipnr); } - if (this->options & NAND_BUSWIDTH_16) { - this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos & 0xFE, page); - bad = cpu_to_le16(this->read_word(mtd)); - if (this->badblockpos & 0x1) - bad >>= 1; + if (chip->options & NAND_BUSWIDTH_16) { + chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos & 0xFE, + page); + bad = cpu_to_le16(chip->read_word(mtd)); + if (chip->badblockpos & 0x1) + bad >>= 8; if ((bad & 0xFF) != 0xff) res = 1; } else { - this->cmdfunc (mtd, NAND_CMD_READOOB, this->badblockpos, page); - if (this->read_byte(mtd) != 0xff) + chip->cmdfunc(mtd, NAND_CMD_READOOB, chip->badblockpos, page); + if (chip->read_byte(mtd) != 0xff) res = 1; } - if (getchip) { - /* Deselect and wake up anyone waiting on the device */ + if (getchip) nand_release_device(mtd); - } return res; } @@ -478,22 +398,33 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) */ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *this = mtd->priv; - u_char buf[2] = {0, 0}; - size_t retlen; - int block; + struct nand_chip *chip = mtd->priv; + uint8_t buf[2] = { 0, 0 }; + int block, ret; /* Get block number */ - block = ((int) ofs) >> this->bbt_erase_shift; - this->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); + block = (int)(ofs >> chip->bbt_erase_shift); + if (chip->bbt) + chip->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); /* Do we have a flash based bad block table ? */ - if (this->options & NAND_USE_FLASH_BBT) - return nand_update_bbt (mtd, ofs); + if (chip->options & NAND_USE_FLASH_BBT) + ret = nand_update_bbt(mtd, ofs); + else { + /* We write two bytes, so we dont have to mess with 16 bit + * access + */ + ofs += mtd->oobsize; + chip->ops.len = chip->ops.ooblen = 2; + chip->ops.datbuf = NULL; + chip->ops.oobbuf = buf; + chip->ops.ooboffs = chip->badblockpos & ~0x01; - /* We write two bytes, so we dont have to mess with 16 bit access */ - ofs += mtd->oobsize + (this->badblockpos & ~0x01); - return nand_write_oob (mtd, ofs , 2, &retlen, buf); + ret = nand_do_write_oob(mtd, ofs, &chip->ops); + } + if (!ret) + mtd->ecc_stats.badblocks++; + return ret; } /** @@ -503,12 +434,12 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) * * The function expects, that the device is already selected */ -static int nand_check_wp (struct mtd_info *mtd) +static int nand_check_wp(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; /* Check the WP bit */ - this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); - return (this->read_byte(mtd) & 0x80) ? 0 : 1; + chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); + return (chip->read_byte(mtd) & NAND_STATUS_WP) ? 0 : 1; } /** @@ -521,16 +452,46 @@ static int nand_check_wp (struct mtd_info *mtd) * Check, if the block is bad. Either by reading the bad block table or * calling of the scan function. */ -static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, int allowbbt) +static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, + int allowbbt) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; - if (!this->bbt) - return this->block_bad(mtd, ofs, getchip); + if (!chip->bbt) + return chip->block_bad(mtd, ofs, getchip); /* Return info from the table */ - return nand_isbad_bbt (mtd, ofs, allowbbt); + return nand_isbad_bbt(mtd, ofs, allowbbt); +} + +/* + * Wait for the ready pin, after a command + * The timeout is catched later. + */ +/* XXX U-BOOT XXX */ +#if 0 +void nand_wait_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + unsigned long timeo = jiffies + 2; + + led_trigger_event(nand_led_trigger, LED_FULL); + /* wait until command is processed or timeout occures */ + do { + if (chip->dev_ready(mtd)) + break; + touch_softlockup_watchdog(); + } while (time_before(jiffies, timeo)); + led_trigger_event(nand_led_trigger, LED_OFF); } +EXPORT_SYMBOL_GPL(nand_wait_ready); +#else +void nand_wait_ready(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + nand_wait(mtd, chip); +} +#endif /** * nand_command - [DEFAULT] Send command to NAND device @@ -542,21 +503,21 @@ static int nand_block_checkbad (struct mtd_info *mtd, loff_t ofs, int getchip, i * Send command to NAND device. This function is used for small page * devices (256/512 Bytes per page) */ -static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) +static void nand_command(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) { - register struct nand_chip *this = mtd->priv; + register struct nand_chip *chip = mtd->priv; + int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; - /* Begin command latch cycle */ - this->hwcontrol(mtd, NAND_CTL_SETCLE); /* * Write out the command to the device. */ if (command == NAND_CMD_SEQIN) { int readcmd; - if (column >= mtd->oobblock) { + if (column >= mtd->writesize) { /* OOB area */ - column -= mtd->oobblock; + column -= mtd->writesize; readcmd = NAND_CMD_READOOB; } else if (column < 256) { /* First 256 bytes --> READ0 */ @@ -565,38 +526,37 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in column -= 256; readcmd = NAND_CMD_READ1; } - this->write_byte(mtd, readcmd); + chip->cmd_ctrl(mtd, readcmd, ctrl); + ctrl &= ~NAND_CTRL_CHANGE; } - this->write_byte(mtd, command); + chip->cmd_ctrl(mtd, command, ctrl); - /* Set ALE and clear CLE to start address cycle */ - this->hwcontrol(mtd, NAND_CTL_CLRCLE); - - if (column != -1 || page_addr != -1) { - this->hwcontrol(mtd, NAND_CTL_SETALE); - - /* Serially input address */ - if (column != -1) { - /* Adjust columns for 16 bit buswidth */ - if (this->options & NAND_BUSWIDTH_16) - column >>= 1; - this->write_byte(mtd, column); - } - if (page_addr != -1) { - this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); - this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); - /* One more address cycle for devices > 32MiB */ - if (this->chipsize > (32 << 20)) - this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); - } - /* Latch in address */ - this->hwcontrol(mtd, NAND_CTL_CLRALE); + /* + * Address cycle, when necessary + */ + ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE; + /* Serially input address */ + if (column != -1) { + /* Adjust columns for 16 bit buswidth */ + if (chip->options & NAND_BUSWIDTH_16) + column >>= 1; + chip->cmd_ctrl(mtd, column, ctrl); + ctrl &= ~NAND_CTRL_CHANGE; } + if (page_addr != -1) { + chip->cmd_ctrl(mtd, page_addr, ctrl); + ctrl &= ~NAND_CTRL_CHANGE; + chip->cmd_ctrl(mtd, page_addr >> 8, ctrl); + /* One more address cycle for devices > 32MiB */ + if (chip->chipsize > (32 << 20)) + chip->cmd_ctrl(mtd, page_addr >> 16, ctrl); + } + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); /* * program and erase have their own busy handlers * status and sequential in needs no delay - */ + */ switch (command) { case NAND_CMD_PAGEPROG: @@ -607,32 +567,32 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in return; case NAND_CMD_RESET: - if (this->dev_ready) + if (chip->dev_ready) break; - udelay(this->chip_delay); - this->hwcontrol(mtd, NAND_CTL_SETCLE); - this->write_byte(mtd, NAND_CMD_STATUS); - this->hwcontrol(mtd, NAND_CTL_CLRCLE); - while ( !(this->read_byte(mtd) & 0x40)); + udelay(chip->chip_delay); + chip->cmd_ctrl(mtd, NAND_CMD_STATUS, + NAND_CTRL_CLE | NAND_CTRL_CHANGE); + chip->cmd_ctrl(mtd, + NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); + while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; return; - /* This applies to read commands */ + /* This applies to read commands */ default: /* * If we don't have access to the busy pin, we apply the given * command delay - */ - if (!this->dev_ready) { - udelay (this->chip_delay); + */ + if (!chip->dev_ready) { + udelay(chip->chip_delay); return; } } - /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ - ndelay (100); - /* wait until command is processed */ - while (!this->dev_ready(mtd)); + ndelay(100); + + nand_wait_ready(mtd); } /** @@ -642,55 +602,53 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in * @column: the column address for this command, -1 if none * @page_addr: the page address for this command, -1 if none * - * Send command to NAND device. This is the version for the new large page devices - * We dont have the seperate regions as we have in the small page devices. - * We must emulate NAND_CMD_READOOB to keep the code compatible. - * + * Send command to NAND device. This is the version for the new large page + * devices We dont have the separate regions as we have in the small page + * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. */ -static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) +static void nand_command_lp(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) { - register struct nand_chip *this = mtd->priv; + register struct nand_chip *chip = mtd->priv; /* Emulate NAND_CMD_READOOB */ if (command == NAND_CMD_READOOB) { - column += mtd->oobblock; + column += mtd->writesize; command = NAND_CMD_READ0; } - - /* Begin command latch cycle */ - this->hwcontrol(mtd, NAND_CTL_SETCLE); - /* Write out the command to the device. */ - this->write_byte(mtd, command); - /* End command latch cycle */ - this->hwcontrol(mtd, NAND_CTL_CLRCLE); + /* Command latch cycle */ + chip->cmd_ctrl(mtd, command & 0xff, + NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); if (column != -1 || page_addr != -1) { - this->hwcontrol(mtd, NAND_CTL_SETALE); + int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; /* Serially input address */ if (column != -1) { /* Adjust columns for 16 bit buswidth */ - if (this->options & NAND_BUSWIDTH_16) + if (chip->options & NAND_BUSWIDTH_16) column >>= 1; - this->write_byte(mtd, column & 0xff); - this->write_byte(mtd, column >> 8); + chip->cmd_ctrl(mtd, column, ctrl); + ctrl &= ~NAND_CTRL_CHANGE; + chip->cmd_ctrl(mtd, column >> 8, ctrl); } if (page_addr != -1) { - this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); - this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); + chip->cmd_ctrl(mtd, page_addr, ctrl); + chip->cmd_ctrl(mtd, page_addr >> 8, + NAND_NCE | NAND_ALE); /* One more address cycle for devices > 128MiB */ - if (this->chipsize > (128 << 20)) - this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); + if (chip->chipsize > (128 << 20)) + chip->cmd_ctrl(mtd, page_addr >> 16, + NAND_NCE | NAND_ALE); } - /* Latch in address */ - this->hwcontrol(mtd, NAND_CTL_CLRALE); } + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); /* * program and erase have their own busy handlers - * status and sequential in needs no delay - */ + * status, sequential in, and deplete1 need no delay + */ switch (command) { case NAND_CMD_CACHEDPROG: @@ -698,51 +656,69 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, case NAND_CMD_ERASE1: case NAND_CMD_ERASE2: case NAND_CMD_SEQIN: + case NAND_CMD_RNDIN: case NAND_CMD_STATUS: + case NAND_CMD_DEPLETE1: return; + /* + * read error status commands require only a short delay + */ + case NAND_CMD_STATUS_ERROR: + case NAND_CMD_STATUS_ERROR0: + case NAND_CMD_STATUS_ERROR1: + case NAND_CMD_STATUS_ERROR2: + case NAND_CMD_STATUS_ERROR3: + udelay(chip->chip_delay); + return; case NAND_CMD_RESET: - if (this->dev_ready) + if (chip->dev_ready) break; - udelay(this->chip_delay); - this->hwcontrol(mtd, NAND_CTL_SETCLE); - this->write_byte(mtd, NAND_CMD_STATUS); - this->hwcontrol(mtd, NAND_CTL_CLRCLE); - while ( !(this->read_byte(mtd) & 0x40)); + udelay(chip->chip_delay); + chip->cmd_ctrl(mtd, NAND_CMD_STATUS, + NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, + NAND_NCE | NAND_CTRL_CHANGE); + while (!(chip->read_byte(mtd) & NAND_STATUS_READY)) ; + return; + + case NAND_CMD_RNDOUT: + /* No ready / busy check necessary */ + chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART, + NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, + NAND_NCE | NAND_CTRL_CHANGE); return; case NAND_CMD_READ0: - /* Begin command latch cycle */ - this->hwcontrol(mtd, NAND_CTL_SETCLE); - /* Write out the start read command */ - this->write_byte(mtd, NAND_CMD_READSTART); - /* End command latch cycle */ - this->hwcontrol(mtd, NAND_CTL_CLRCLE); - /* Fall through into ready check */ - - /* This applies to read commands */ + chip->cmd_ctrl(mtd, NAND_CMD_READSTART, + NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); + chip->cmd_ctrl(mtd, NAND_CMD_NONE, + NAND_NCE | NAND_CTRL_CHANGE); + + /* This applies to read commands */ default: /* * If we don't have access to the busy pin, we apply the given * command delay - */ - if (!this->dev_ready) { - udelay (this->chip_delay); + */ + if (!chip->dev_ready) { + udelay(chip->chip_delay); return; } } /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ - ndelay (100); - /* wait until command is processed */ - while (!this->dev_ready(mtd)); + ndelay(100); + + nand_wait_ready(mtd); } /** * nand_get_device - [GENERIC] Get chip for selected access - * @this: the nand chip descriptor + * @chip: the nand chip descriptor * @mtd: MTD device structure * @new_state: the state which is requested * @@ -750,100 +726,96 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column, */ /* XXX U-BOOT XXX */ #if 0 -static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) +static int +nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) { - struct nand_chip *active = this; - - DECLARE_WAITQUEUE (wait, current); + spinlock_t *lock = &chip->controller->lock; + wait_queue_head_t *wq = &chip->controller->wq; + DECLARE_WAITQUEUE(wait, current); + retry: + spin_lock(lock); - /* - * Grab the lock and see if the device is available - */ -retry: /* Hardware controller shared among independend devices */ - if (this->controller) { - spin_lock (&this->controller->lock); - if (this->controller->active) - active = this->controller->active; - else - this->controller->active = this; - spin_unlock (&this->controller->lock); - } + /* Hardware controller shared among independend devices */ + if (!chip->controller->active) + chip->controller->active = chip; - if (active == this) { - spin_lock (&this->chip_lock); - if (this->state == FL_READY) { - this->state = new_state; - spin_unlock (&this->chip_lock); - return; - } + if (chip->controller->active == chip && chip->state == FL_READY) { + chip->state = new_state; + spin_unlock(lock); + return 0; } - set_current_state (TASK_UNINTERRUPTIBLE); - add_wait_queue (&active->wq, &wait); - spin_unlock (&active->chip_lock); - schedule (); - remove_wait_queue (&active->wq, &wait); + if (new_state == FL_PM_SUSPENDED) { + spin_unlock(lock); + return (chip->state == FL_PM_SUSPENDED) ? 0 : -EAGAIN; + } + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(wq, &wait); + spin_unlock(lock); + schedule(); + remove_wait_queue(wq, &wait); goto retry; } #else -static void nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) {} +static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) +{ + return 0; +} #endif /** * nand_wait - [DEFAULT] wait until the command is done * @mtd: MTD device structure - * @this: NAND chip structure - * @state: state to select the max. timeout value + * @chip: NAND chip structure * * Wait for command done. This applies to erase and program only * Erase can take up to 400ms and program up to 20ms according to * general NAND and SmartMedia specs - * -*/ + */ /* XXX U-BOOT XXX */ #if 0 -static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) { - unsigned long timeo = jiffies; - int status; + + unsigned long timeo = jiffies; + int status, state = chip->state; if (state == FL_ERASING) - timeo += (HZ * 400) / 1000; + timeo += (HZ * 400) / 1000; else - timeo += (HZ * 20) / 1000; + timeo += (HZ * 20) / 1000; + + led_trigger_event(nand_led_trigger, LED_FULL); /* Apply this short delay always to ensure that we do wait tWB in * any case on any machine. */ - ndelay (100); + ndelay(100); - if ((state == FL_ERASING) && (this->options & NAND_IS_AND)) - this->cmdfunc (mtd, NAND_CMD_STATUS_MULTI, -1, -1); + if ((state == FL_ERASING) && (chip->options & NAND_IS_AND)) + chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); else - this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); + chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); while (time_before(jiffies, timeo)) { - /* Check, if we were interrupted */ - if (this->state != state) - return 0; - - if (this->dev_ready) { - if (this->dev_ready(mtd)) + if (chip->dev_ready) { + if (chip->dev_ready(mtd)) break; } else { - if (this->read_byte(mtd) & NAND_STATUS_READY) + if (chip->read_byte(mtd) & NAND_STATUS_READY) break; } - yield (); + cond_resched(); } - status = (int) this->read_byte(mtd); - return status; + led_trigger_event(nand_led_trigger, LED_OFF); - return 0; + status = (int)chip->read_byte(mtd); + return status; } #else -static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) +static int nand_wait(struct mtd_info *mtd, struct nand_chip *this) { unsigned long timeo; + int state = this->state; if (state == FL_ERASING) timeo = (CFG_HZ * 400) / 1000; @@ -881,1211 +853,1135 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state) #endif /** - * nand_write_page - [GENERIC] write one page - * @mtd: MTD device structure - * @this: NAND chip structure - * @page: startpage inside the chip, must be called with (page & this->pagemask) - * @oob_buf: out of band data buffer - * @oobsel: out of band selecttion structre - * @cached: 1 = enable cached programming if supported by chip - * - * Nand_page_program function is used for write and writev ! - * This function will always program a full page of data - * If you call it with a non page aligned buffer, you're lost :) - * - * Cached programming is not supported yet. + * nand_read_page_raw - [Intern] read raw page data without ecc + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data */ -static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, - u_char *oob_buf, struct nand_oobinfo *oobsel, int cached) +static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) { - int i, status; - u_char ecc_code[NAND_MAX_OOBSIZE]; - int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; - uint *oob_config = oobsel->eccpos; - int datidx = 0, eccidx = 0, eccsteps = this->eccsteps; - int eccbytes = 0; + chip->read_buf(mtd, buf, mtd->writesize); + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + return 0; +} - /* FIXME: Enable cached programming */ - cached = 0; +/** + * nand_read_page_swecc - [REPLACABLE] software ecc based page read function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data + */ +static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_calc = chip->buffers->ecccalc; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; - /* Send command to begin auto page programming */ - this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); + chip->ecc.read_page_raw(mtd, chip, buf); - /* Write out complete page of data, take care of eccmode */ - switch (eccmode) { - /* No ecc, write all */ - case NAND_ECC_NONE: - printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); - this->write_buf(mtd, this->data_poi, mtd->oobblock); - break; + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) + chip->ecc.calculate(mtd, p, &ecc_calc[i]); - /* Software ecc 3/256, write all */ - case NAND_ECC_SOFT: - for (; eccsteps; eccsteps--) { - this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); - for (i = 0; i < 3; i++, eccidx++) - oob_buf[oob_config[eccidx]] = ecc_code[i]; - datidx += this->eccsize; - } - this->write_buf(mtd, this->data_poi, mtd->oobblock); - break; - default: - eccbytes = this->eccbytes; - for (; eccsteps; eccsteps--) { - /* enable hardware ecc logic for write */ - this->enable_hwecc(mtd, NAND_ECC_WRITE); - this->write_buf(mtd, &this->data_poi[datidx], this->eccsize); - this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code); - for (i = 0; i < eccbytes; i++, eccidx++) - oob_buf[oob_config[eccidx]] = ecc_code[i]; - /* If the hardware ecc provides syndromes then - * the ecc code must be written immediately after - * the data bytes (words) */ - if (this->options & NAND_HWECC_SYNDROME) - this->write_buf(mtd, ecc_code, eccbytes); - datidx += this->eccsize; - } - break; - } + for (i = 0; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccpos[i]]; - /* Write out OOB data */ - if (this->options & NAND_HWECC_SYNDROME) - this->write_buf(mtd, &oob_buf[oobsel->eccbytes], mtd->oobsize - oobsel->eccbytes); - else - this->write_buf(mtd, oob_buf, mtd->oobsize); - - /* Send command to actually program the data */ - this->cmdfunc (mtd, cached ? NAND_CMD_CACHEDPROG : NAND_CMD_PAGEPROG, -1, -1); - - if (!cached) { - /* call wait ready function */ - status = this->waitfunc (mtd, this, FL_WRITING); - /* See if device thinks it succeeded */ - if (status & 0x01) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "%s: Failed write, page 0x%08x, ", - __FUNCTION__, page); - return -EIO; - } - } else { - /* FIXME: Implement cached programming ! */ - /* wait until cache is ready*/ - /* status = this->waitfunc (mtd, this, FL_CACHEDRPG); */ + eccsteps = chip->ecc.steps; + p = buf; + + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + + stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat == -1) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; } return 0; } -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE /** - * nand_verify_pages - [GENERIC] verify the chip contents after a write - * @mtd: MTD device structure - * @this: NAND chip structure - * @page: startpage inside the chip, must be called with (page & this->pagemask) - * @numpages: number of pages to verify - * @oob_buf: out of band data buffer - * @oobsel: out of band selecttion structre - * @chipnr: number of the current chip - * @oobmode: 1 = full buffer verify, 0 = ecc only + * nand_read_page_hwecc - [REPLACABLE] hardware ecc based page read function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data * - * The NAND device assumes that it is always writing to a cleanly erased page. - * Hence, it performs its internal write verification only on bits that - * transitioned from 1 to 0. The device does NOT verify the whole page on a - * byte by byte basis. It is possible that the page was not completely erased - * or the page is becoming unusable due to wear. The read with ECC would catch - * the error later when the ECC page check fails, but we would rather catch - * it early in the page write stage. Better to write no data than invalid data. + * Not for syndrome calculating ecc controllers which need a special oob layout */ -static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages, - u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode) -{ - int i, j, datidx = 0, oobofs = 0, res = -EIO; - int eccsteps = this->eccsteps; - int hweccbytes; - u_char oobdata[64]; - - hweccbytes = (this->options & NAND_HWECC_SYNDROME) ? (oobsel->eccbytes / eccsteps) : 0; - - /* Send command to read back the first page */ - this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); - - for(;;) { - for (j = 0; j < eccsteps; j++) { - /* Loop through and verify the data */ - if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "%s: " - "Failed write verify, page 0x%08x ", - __FUNCTION__, page); - goto out; - } - datidx += mtd->eccsize; - /* Have we a hw generator layout ? */ - if (!hweccbytes) - continue; - if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "%s: " - "Failed write verify, page 0x%08x ", - __FUNCTION__, page); - goto out; - } - oobofs += hweccbytes; - } +static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *ecc_calc = chip->buffers->ecccalc; + uint8_t *ecc_code = chip->buffers->ecccode; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + chip->ecc.hwctl(mtd, NAND_ECC_READ); + chip->read_buf(mtd, p, eccsize); + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + } + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - /* check, if we must compare all data or if we just have to - * compare the ecc bytes - */ - if (oobmode) { - if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "%s: " - "Failed write verify, page 0x%08x ", - __FUNCTION__, page); - goto out; - } - } else { - /* Read always, else autoincrement fails */ - this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps); - - if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) { - int ecccnt = oobsel->eccbytes; - - for (i = 0; i < ecccnt; i++) { - int idx = oobsel->eccpos[i]; - if (oobdata[idx] != oob_buf[oobofs + idx] ) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "%s: Failed ECC write " - "verify, page 0x%08x, " - "%6i bytes were succesful\n", - __FUNCTION__, page, i); - goto out; - } - } - } - } - oobofs += mtd->oobsize - hweccbytes * eccsteps; - page++; - numpages--; - - /* Apply delay or wait for ready/busy pin - * Do this before the AUTOINCR check, so no problems - * arise if a chip which does auto increment - * is marked as NOAUTOINCR by the board driver. - * Do this also before returning, so the chip is - * ready for the next command. - */ - if (!this->dev_ready) - udelay (this->chip_delay); - else - while (!this->dev_ready(mtd)); + for (i = 0; i < chip->ecc.total; i++) + ecc_code[i] = chip->oob_poi[eccpos[i]]; - /* All done, return happy */ - if (!numpages) - return 0; + eccsteps = chip->ecc.steps; + p = buf; + for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; - /* Check, if the chip supports auto page increment */ - if (!NAND_CANAUTOINCR(this)) - this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); + stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); + if (stat == -1) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; } - /* - * Terminate the read command. We come here in case of an error - * So we must issue a reset command. - */ -out: - this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1); - return res; + return 0; } -#endif /** - * nand_read - [MTD Interface] MTD compability function for nand_read_ecc - * @mtd: MTD device structure - * @from: offset to read from - * @len: number of bytes to read - * @retlen: pointer to variable to store the number of read bytes - * @buf: the databuffer to put data + * nand_read_page_syndrome - [REPLACABLE] hardware ecc syndrom based page read + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: buffer to store read data * - * This function simply calls nand_read_ecc with oob buffer and oobsel = NULL -*/ -static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) + * The hw generator calculates the error syndrome automatically. Therefor + * we need a special oob layout and handling. + */ +static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf) { - return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *p = buf; + uint8_t *oob = chip->oob_poi; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + int stat; + + chip->ecc.hwctl(mtd, NAND_ECC_READ); + chip->read_buf(mtd, p, eccsize); + + if (chip->ecc.prepad) { + chip->read_buf(mtd, oob, chip->ecc.prepad); + oob += chip->ecc.prepad; + } + + chip->ecc.hwctl(mtd, NAND_ECC_READSYN); + chip->read_buf(mtd, oob, eccbytes); + stat = chip->ecc.correct(mtd, p, oob, NULL); + + if (stat == -1) + mtd->ecc_stats.failed++; + else + mtd->ecc_stats.corrected += stat; + + oob += eccbytes; + + if (chip->ecc.postpad) { + chip->read_buf(mtd, oob, chip->ecc.postpad); + oob += chip->ecc.postpad; + } + } + + /* Calculate remaining oob bytes */ + i = mtd->oobsize - (oob - chip->oob_poi); + if (i) + chip->read_buf(mtd, oob, i); + + return 0; } +/** + * nand_transfer_oob - [Internal] Transfer oob to client buffer + * @chip: nand chip structure + * @oob: oob destination address + * @ops: oob ops structure + * @len: size of oob to transfer + */ +static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, + struct mtd_oob_ops *ops, size_t len) +{ + switch(ops->mode) { + + case MTD_OOB_PLACE: + case MTD_OOB_RAW: + memcpy(oob, chip->oob_poi + ops->ooboffs, len); + return oob + len; + + case MTD_OOB_AUTO: { + struct nand_oobfree *free = chip->ecc.layout->oobfree; + uint32_t boffs = 0, roffs = ops->ooboffs; + size_t bytes = 0; + + for(; free->length && len; free++, len -= bytes) { + /* Read request not from offset 0 ? */ + if (unlikely(roffs)) { + if (roffs >= free->length) { + roffs -= free->length; + continue; + } + boffs = free->offset + roffs; + bytes = min_t(size_t, len, + (free->length - roffs)); + roffs = 0; + } else { + bytes = min_t(size_t, len, free->length); + boffs = free->offset; + } + memcpy(oob, chip->oob_poi + boffs, bytes); + oob += bytes; + } + return oob; + } + default: + BUG(); + } + return NULL; +} /** - * nand_read_ecc - [MTD Interface] Read data with ECC + * nand_do_read_ops - [Internal] Read data with ECC + * * @mtd: MTD device structure * @from: offset to read from - * @len: number of bytes to read - * @retlen: pointer to variable to store the number of read bytes - * @buf: the databuffer to put data - * @oob_buf: filesystem supplied oob data buffer - * @oobsel: oob selection structure + * @ops: oob ops structure * - * NAND read with ECC + * Internal function. Called with chip held. */ -static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel) +static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { - int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1; - int read = 0, oob = 0, ecc_status = 0, ecc_failed = 0; - struct nand_chip *this = mtd->priv; - u_char *data_poi, *oob_data = oob_buf; - u_char ecc_calc[NAND_MAX_OOBSIZE]; - u_char ecc_code[NAND_MAX_OOBSIZE]; - int eccmode, eccsteps; - unsigned *oob_config; - int datidx; - int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; - int eccbytes; - int compareecc = 1; - int oobreadlen; + int chipnr, page, realpage, col, bytes, aligned; + struct nand_chip *chip = mtd->priv; + struct mtd_ecc_stats stats; + int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; + int sndcmd = 1; + int ret = 0; + uint32_t readlen = ops->len; + uint32_t oobreadlen = ops->ooblen; + uint8_t *bufpoi, *oob, *buf; + stats = mtd->ecc_stats; - MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", - (unsigned int) from, (int) len); + chipnr = (int)(from >> chip->chip_shift); + chip->select_chip(mtd, chipnr); - /* Do not allow reads past end of device */ - if ((from + len) > mtd->size) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_read_ecc: Attempt read beyond end of device\n"); - *retlen = 0; - return -EINVAL; - } + realpage = (int)(from >> chip->page_shift); + page = realpage & chip->pagemask; - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd ,FL_READING); + col = (int)(from & (mtd->writesize - 1)); - /* use userspace supplied oobinfo, if zero */ - if (oobsel == NULL) - oobsel = &mtd->oobinfo; + buf = ops->datbuf; + oob = ops->oobbuf; - /* Autoplace of oob data ? Use the default placement scheme */ - if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) - oobsel = this->autooob; + while(1) { + bytes = min(mtd->writesize - col, readlen); + aligned = (bytes == mtd->writesize); - eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; - oob_config = oobsel->eccpos; + /* Is the current page in the buffer ? */ + if (realpage != chip->pagebuf || oob) { + bufpoi = aligned ? buf : chip->buffers->databuf; - /* Select the NAND device */ - chipnr = (int)(from >> this->chip_shift); - this->select_chip(mtd, chipnr); + if (likely(sndcmd)) { + chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); + sndcmd = 0; + } - /* First we calculate the starting page */ - realpage = (int) (from >> this->page_shift); - page = realpage & this->pagemask; + /* Now read the page into the buffer */ + if (unlikely(ops->mode == MTD_OOB_RAW)) + ret = chip->ecc.read_page_raw(mtd, chip, bufpoi); + else + ret = chip->ecc.read_page(mtd, chip, bufpoi); + if (ret < 0) + break; - /* Get raw starting column */ - col = from & (mtd->oobblock - 1); + /* Transfer not aligned data */ + if (!aligned) { + chip->pagebuf = realpage; + memcpy(buf, chip->buffers->databuf + col, bytes); + } - end = mtd->oobblock; - ecc = this->eccsize; - eccbytes = this->eccbytes; + buf += bytes; + + if (unlikely(oob)) { + /* Raw mode does data:oob:data:oob */ + if (ops->mode != MTD_OOB_RAW) { + int toread = min(oobreadlen, + chip->ecc.layout->oobavail); + if (toread) { + oob = nand_transfer_oob(chip, + oob, ops, toread); + oobreadlen -= toread; + } + } else + buf = nand_transfer_oob(chip, + buf, ops, mtd->oobsize); + } - if ((eccmode == NAND_ECC_NONE) || (this->options & NAND_HWECC_SYNDROME)) - compareecc = 0; + if (!(chip->options & NAND_NO_READRDY)) { + /* + * Apply delay or wait for ready/busy pin. Do + * this before the AUTOINCR check, so no + * problems arise if a chip which does auto + * increment is marked as NOAUTOINCR by the + * board driver. + */ + if (!chip->dev_ready) + udelay(chip->chip_delay); + else + nand_wait_ready(mtd); + } + } else { + memcpy(buf, chip->buffers->databuf + col, bytes); + buf += bytes; + } - oobreadlen = mtd->oobsize; - if (this->options & NAND_HWECC_SYNDROME) - oobreadlen -= oobsel->eccbytes; + readlen -= bytes; - /* Loop until all data read */ - while (read < len) { + if (!readlen) + break; - int aligned = (!col && (len - read) >= end); - /* - * If the read is not page aligned, we have to read into data buffer - * due to ecc, else we read into return buffer direct - */ - if (aligned) - data_poi = &buf[read]; - else - data_poi = this->data_buf; + /* For subsequent reads align to page boundary. */ + col = 0; + /* Increment page address */ + realpage++; - /* Check, if we have this page in the buffer - * - * FIXME: Make it work when we must provide oob data too, - * check the usage of data_buf oob field - */ - if (realpage == this->pagebuf && !oob_buf) { - /* aligned read ? */ - if (aligned) - memcpy (data_poi, this->data_buf, end); - goto readdata; + page = realpage & chip->pagemask; + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + chip->select_chip(mtd, -1); + chip->select_chip(mtd, chipnr); } - /* Check, if we must send the read command */ - if (sndcmd) { - this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); - sndcmd = 0; - } + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ + if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck)) + sndcmd = 1; + } - /* get oob area, if we have no oob buffer from fs-driver */ - if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE || - oobsel->useecc == MTD_NANDECC_AUTOPL_USR) - oob_data = &this->data_buf[end]; + ops->retlen = ops->len - (size_t) readlen; + if (oob) + ops->oobretlen = ops->ooblen - oobreadlen; - eccsteps = this->eccsteps; + if (ret) + return ret; - switch (eccmode) { - case NAND_ECC_NONE: { /* No ECC, Read in a page */ -/* XXX U-BOOT XXX */ -#if 0 - static unsigned long lastwhinge = 0; - if ((lastwhinge / HZ) != (jiffies / HZ)) { - printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n"); - lastwhinge = jiffies; - } -#else - puts("Reading data from NAND FLASH without ECC is not recommended\n"); -#endif - this->read_buf(mtd, data_poi, end); - break; - } + if (mtd->ecc_stats.failed - stats.failed) + return -EBADMSG; - case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */ - this->read_buf(mtd, data_poi, end); - for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc) - this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); - break; + return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0; +} - default: - for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=eccbytes, datidx += ecc) { - this->enable_hwecc(mtd, NAND_ECC_READ); - this->read_buf(mtd, &data_poi[datidx], ecc); - - /* HW ecc with syndrome calculation must read the - * syndrome from flash immidiately after the data */ - if (!compareecc) { - /* Some hw ecc generators need to know when the - * syndrome is read from flash */ - this->enable_hwecc(mtd, NAND_ECC_READSYN); - this->read_buf(mtd, &oob_data[i], eccbytes); - /* We calc error correction directly, it checks the hw - * generator for an error, reads back the syndrome and - * does the error correction on the fly */ - if (this->correct_data(mtd, &data_poi[datidx], &oob_data[i], &ecc_code[i]) == -1) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " - "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr); - ecc_failed++; - } - } else { - this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]); - } - } - break; - } +/** + * nand_read - [MTD Interface] MTD compability function for nand_do_read_ecc + * @mtd: MTD device structure + * @from: offset to read from + * @len: number of bytes to read + * @retlen: pointer to variable to store the number of read bytes + * @buf: the databuffer to put data + * + * Get hold of the chip and call nand_do_read + */ +static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t *retlen, uint8_t *buf) +{ + struct nand_chip *chip = mtd->priv; + int ret; - /* read oobdata */ - this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen); + /* Do not allow reads past end of device */ + if ((from + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; - /* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */ - if (!compareecc) - goto readoob; + nand_get_device(chip, mtd, FL_READING); - /* Pick the ECC bytes out of the oob data */ - for (j = 0; j < oobsel->eccbytes; j++) - ecc_code[j] = oob_data[oob_config[j]]; + chip->ops.len = len; + chip->ops.datbuf = buf; + chip->ops.oobbuf = NULL; - /* correct data, if neccecary */ - for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) { - ecc_status = this->correct_data(mtd, &data_poi[datidx], &ecc_code[j], &ecc_calc[j]); + ret = nand_do_read_ops(mtd, from, &chip->ops); - /* Get next chunk of ecc bytes */ - j += eccbytes; + *retlen = chip->ops.retlen; - /* Check, if we have a fs supplied oob-buffer, - * This is the legacy mode. Used by YAFFS1 - * Should go away some day - */ - if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) { - int *p = (int *)(&oob_data[mtd->oobsize]); - p[i] = ecc_status; - } + nand_release_device(mtd); - if (ecc_status == -1) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " - "Failed ECC read, page 0x%08x\n", - page); - ecc_failed++; - } - } + return ret; +} - readoob: - /* check, if we have a fs supplied oob-buffer */ - if (oob_buf) { - /* without autoplace. Legacy mode used by YAFFS1 */ - switch(oobsel->useecc) { - case MTD_NANDECC_AUTOPLACE: - case MTD_NANDECC_AUTOPL_USR: - /* Walk through the autoplace chunks */ - for (i = 0, j = 0; j < mtd->oobavail; i++) { - int from = oobsel->oobfree[i][0]; - int num = oobsel->oobfree[i][1]; - memcpy(&oob_buf[oob+j], &oob_data[from], num); - j+= num; - } - oob += mtd->oobavail; - break; - case MTD_NANDECC_PLACE: - /* YAFFS1 legacy mode */ - oob_data += this->eccsteps * sizeof (int); - default: - oob_data += mtd->oobsize; - } - } - readdata: - /* Partial page read, transfer data into fs buffer */ - if (!aligned) { - for (j = col; j < end && read < len; j++) - buf[read++] = data_poi[j]; - this->pagebuf = realpage; +/** + * nand_read_oob_std - [REPLACABLE] the most common OOB data read function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @page: page number to read + * @sndcmd: flag whether to issue read command or not + */ +static int nand_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, + int page, int sndcmd) +{ + if (sndcmd) { + chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); + sndcmd = 0; + } + chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); + return sndcmd; +} + +/** + * nand_read_oob_syndrome - [REPLACABLE] OOB data read function for HW ECC + * with syndromes + * @mtd: mtd info structure + * @chip: nand chip info structure + * @page: page number to read + * @sndcmd: flag whether to issue read command or not + */ +static int nand_read_oob_syndrome(struct mtd_info *mtd, struct nand_chip *chip, + int page, int sndcmd) +{ + uint8_t *buf = chip->oob_poi; + int length = mtd->oobsize; + int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; + int eccsize = chip->ecc.size; + uint8_t *bufpoi = buf; + int i, toread, sndrnd = 0, pos; + + chip->cmdfunc(mtd, NAND_CMD_READ0, chip->ecc.size, page); + for (i = 0; i < chip->ecc.steps; i++) { + if (sndrnd) { + pos = eccsize + i * (eccsize + chunk); + if (mtd->writesize > 512) + chip->cmdfunc(mtd, NAND_CMD_RNDOUT, pos, -1); + else + chip->cmdfunc(mtd, NAND_CMD_READ0, pos, page); } else - read += mtd->oobblock; - - /* Apply delay or wait for ready/busy pin - * Do this before the AUTOINCR check, so no problems - * arise if a chip which does auto increment - * is marked as NOAUTOINCR by the board driver. - */ - if (!this->dev_ready) - udelay (this->chip_delay); - else - while (!this->dev_ready(mtd)); + sndrnd = 1; + toread = min_t(int, length, chunk); + chip->read_buf(mtd, bufpoi, toread); + bufpoi += toread; + length -= toread; + } + if (length > 0) + chip->read_buf(mtd, bufpoi, length); - if (read == len) - break; + return 1; +} - /* For subsequent reads align to page boundary. */ - col = 0; - /* Increment page address */ - realpage++; +/** + * nand_write_oob_std - [REPLACABLE] the most common OOB data write function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @page: page number to write + */ +static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + int status = 0; + const uint8_t *buf = chip->oob_poi; + int length = mtd->oobsize; - page = realpage & this->pagemask; - /* Check, if we cross a chip boundary */ - if (!page) { - chipnr++; - this->select_chip(mtd, -1); - this->select_chip(mtd, chipnr); - } - /* Check, if the chip supports auto page increment - * or if we have hit a block boundary. - */ - if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) - sndcmd = 1; - } + chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); + chip->write_buf(mtd, buf, length); + /* Send command to program the OOB data */ + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); - /* Deselect and wake up anyone waiting on the device */ - nand_release_device(mtd); + status = chip->waitfunc(mtd, chip); + + return status & NAND_STATUS_FAIL ? -EIO : 0; +} + +/** + * nand_write_oob_syndrome - [REPLACABLE] OOB data write function for HW ECC + * with syndrome - only for large page flash ! + * @mtd: mtd info structure + * @chip: nand chip info structure + * @page: page number to write + */ +static int nand_write_oob_syndrome(struct mtd_info *mtd, + struct nand_chip *chip, int page) +{ + int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; + int eccsize = chip->ecc.size, length = mtd->oobsize; + int i, len, pos, status = 0, sndcmd = 0, steps = chip->ecc.steps; + const uint8_t *bufpoi = chip->oob_poi; /* - * Return success, if no ECC failures, else -EBADMSG - * fs driver will take care of that, because - * retlen == desired len and result == -EBADMSG + * data-ecc-data-ecc ... ecc-oob + * or + * data-pad-ecc-pad-data-pad .... ecc-pad-oob */ - *retlen = read; - return ecc_failed ? -EBADMSG : 0; + if (!chip->ecc.prepad && !chip->ecc.postpad) { + pos = steps * (eccsize + chunk); + steps = 0; + } else + pos = eccsize; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); + for (i = 0; i < steps; i++) { + if (sndcmd) { + if (mtd->writesize <= 512) { + uint32_t fill = 0xFFFFFFFF; + + len = eccsize; + while (len > 0) { + int num = min_t(int, len, 4); + chip->write_buf(mtd, (uint8_t *)&fill, + num); + len -= num; + } + } else { + pos = eccsize + i * (eccsize + chunk); + chip->cmdfunc(mtd, NAND_CMD_RNDIN, pos, -1); + } + } else + sndcmd = 1; + len = min_t(int, length, chunk); + chip->write_buf(mtd, bufpoi, len); + bufpoi += len; + length -= len; + } + if (length > 0) + chip->write_buf(mtd, bufpoi, length); + + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + status = chip->waitfunc(mtd, chip); + + return status & NAND_STATUS_FAIL ? -EIO : 0; } /** - * nand_read_oob - [MTD Interface] NAND read out-of-band + * nand_do_read_oob - [Intern] NAND read out-of-band * @mtd: MTD device structure * @from: offset to read from - * @len: number of bytes to read - * @retlen: pointer to variable to store the number of read bytes - * @buf: the databuffer to put data + * @ops: oob operations description structure * * NAND read out-of-band data from the spare area */ -static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) +static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { - int i, col, page, chipnr; - struct nand_chip *this = mtd->priv; - int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; - - MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", - (unsigned int) from, (int) len); - - /* Shift to get page */ - page = (int)(from >> this->page_shift); - chipnr = (int)(from >> this->chip_shift); - - /* Mask to get column */ - col = from & (mtd->oobsize - 1); + int page, realpage, chipnr, sndcmd = 1; + struct nand_chip *chip = mtd->priv; + int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; + int readlen = ops->ooblen; + int len; + uint8_t *buf = ops->oobbuf; + + MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", + (unsigned long long)from, readlen); + + if (ops->mode == MTD_OOB_AUTO) + len = chip->ecc.layout->oobavail; + else + len = mtd->oobsize; - /* Initialize return length value */ - *retlen = 0; + if (unlikely(ops->ooboffs >= len)) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt to start read outside oob\n"); + return -EINVAL; + } /* Do not allow reads past end of device */ - if ((from + len) > mtd->size) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_read_oob: Attempt read beyond end of device\n"); - *retlen = 0; + if (unlikely(from >= mtd->size || + ops->ooboffs + readlen > ((mtd->size >> chip->page_shift) - + (from >> chip->page_shift)) * len)) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt read beyond end of device\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd , FL_READING); + chipnr = (int)(from >> chip->chip_shift); + chip->select_chip(mtd, chipnr); - /* Select the NAND device */ - this->select_chip(mtd, chipnr); + /* Shift to get page */ + realpage = (int)(from >> chip->page_shift); + page = realpage & chip->pagemask; - /* Send the read command */ - this->cmdfunc (mtd, NAND_CMD_READOOB, col, page & this->pagemask); - /* - * Read the data, if we read more than one page - * oob data, let the device transfer the data ! - */ - i = 0; - while (i < len) { - int thislen = mtd->oobsize - col; - thislen = min_t(int, thislen, len); - this->read_buf(mtd, &buf[i], thislen); - i += thislen; - - /* Apply delay or wait for ready/busy pin - * Do this before the AUTOINCR check, so no problems - * arise if a chip which does auto increment - * is marked as NOAUTOINCR by the board driver. - */ - if (!this->dev_ready) - udelay (this->chip_delay); - else - while (!this->dev_ready(mtd)); - - /* Read more ? */ - if (i < len) { - page++; - col = 0; - - /* Check, if we cross a chip boundary */ - if (!(page & this->pagemask)) { - chipnr++; - this->select_chip(mtd, -1); - this->select_chip(mtd, chipnr); - } + while(1) { + sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); - /* Check, if the chip supports auto page increment - * or if we have hit a block boundary. - */ - if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) { - /* For subsequent page reads set offset to 0 */ - this->cmdfunc (mtd, NAND_CMD_READOOB, 0x0, page & this->pagemask); - } + len = min(len, readlen); + buf = nand_transfer_oob(chip, buf, ops, len); + + if (!(chip->options & NAND_NO_READRDY)) { + /* + * Apply delay or wait for ready/busy pin. Do this + * before the AUTOINCR check, so no problems arise if a + * chip which does auto increment is marked as + * NOAUTOINCR by the board driver. + */ + if (!chip->dev_ready) + udelay(chip->chip_delay); + else + nand_wait_ready(mtd); } - } - /* Deselect and wake up anyone waiting on the device */ - nand_release_device(mtd); + readlen -= len; + if (!readlen) + break; + + /* Increment page address */ + realpage++; + + page = realpage & chip->pagemask; + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + chip->select_chip(mtd, -1); + chip->select_chip(mtd, chipnr); + } + + /* Check, if the chip supports auto page increment + * or if we have hit a block boundary. + */ + if (!NAND_CANAUTOINCR(chip) || !(page & blkcheck)) + sndcmd = 1; + } - /* Return happy */ - *retlen = len; + ops->oobretlen = ops->ooblen; return 0; } /** - * nand_read_raw - [GENERIC] Read raw data including oob into buffer + * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band * @mtd: MTD device structure - * @buf: temporary buffer * @from: offset to read from - * @len: number of bytes to read - * @ooblen: number of oob data bytes to read + * @ops: oob operation description structure * - * Read raw data including oob into buffer + * NAND read data and/or out-of-band data */ -int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen) +static int nand_read_oob(struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops) { - struct nand_chip *this = mtd->priv; - int page = (int) (from >> this->page_shift); - int chip = (int) (from >> this->chip_shift); - int sndcmd = 1; - int cnt = 0; - int pagesize = mtd->oobblock + mtd->oobsize; - int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1; + struct nand_chip *chip = mtd->priv; + int ret = -ENOTSUPP; + + ops->retlen = 0; /* Do not allow reads past end of device */ - if ((from + len) > mtd->size) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_read_raw: Attempt read beyond end of device\n"); + if (ops->datbuf && (from + ops->len) > mtd->size) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt read beyond end of device\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd , FL_READING); + nand_get_device(chip, mtd, FL_READING); - this->select_chip (mtd, chip); + switch(ops->mode) { + case MTD_OOB_PLACE: + case MTD_OOB_AUTO: + case MTD_OOB_RAW: + break; - /* Add requested oob length */ - len += ooblen; + default: + goto out; + } - while (len) { - if (sndcmd) - this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask); - sndcmd = 0; + if (!ops->datbuf) + ret = nand_do_read_oob(mtd, from, ops); + else + ret = nand_do_read_ops(mtd, from, ops); - this->read_buf (mtd, &buf[cnt], pagesize); + out: + nand_release_device(mtd); + return ret; +} - len -= pagesize; - cnt += pagesize; - page++; - if (!this->dev_ready) - udelay (this->chip_delay); - else - while (!this->dev_ready(mtd)); +/** + * nand_write_page_raw - [Intern] raw page write function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: data buffer + */ +static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf) +{ + chip->write_buf(mtd, buf, mtd->writesize); + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); +} - /* Check, if the chip supports auto page increment */ - if (!NAND_CANAUTOINCR(this) || !(page & blockcheck)) - sndcmd = 1; - } +/** + * nand_write_page_swecc - [REPLACABLE] software ecc based page write function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: data buffer + */ +static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *ecc_calc = chip->buffers->ecccalc; + const uint8_t *p = buf; + uint32_t *eccpos = chip->ecc.layout->eccpos; - /* Deselect and wake up anyone waiting on the device */ - nand_release_device(mtd); - return 0; + /* Software ecc calculation */ + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + + for (i = 0; i < chip->ecc.total; i++) + chip->oob_poi[eccpos[i]] = ecc_calc[i]; + + chip->ecc.write_page_raw(mtd, chip, buf); } +/** + * nand_write_page_hwecc - [REPLACABLE] hardware ecc based page write function + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: data buffer + */ +static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf) +{ + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + uint8_t *ecc_calc = chip->buffers->ecccalc; + const uint8_t *p = buf; + uint32_t *eccpos = chip->ecc.layout->eccpos; + + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { + chip->ecc.hwctl(mtd, NAND_ECC_WRITE); + chip->write_buf(mtd, p, eccsize); + chip->ecc.calculate(mtd, p, &ecc_calc[i]); + } + + for (i = 0; i < chip->ecc.total; i++) + chip->oob_poi[eccpos[i]] = ecc_calc[i]; + + chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); +} /** - * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer - * @mtd: MTD device structure - * @fsbuf: buffer given by fs driver - * @oobsel: out of band selection structre - * @autoplace: 1 = place given buffer into the oob bytes - * @numpages: number of pages to prepare - * - * Return: - * 1. Filesystem buffer available and autoplacement is off, - * return filesystem buffer - * 2. No filesystem buffer or autoplace is off, return internal - * buffer - * 3. Filesystem buffer is given and autoplace selected - * put data from fs buffer into internal buffer and - * retrun internal buffer - * - * Note: The internal buffer is filled with 0xff. This must - * be done only once, when no autoplacement happens - * Autoplacement sets the buffer dirty flag, which - * forces the 0xff fill before using the buffer again. + * nand_write_page_syndrome - [REPLACABLE] hardware ecc syndrom based page write + * @mtd: mtd info structure + * @chip: nand chip info structure + * @buf: data buffer * -*/ -static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel, - int autoplace, int numpages) + * The hw generator calculates the error syndrome automatically. Therefor + * we need a special oob layout and handling. + */ +static void nand_write_page_syndrome(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf) { - struct nand_chip *this = mtd->priv; - int i, len, ofs; + int i, eccsize = chip->ecc.size; + int eccbytes = chip->ecc.bytes; + int eccsteps = chip->ecc.steps; + const uint8_t *p = buf; + uint8_t *oob = chip->oob_poi; - /* Zero copy fs supplied buffer */ - if (fsbuf && !autoplace) - return fsbuf; + for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - /* Check, if the buffer must be filled with ff again */ - if (this->oobdirty) { - memset (this->oob_buf, 0xff, - mtd->oobsize << (this->phys_erase_shift - this->page_shift)); - this->oobdirty = 0; - } + chip->ecc.hwctl(mtd, NAND_ECC_WRITE); + chip->write_buf(mtd, p, eccsize); - /* If we have no autoplacement or no fs buffer use the internal one */ - if (!autoplace || !fsbuf) - return this->oob_buf; - - /* Walk through the pages and place the data */ - this->oobdirty = 1; - ofs = 0; - while (numpages--) { - for (i = 0, len = 0; len < mtd->oobavail; i++) { - int to = ofs + oobsel->oobfree[i][0]; - int num = oobsel->oobfree[i][1]; - memcpy (&this->oob_buf[to], fsbuf, num); - len += num; - fsbuf += num; + if (chip->ecc.prepad) { + chip->write_buf(mtd, oob, chip->ecc.prepad); + oob += chip->ecc.prepad; + } + + chip->ecc.calculate(mtd, p, oob); + chip->write_buf(mtd, oob, eccbytes); + oob += eccbytes; + + if (chip->ecc.postpad) { + chip->write_buf(mtd, oob, chip->ecc.postpad); + oob += chip->ecc.postpad; } - ofs += mtd->oobavail; } - return this->oob_buf; -} -#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0 + /* Calculate remaining oob bytes */ + i = mtd->oobsize - (oob - chip->oob_poi); + if (i) + chip->write_buf(mtd, oob, i); +} /** - * nand_write - [MTD Interface] compability function for nand_write_ecc + * nand_write_page - [REPLACEABLE] write one page * @mtd: MTD device structure - * @to: offset to write to - * @len: number of bytes to write - * @retlen: pointer to variable to store the number of written bytes + * @chip: NAND chip descriptor * @buf: the data to write - * - * This function simply calls nand_write_ecc with oob buffer and oobsel = NULL - * -*/ -static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) + * @page: page number to write + * @cached: cached programming + * @raw: use _raw version of write_page + */ +static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf, int page, int cached, int raw) { - return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); + int status; + + chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); + + if (unlikely(raw)) + chip->ecc.write_page_raw(mtd, chip, buf); + else + chip->ecc.write_page(mtd, chip, buf); + + /* + * Cached progamming disabled for now, Not sure if its worth the + * trouble. The speed gain is not very impressive. (2.3->2.6Mib/s) + */ + cached = 0; + + if (!cached || !(chip->options & NAND_CACHEPRG)) { + + chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); + status = chip->waitfunc(mtd, chip); + /* + * See if operation failed and additional status checks are + * available + */ + if ((status & NAND_STATUS_FAIL) && (chip->errstat)) + status = chip->errstat(mtd, chip, FL_WRITING, status, + page); + + if (status & NAND_STATUS_FAIL) + return -EIO; + } else { + chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1); + status = chip->waitfunc(mtd, chip); + } + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + /* Send command to read back the data */ + chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); + + if (chip->verify_buf(mtd, buf, mtd->writesize)) + return -EIO; +#endif + return 0; +} + +/** + * nand_fill_oob - [Internal] Transfer client buffer to oob + * @chip: nand chip structure + * @oob: oob data buffer + * @ops: oob ops structure + */ +static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, + struct mtd_oob_ops *ops) +{ + size_t len = ops->ooblen; + + switch(ops->mode) { + + case MTD_OOB_PLACE: + case MTD_OOB_RAW: + memcpy(chip->oob_poi + ops->ooboffs, oob, len); + return oob + len; + + case MTD_OOB_AUTO: { + struct nand_oobfree *free = chip->ecc.layout->oobfree; + uint32_t boffs = 0, woffs = ops->ooboffs; + size_t bytes = 0; + + for(; free->length && len; free++, len -= bytes) { + /* Write request not from offset 0 ? */ + if (unlikely(woffs)) { + if (woffs >= free->length) { + woffs -= free->length; + continue; + } + boffs = free->offset + woffs; + bytes = min_t(size_t, len, + (free->length - woffs)); + woffs = 0; + } else { + bytes = min_t(size_t, len, free->length); + boffs = free->offset; + } + memcpy(chip->oob_poi + boffs, oob, bytes); + oob += bytes; + } + return oob; + } + default: + BUG(); + } + return NULL; } +#define NOTALIGNED(x) (x & (chip->subpagesize - 1)) != 0 + /** - * nand_write_ecc - [MTD Interface] NAND write with ECC + * nand_do_write_ops - [Internal] NAND write with ECC * @mtd: MTD device structure * @to: offset to write to - * @len: number of bytes to write - * @retlen: pointer to variable to store the number of written bytes - * @buf: the data to write - * @eccbuf: filesystem supplied oob data buffer - * @oobsel: oob selection structure + * @ops: oob operations description structure * * NAND write with ECC */ -static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, - size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel) +static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) { - int startpage, page, ret = -EIO, oob = 0, written = 0, chipnr; - int autoplace = 0, numpages, totalpages; - struct nand_chip *this = mtd->priv; - u_char *oobbuf, *bufstart; - int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); - - MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", - (unsigned int) to, (int) len); - - /* Initialize retlen, in case of early exit */ - *retlen = 0; + int chipnr, realpage, page, blockmask, column; + struct nand_chip *chip = mtd->priv; + uint32_t writelen = ops->len; + uint8_t *oob = ops->oobbuf; + uint8_t *buf = ops->datbuf; + int ret, subpage; - /* Do not allow write past end of device */ - if ((to + len) > mtd->size) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_write_ecc: Attempt to write past end of page\n"); - return -EINVAL; - } + ops->retlen = 0; + if (!writelen) + return 0; /* reject writes, which are not page aligned */ - if (NOTALIGNED (to) || NOTALIGNED(len)) { - printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); + if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { + printk(KERN_NOTICE "nand_write: " + "Attempt to write not page aligned data\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_WRITING); + column = to & (mtd->writesize - 1); + subpage = column || (writelen & (mtd->writesize - 1)); - /* Calculate chipnr */ - chipnr = (int)(to >> this->chip_shift); - /* Select the NAND device */ - this->select_chip(mtd, chipnr); + if (subpage && oob) + return -EINVAL; + + chipnr = (int)(to >> chip->chip_shift); + chip->select_chip(mtd, chipnr); /* Check, if it is write protected */ if (nand_check_wp(mtd)) { - printk (KERN_NOTICE "nand_write_ecc: Device is write protected\n"); - goto out; + printk (KERN_NOTICE "nand_do_write_ops: Device is write protected\n"); + return -EIO; } - /* if oobsel is NULL, use chip defaults */ - if (oobsel == NULL) - oobsel = &mtd->oobinfo; + realpage = (int)(to >> chip->page_shift); + page = realpage & chip->pagemask; + blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; + + /* Invalidate the page cache, when we write to the cached page */ + if (to <= (chip->pagebuf << chip->page_shift) && + (chip->pagebuf << chip->page_shift) < (to + ops->len)) + chip->pagebuf = -1; + + /* If we're not given explicit OOB data, let it be 0xFF */ + if (likely(!oob)) + memset(chip->oob_poi, 0xff, mtd->oobsize); + + while(1) { + int bytes = mtd->writesize; + int cached = writelen > bytes && page != blockmask; + uint8_t *wbuf = buf; + + /* Partial page write ? */ + if (unlikely(column || writelen < (mtd->writesize - 1))) { + cached = 0; + bytes = min_t(int, bytes - column, (int) writelen); + chip->pagebuf = -1; + memset(chip->buffers->databuf, 0xff, mtd->writesize); + memcpy(&chip->buffers->databuf[column], buf, bytes); + wbuf = chip->buffers->databuf; + } - /* Autoplace of oob data ? Use the default placement scheme */ - if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { - oobsel = this->autooob; - autoplace = 1; - } - if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) - autoplace = 1; + if (unlikely(oob)) + oob = nand_fill_oob(chip, oob, ops); - /* Setup variables and oob buffer */ - totalpages = len >> this->page_shift; - page = (int) (to >> this->page_shift); - /* Invalidate the page cache, if we write to the cached page */ - if (page <= this->pagebuf && this->pagebuf < (page + totalpages)) - this->pagebuf = -1; - - /* Set it relative to chip */ - page &= this->pagemask; - startpage = page; - /* Calc number of pages we can write in one go */ - numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages); - oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages); - bufstart = (u_char *)buf; - - /* Loop until all data is written */ - while (written < len) { - - this->data_poi = (u_char*) &buf[written]; - /* Write one page. If this is the last page to write - * or the last page in this block, then use the - * real pageprogram command, else select cached programming - * if supported by the chip. - */ - ret = nand_write_page (mtd, this, page, &oobbuf[oob], oobsel, (--numpages > 0)); - if (ret) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_write_ecc: write_page failed %d\n", ret); - goto out; - } - /* Next oob page */ - oob += mtd->oobsize; - /* Update written bytes count */ - written += mtd->oobblock; - if (written == len) - goto cmp; + ret = chip->write_page(mtd, chip, wbuf, page, cached, + (ops->mode == MTD_OOB_RAW)); + if (ret) + break; - /* Increment page address */ - page++; - - /* Have we hit a block boundary ? Then we have to verify and - * if verify is ok, we have to setup the oob buffer for - * the next pages. - */ - if (!(page & (ppblock - 1))){ - int ofs; - this->data_poi = bufstart; - ret = nand_verify_pages (mtd, this, startpage, - page - startpage, - oobbuf, oobsel, chipnr, (eccbuf != NULL)); - if (ret) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: " - "verify_pages failed %d\n", ret); - goto out; - } - *retlen = written; - bufstart = (u_char*) &buf[written]; - - ofs = autoplace ? mtd->oobavail : mtd->oobsize; - if (eccbuf) - eccbuf += (page - startpage) * ofs; - totalpages -= page - startpage; - numpages = min (totalpages, ppblock); - page &= this->pagemask; - startpage = page; - oob = 0; - this->oobdirty = 1; - oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, - autoplace, numpages); - /* Check, if we cross a chip boundary */ - if (!page) { - chipnr++; - this->select_chip(mtd, -1); - this->select_chip(mtd, chipnr); - } + writelen -= bytes; + if (!writelen) + break; + + column = 0; + buf += bytes; + realpage++; + + page = realpage & chip->pagemask; + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + chip->select_chip(mtd, -1); + chip->select_chip(mtd, chipnr); } } - /* Verify the remaining pages */ -cmp: - this->data_poi = bufstart; - ret = nand_verify_pages (mtd, this, startpage, totalpages, - oobbuf, oobsel, chipnr, (eccbuf != NULL)); - if (!ret) - *retlen = written; - else - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_write_ecc: verify_pages failed %d\n", ret); - -out: - /* Deselect and wake up anyone waiting on the device */ - nand_release_device(mtd); + ops->retlen = ops->len - writelen; + if (unlikely(oob)) + ops->oobretlen = ops->ooblen; return ret; } - /** - * nand_write_oob - [MTD Interface] NAND write out-of-band + * nand_write - [MTD Interface] NAND write with ECC * @mtd: MTD device structure * @to: offset to write to * @len: number of bytes to write * @retlen: pointer to variable to store the number of written bytes * @buf: the data to write * - * NAND write out-of-band + * NAND write with ECC */ -static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) +static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t *retlen, const uint8_t *buf) { - int column, page, status, ret = -EIO, chipnr; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; + int ret; - MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", - (unsigned int) to, (int) len); + /* Do not allow reads past end of device */ + if ((to + len) > mtd->size) + return -EINVAL; + if (!len) + return 0; - /* Shift to get page */ - page = (int) (to >> this->page_shift); - chipnr = (int) (to >> this->chip_shift); + nand_get_device(chip, mtd, FL_WRITING); + + chip->ops.len = len; + chip->ops.datbuf = (uint8_t *)buf; + chip->ops.oobbuf = NULL; - /* Mask to get column */ - column = to & (mtd->oobsize - 1); + ret = nand_do_write_ops(mtd, to, &chip->ops); - /* Initialize return length value */ - *retlen = 0; + *retlen = chip->ops.retlen; + + nand_release_device(mtd); + + return ret; +} + +/** + * nand_do_write_oob - [MTD Interface] NAND write out-of-band + * @mtd: MTD device structure + * @to: offset to write to + * @ops: oob operation description structure + * + * NAND write out-of-band + */ +static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) +{ + int chipnr, page, status, len; + struct nand_chip *chip = mtd->priv; + + MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", + (unsigned int)to, (int)ops->ooblen); + + if (ops->mode == MTD_OOB_AUTO) + len = chip->ecc.layout->oobavail; + else + len = mtd->oobsize; /* Do not allow write past end of page */ - if ((column + len) > mtd->oobsize) { + if ((ops->ooboffs + ops->ooblen) > len) { MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Attempt to write past end of page\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_WRITING); + if (unlikely(ops->ooboffs >= len)) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt to start write outside oob\n"); + return -EINVAL; + } - /* Select the NAND device */ - this->select_chip(mtd, chipnr); + /* Do not allow reads past end of device */ + if (unlikely(to >= mtd->size || + ops->ooboffs + ops->ooblen > + ((mtd->size >> chip->page_shift) - + (to >> chip->page_shift)) * len)) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt write beyond end of device\n"); + return -EINVAL; + } + + chipnr = (int)(to >> chip->chip_shift); + chip->select_chip(mtd, chipnr); - /* Reset the chip. Some chips (like the Toshiba TC5832DC found - in one of my DiskOnChip 2000 test units) will clear the whole - data page too if we don't do this. I have no clue why, but - I seem to have 'fixed' it in the doc2000 driver in - August 1999. dwmw2. */ - this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* Shift to get page */ + page = (int)(to >> chip->page_shift); + + /* + * Reset the chip. Some chips (like the Toshiba TC5832DC found in one + * of my DiskOnChip 2000 test units) will clear the whole data page too + * if we don't do this. I have no clue why, but I seem to have 'fixed' + * it in the doc2000 driver in August 1999. dwmw2. + */ + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* Check, if it is write protected */ if (nand_check_wp(mtd)) - goto out; + return -EROFS; /* Invalidate the page cache, if we write to the cached page */ - if (page == this->pagebuf) - this->pagebuf = -1; - - if (NAND_MUST_PAD(this)) { - /* Write out desired data */ - this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask); - if (!ffchars) { - if (!(ffchars = kmalloc (mtd->oobsize, GFP_KERNEL))) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " - "No memory for padding array, " - "need %d bytes", mtd->oobsize); - ret = -ENOMEM; - goto out; - } - memset(ffchars, 0xff, mtd->oobsize); - } - /* prepad 0xff for partial programming */ - this->write_buf(mtd, ffchars, column); - /* write data */ - this->write_buf(mtd, buf, len); - /* postpad 0xff for partial programming */ - this->write_buf(mtd, ffchars, mtd->oobsize - (len+column)); - } else { - /* Write out desired data */ - this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock + column, page & this->pagemask); - /* write data */ - this->write_buf(mtd, buf, len); - } - /* Send command to program the OOB data */ - this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); - - status = this->waitfunc (mtd, this, FL_WRITING); - - /* See if device thinks it succeeded */ - if (status & 0x01) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " - "Failed write, page 0x%08x\n", page); - ret = -EIO; - goto out; - } - /* Return happy */ - *retlen = len; + if (page == chip->pagebuf) + chip->pagebuf = -1; -#ifdef CONFIG_MTD_NAND_VERIFY_WRITE - /* Send command to read back the data */ - this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask); + memset(chip->oob_poi, 0xff, mtd->oobsize); + nand_fill_oob(chip, ops->oobbuf, ops); + status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); + memset(chip->oob_poi, 0xff, mtd->oobsize); - if (this->verify_buf(mtd, buf, len)) { - MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " - "Failed write verify, page 0x%08x\n", page); - ret = -EIO; - goto out; - } -#endif - ret = 0; -out: - /* Deselect and wake up anyone waiting on the device */ - nand_release_device(mtd); + if (status) + return status; - return ret; -} + ops->oobretlen = ops->ooblen; -/* XXX U-BOOT XXX */ -#if 0 -/** - * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc - * @mtd: MTD device structure - * @vecs: the iovectors to write - * @count: number of vectors - * @to: offset to write to - * @retlen: pointer to variable to store the number of written bytes - * - * NAND write with kvec. This just calls the ecc function - */ -static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, - loff_t to, size_t * retlen) -{ - return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, NULL)); + return 0; } /** - * nand_writev_ecc - [MTD Interface] write with iovec with ecc + * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band * @mtd: MTD device structure - * @vecs: the iovectors to write - * @count: number of vectors * @to: offset to write to - * @retlen: pointer to variable to store the number of written bytes - * @eccbuf: filesystem supplied oob data buffer - * @oobsel: oob selection structure - * - * NAND write with iovec with ecc + * @ops: oob operation description structure */ -static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, - loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) +static int nand_write_oob(struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops) { - int i, page, len, total_len, ret = -EIO, written = 0, chipnr; - int oob, numpages, autoplace = 0, startpage; - struct nand_chip *this = mtd->priv; - int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); - u_char *oobbuf, *bufstart; - - /* Preset written len for early exit */ - *retlen = 0; + struct nand_chip *chip = mtd->priv; + int ret = -ENOTSUPP; - /* Calculate total length of data */ - total_len = 0; - for (i = 0; i < count; i++) - total_len += (int) vecs[i].iov_len; - - MTDDEBUG (MTD_DEBUG_LEVEL3, - "nand_writev: to = 0x%08x, len = %i, count = %ld\n", - (unsigned int) to, (unsigned int) total_len, count); - - /* Do not allow write past end of page */ - if ((to + total_len) > mtd->size) { - MTDDEBUG (MTD_DEBUG_LEVEL0, - "nand_writev: Attempted write past end of device\n"); - return -EINVAL; - } + ops->retlen = 0; - /* reject writes, which are not page aligned */ - if (NOTALIGNED (to) || NOTALIGNED(total_len)) { - printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); + /* Do not allow writes past end of device */ + if (ops->datbuf && (to + ops->len) > mtd->size) { + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: " + "Attempt read beyond end of device\n"); return -EINVAL; } - /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_WRITING); + nand_get_device(chip, mtd, FL_WRITING); - /* Get the current chip-nr */ - chipnr = (int) (to >> this->chip_shift); - /* Select the NAND device */ - this->select_chip(mtd, chipnr); + switch(ops->mode) { + case MTD_OOB_PLACE: + case MTD_OOB_AUTO: + case MTD_OOB_RAW: + break; - /* Check, if it is write protected */ - if (nand_check_wp(mtd)) + default: goto out; - - /* if oobsel is NULL, use chip defaults */ - if (oobsel == NULL) - oobsel = &mtd->oobinfo; - - /* Autoplace of oob data ? Use the default placement scheme */ - if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { - oobsel = this->autooob; - autoplace = 1; } - if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) - autoplace = 1; - - /* Setup start page */ - page = (int) (to >> this->page_shift); - /* Invalidate the page cache, if we write to the cached page */ - if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) - this->pagebuf = -1; - - startpage = page & this->pagemask; - - /* Loop until all kvec' data has been written */ - len = 0; - while (count) { - /* If the given tuple is >= pagesize then - * write it out from the iov - */ - if ((vecs->iov_len - len) >= mtd->oobblock) { - /* Calc number of pages we can write - * out of this iov in one go */ - numpages = (vecs->iov_len - len) >> this->page_shift; - /* Do not cross block boundaries */ - numpages = min (ppblock - (startpage & (ppblock - 1)), numpages); - oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); - bufstart = (u_char *)vecs->iov_base; - bufstart += len; - this->data_poi = bufstart; - oob = 0; - for (i = 1; i <= numpages; i++) { - /* Write one page. If this is the last page to write - * then use the real pageprogram command, else select - * cached programming if supported by the chip. - */ - ret = nand_write_page (mtd, this, page & this->pagemask, - &oobbuf[oob], oobsel, i != numpages); - if (ret) - goto out; - this->data_poi += mtd->oobblock; - len += mtd->oobblock; - oob += mtd->oobsize; - page++; - } - /* Check, if we have to switch to the next tuple */ - if (len >= (int) vecs->iov_len) { - vecs++; - len = 0; - count--; - } - } else { - /* We must use the internal buffer, read data out of each - * tuple until we have a full page to write - */ - int cnt = 0; - while (cnt < mtd->oobblock) { - if (vecs->iov_base != NULL && vecs->iov_len) - this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++]; - /* Check, if we have to switch to the next tuple */ - if (len >= (int) vecs->iov_len) { - vecs++; - len = 0; - count--; - } - } - this->pagebuf = page; - this->data_poi = this->data_buf; - bufstart = this->data_poi; - numpages = 1; - oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages); - ret = nand_write_page (mtd, this, page & this->pagemask, - oobbuf, oobsel, 0); - if (ret) - goto out; - page++; - } - this->data_poi = bufstart; - ret = nand_verify_pages (mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); - if (ret) - goto out; - - written += mtd->oobblock * numpages; - /* All done ? */ - if (!count) - break; + if (!ops->datbuf) + ret = nand_do_write_oob(mtd, to, ops); + else + ret = nand_do_write_ops(mtd, to, ops); - startpage = page & this->pagemask; - /* Check, if we cross a chip boundary */ - if (!startpage) { - chipnr++; - this->select_chip(mtd, -1); - this->select_chip(mtd, chipnr); - } - } - ret = 0; -out: - /* Deselect and wake up anyone waiting on the device */ + out: nand_release_device(mtd); - - *retlen = written; return ret; } -#endif /** * single_erease_cmd - [GENERIC] NAND standard block erase command function @@ -2094,12 +1990,12 @@ out: * * Standard erase command for NAND chips */ -static void single_erase_cmd (struct mtd_info *mtd, int page) +static void single_erase_cmd(struct mtd_info *mtd, int page) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; /* Send commands to erase a block */ - this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); - this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); + chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); } /** @@ -2110,15 +2006,15 @@ static void single_erase_cmd (struct mtd_info *mtd, int page) * AND multi block erase command function * Erase 4 consecutive blocks */ -static void multi_erase_cmd (struct mtd_info *mtd, int page) +static void multi_erase_cmd(struct mtd_info *mtd, int page) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; /* Send commands to erase a block */ - this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); - this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); - this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page++); - this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); - this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); + chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); + chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); } /** @@ -2128,35 +2024,39 @@ static void multi_erase_cmd (struct mtd_info *mtd, int page) * * Erase one ore more blocks */ -static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) +static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) { - return nand_erase_nand (mtd, instr, 0); + return nand_erase_nand(mtd, instr, 0); } +#define BBT_PAGE_MASK 0xffffff3f /** - * nand_erase_intern - [NAND Interface] erase block(s) + * nand_erase_nand - [Internal] erase block(s) * @mtd: MTD device structure * @instr: erase instruction * @allowbbt: allow erasing the bbt area * * Erase one ore more blocks */ -int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt) +int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, + int allowbbt) { int page, len, status, pages_per_block, ret, chipnr; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; + int rewrite_bbt[NAND_MAX_CHIPS]={0}; + unsigned int bbt_masked_page = 0xffffffff; MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_erase: start = 0x%08x, len = %i\n", (unsigned int) instr->addr, (unsigned int) instr->len); /* Start address must align on block boundary */ - if (instr->addr & ((1 << this->phys_erase_shift) - 1)) { + if (instr->addr & ((1 << chip->phys_erase_shift) - 1)) { MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); return -EINVAL; } /* Length must align on block boundary */ - if (instr->len & ((1 << this->phys_erase_shift) - 1)) { + if (instr->len & ((1 << chip->phys_erase_shift) - 1)) { MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n"); return -EINVAL; @@ -2172,19 +2072,18 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb instr->fail_addr = 0xffffffff; /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_ERASING); + nand_get_device(chip, mtd, FL_ERASING); /* Shift to get first page */ - page = (int) (instr->addr >> this->page_shift); - chipnr = (int) (instr->addr >> this->chip_shift); + page = (int)(instr->addr >> chip->page_shift); + chipnr = (int)(instr->addr >> chip->chip_shift); /* Calculate pages in each block */ - pages_per_block = 1 << (this->phys_erase_shift - this->page_shift); - + pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift); + /* Select the NAND device */ - this->select_chip(mtd, chipnr); + chip->select_chip(mtd, chipnr); - /* Check the WP bit */ /* Check, if it is write protected */ if (nand_check_wp(mtd)) { MTDDEBUG (MTD_DEBUG_LEVEL0, @@ -2193,52 +2092,92 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb goto erase_exit; } + /* + * If BBT requires refresh, set the BBT page mask to see if the BBT + * should be rewritten. Otherwise the mask is set to 0xffffffff which + * can not be matched. This is also done when the bbt is actually + * erased to avoid recusrsive updates + */ + if (chip->options & BBT_AUTO_REFRESH && !allowbbt) + bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK; + /* Loop through the pages */ len = instr->len; instr->state = MTD_ERASING; while (len) { -#ifndef NAND_ALLOW_ERASE_ALL - /* Check if we have a bad block, we do not erase bad blocks ! */ - if (nand_block_checkbad(mtd, ((loff_t) page) << this->page_shift, 0, allowbbt)) { - printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page); + /* + * heck if we have a bad block, we do not erase bad blocks ! + */ + if (nand_block_checkbad(mtd, ((loff_t) page) << + chip->page_shift, 0, allowbbt)) { + printk(KERN_WARNING "nand_erase: attempt to erase a " + "bad block at page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; goto erase_exit; } -#endif - /* Invalidate the page cache, if we erase the block which contains - the current cached page */ - if (page <= this->pagebuf && this->pagebuf < (page + pages_per_block)) - this->pagebuf = -1; - this->erase_cmd (mtd, page & this->pagemask); + /* + * Invalidate the page cache, if we erase the block which + * contains the current cached page + */ + if (page <= chip->pagebuf && chip->pagebuf < + (page + pages_per_block)) + chip->pagebuf = -1; + + chip->erase_cmd(mtd, page & chip->pagemask); + + status = chip->waitfunc(mtd, chip); - status = this->waitfunc (mtd, this, FL_ERASING); + /* + * See if operation failed and additional status checks are + * available + */ + if ((status & NAND_STATUS_FAIL) && (chip->errstat)) + status = chip->errstat(mtd, chip, FL_ERASING, + status, page); /* See if block erase succeeded */ - if (status & 0x01) { + if (status & NAND_STATUS_FAIL) { MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x\n", page); instr->state = MTD_ERASE_FAILED; - instr->fail_addr = (page << this->page_shift); + instr->fail_addr = (page << chip->page_shift); goto erase_exit; } + /* + * If BBT requires refresh, set the BBT rewrite flag to the + * page being erased + */ + if (bbt_masked_page != 0xffffffff && + (page & BBT_PAGE_MASK) == bbt_masked_page) + rewrite_bbt[chipnr] = (page << chip->page_shift); + /* Increment page address and decrement length */ - len -= (1 << this->phys_erase_shift); + len -= (1 << chip->phys_erase_shift); page += pages_per_block; /* Check, if we cross a chip boundary */ - if (len && !(page & this->pagemask)) { + if (len && !(page & chip->pagemask)) { chipnr++; - this->select_chip(mtd, -1); - this->select_chip(mtd, chipnr); + chip->select_chip(mtd, -1); + chip->select_chip(mtd, chipnr); + + /* + * If BBT requires refresh and BBT-PERCHIP, set the BBT + * page mask to see if this BBT should be rewritten + */ + if (bbt_masked_page != 0xffffffff && + (chip->bbt_td->options & NAND_BBT_PERCHIP)) + bbt_masked_page = chip->bbt_td->pages[chipnr] & + BBT_PAGE_MASK; } } instr->state = MTD_ERASE_DONE; -erase_exit: + erase_exit: ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; /* Do call back function */ @@ -2248,6 +2187,23 @@ erase_exit: /* Deselect and wake up anyone waiting on the device */ nand_release_device(mtd); + /* + * If BBT requires refresh and erase was successful, rewrite any + * selected bad block tables + */ + if (bbt_masked_page == 0xffffffff || ret) + return ret; + + for (chipnr = 0; chipnr < chip->numchips; chipnr++) { + if (!rewrite_bbt[chipnr]) + continue; + /* update the BBT for chip */ + MTDDEBUG (MTD_DEBUG_LEVEL0, "nand_erase_nand: nand_update_bbt " + "(%d:0x%0x 0x%0x)\n", chipnr, rewrite_bbt[chipnr], + chip->bbt_td->pages[chipnr]); + nand_update_bbt(mtd, rewrite_bbt[chipnr]); + } + /* Return more or less happy */ return ret; } @@ -2258,41 +2214,40 @@ erase_exit: * * Sync is actually a wait for chip ready function */ -static void nand_sync (struct mtd_info *mtd) +static void nand_sync(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; MTDDEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n"); /* Grab the lock and see if the device is available */ - nand_get_device (this, mtd, FL_SYNCING); + nand_get_device(chip, mtd, FL_SYNCING); /* Release it and go back */ - nand_release_device (mtd); + nand_release_device(mtd); } - /** - * nand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad + * nand_block_isbad - [MTD Interface] Check if block at offset is bad * @mtd: MTD device structure - * @ofs: offset relative to mtd start + * @offs: offset relative to mtd start */ -static int nand_block_isbad (struct mtd_info *mtd, loff_t ofs) +static int nand_block_isbad(struct mtd_info *mtd, loff_t offs) { /* Check for invalid offset */ - if (ofs > mtd->size) + if (offs > mtd->size) return -EINVAL; - return nand_block_checkbad (mtd, ofs, 1, 0); + return nand_block_checkbad(mtd, offs, 1, 0); } /** - * nand_block_markbad - [MTD Interface] Mark the block at the given offset as bad + * nand_block_markbad - [MTD Interface] Mark block at the given offset as bad * @mtd: MTD device structure * @ofs: offset relative to mtd start */ -static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) +static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; int ret; if ((ret = nand_block_isbad(mtd, ofs))) { @@ -2302,419 +2257,553 @@ static int nand_block_markbad (struct mtd_info *mtd, loff_t ofs) return ret; } - return this->block_markbad(mtd, ofs); + return chip->block_markbad(mtd, ofs); } /** - * nand_scan - [NAND Interface] Scan for the NAND device + * nand_suspend - [MTD Interface] Suspend the NAND flash * @mtd: MTD device structure - * @maxchips: Number of chips to scan for - * - * This fills out all the not initialized function pointers - * with the defaults. - * The flash ID is read and the mtd/chip structures are - * filled with the appropriate values. Buffers are allocated if - * they are not provided by the board driver - * */ -int nand_scan (struct mtd_info *mtd, int maxchips) +static int nand_suspend(struct mtd_info *mtd) { - int i, j, nand_maf_id, nand_dev_id, busw; - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; + + return nand_get_device(chip, mtd, FL_PM_SUSPENDED); +} + +/** + * nand_resume - [MTD Interface] Resume the NAND flash + * @mtd: MTD device structure + */ +static void nand_resume(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; - /* Get buswidth to select the correct functions*/ - busw = this->options & NAND_BUSWIDTH_16; + if (chip->state == FL_PM_SUSPENDED) + nand_release_device(mtd); + else + printk(KERN_ERR "nand_resume() called for a chip which is not " + "in suspended state\n"); +} +/* + * Set default functions + */ +static void nand_set_defaults(struct nand_chip *chip, int busw) +{ /* check for proper chip_delay setup, set 20us if not */ - if (!this->chip_delay) - this->chip_delay = 20; + if (!chip->chip_delay) + chip->chip_delay = 20; /* check, if a user supplied command function given */ - if (this->cmdfunc == NULL) - this->cmdfunc = nand_command; + if (chip->cmdfunc == NULL) + chip->cmdfunc = nand_command; /* check, if a user supplied wait function given */ - if (this->waitfunc == NULL) - this->waitfunc = nand_wait; - - if (!this->select_chip) - this->select_chip = nand_select_chip; - if (!this->write_byte) - this->write_byte = busw ? nand_write_byte16 : nand_write_byte; - if (!this->read_byte) - this->read_byte = busw ? nand_read_byte16 : nand_read_byte; - if (!this->write_word) - this->write_word = nand_write_word; - if (!this->read_word) - this->read_word = nand_read_word; - if (!this->block_bad) - this->block_bad = nand_block_bad; - if (!this->block_markbad) - this->block_markbad = nand_default_block_markbad; - if (!this->write_buf) - this->write_buf = busw ? nand_write_buf16 : nand_write_buf; - if (!this->read_buf) - this->read_buf = busw ? nand_read_buf16 : nand_read_buf; - if (!this->verify_buf) - this->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; - if (!this->scan_bbt) - this->scan_bbt = nand_default_bbt; + if (chip->waitfunc == NULL) + chip->waitfunc = nand_wait; + + if (!chip->select_chip) + chip->select_chip = nand_select_chip; + if (!chip->read_byte) + chip->read_byte = busw ? nand_read_byte16 : nand_read_byte; + if (!chip->read_word) + chip->read_word = nand_read_word; + if (!chip->block_bad) + chip->block_bad = nand_block_bad; + if (!chip->block_markbad) + chip->block_markbad = nand_default_block_markbad; + if (!chip->write_buf) + chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; + if (!chip->read_buf) + chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; + if (!chip->verify_buf) + chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf; + if (!chip->scan_bbt) + chip->scan_bbt = nand_default_bbt; + + if (!chip->controller) { + chip->controller = &chip->hwcontrol; + + /* XXX U-BOOT XXX */ +#if 0 + spin_lock_init(&chip->controller->lock); + init_waitqueue_head(&chip->controller->wq); +#endif + } + +} + +/* + * Get the flash and manufacturer id and lookup if the type is supported + */ +static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, + struct nand_chip *chip, + int busw, int *maf_id) +{ + struct nand_flash_dev *type = NULL; + int i, dev_id, maf_idx; /* Select the device */ - this->select_chip(mtd, 0); + chip->select_chip(mtd, 0); /* Send the command for reading device ID */ - this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ - nand_maf_id = this->read_byte(mtd); - nand_dev_id = this->read_byte(mtd); + *maf_id = chip->read_byte(mtd); + dev_id = chip->read_byte(mtd); - /* Print and store flash device information */ + /* Lookup the flash id */ for (i = 0; nand_flash_ids[i].name != NULL; i++) { + if (dev_id == nand_flash_ids[i].id) { + type = &nand_flash_ids[i]; + break; + } + } - if (nand_dev_id != nand_flash_ids[i].id) - continue; + if (!type) + return ERR_PTR(-ENODEV); + + if (!mtd->name) + mtd->name = type->name; + + chip->chipsize = type->chipsize << 20; + + /* Newer devices have all the information in additional id bytes */ + if (!type->pagesize) { + int extid; + /* The 3rd id byte holds MLC / multichip data */ + chip->cellinfo = chip->read_byte(mtd); + /* The 4th id byte is the important one */ + extid = chip->read_byte(mtd); + /* Calc pagesize */ + mtd->writesize = 1024 << (extid & 0x3); + extid >>= 2; + /* Calc oobsize */ + mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9); + extid >>= 2; + /* Calc blocksize. Blocksize is multiples of 64KiB */ + mtd->erasesize = (64 * 1024) << (extid & 0x03); + extid >>= 2; + /* Get buswidth information */ + busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; - if (!mtd->name) mtd->name = nand_flash_ids[i].name; - this->chipsize = nand_flash_ids[i].chipsize << 20; - - /* New devices have all the information in additional id bytes */ - if (!nand_flash_ids[i].pagesize) { - int extid; - /* The 3rd id byte contains non relevant data ATM */ - extid = this->read_byte(mtd); - /* The 4th id byte is the important one */ - extid = this->read_byte(mtd); - /* Calc pagesize */ - mtd->oobblock = 1024 << (extid & 0x3); - extid >>= 2; - /* Calc oobsize */ - mtd->oobsize = (8 << (extid & 0x01)) * (mtd->oobblock / 512); - extid >>= 2; - /* Calc blocksize. Blocksize is multiples of 64KiB */ - mtd->erasesize = (64 * 1024) << (extid & 0x03); - extid >>= 2; - /* Get buswidth information */ - busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0; + } else { + /* + * Old devices have chip data hardcoded in the device id table + */ + mtd->erasesize = type->erasesize; + mtd->writesize = type->pagesize; + mtd->oobsize = mtd->writesize / 32; + busw = type->options & NAND_BUSWIDTH_16; + } - } else { - /* Old devices have this data hardcoded in the - * device id table */ - mtd->erasesize = nand_flash_ids[i].erasesize; - mtd->oobblock = nand_flash_ids[i].pagesize; - mtd->oobsize = mtd->oobblock / 32; - busw = nand_flash_ids[i].options & NAND_BUSWIDTH_16; - } + /* Try to identify manufacturer */ + for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { + if (nand_manuf_ids[maf_idx].id == *maf_id) + break; + } - /* Check, if buswidth is correct. Hardware drivers should set - * this correct ! */ - if (busw != (this->options & NAND_BUSWIDTH_16)) { - printk (KERN_INFO "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id, - nand_manuf_ids[i].name , mtd->name); - printk (KERN_WARNING - "NAND bus width %d instead %d bit\n", - (this->options & NAND_BUSWIDTH_16) ? 16 : 8, - busw ? 16 : 8); - this->select_chip(mtd, -1); - return 1; - } + /* + * Check, if buswidth is correct. Hardware drivers should set + * chip correct ! + */ + if (busw != (chip->options & NAND_BUSWIDTH_16)) { + printk(KERN_INFO "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, + dev_id, nand_manuf_ids[maf_idx].name, mtd->name); + printk(KERN_WARNING "NAND bus width %d instead %d bit\n", + (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, + busw ? 16 : 8); + return ERR_PTR(-EINVAL); + } - /* Calculate the address shift from the page size */ - this->page_shift = ffs(mtd->oobblock) - 1; - this->bbt_erase_shift = this->phys_erase_shift = ffs(mtd->erasesize) - 1; - this->chip_shift = ffs(this->chipsize) - 1; - - /* Set the bad block position */ - this->badblockpos = mtd->oobblock > 512 ? - NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; - - /* Get chip options, preserve non chip based options */ - this->options &= ~NAND_CHIPOPTIONS_MSK; - this->options |= nand_flash_ids[i].options & NAND_CHIPOPTIONS_MSK; - /* Set this as a default. Board drivers can override it, if neccecary */ - this->options |= NAND_NO_AUTOINCR; - /* Check if this is a not a samsung device. Do not clear the options - * for chips which are not having an extended id. - */ - if (nand_maf_id != NAND_MFR_SAMSUNG && !nand_flash_ids[i].pagesize) - this->options &= ~NAND_SAMSUNG_LP_OPTIONS; + /* Calculate the address shift from the page size */ + chip->page_shift = ffs(mtd->writesize) - 1; + /* Convert chipsize to number of pages per chip -1. */ + chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; - /* Check for AND chips with 4 page planes */ - if (this->options & NAND_4PAGE_ARRAY) - this->erase_cmd = multi_erase_cmd; - else - this->erase_cmd = single_erase_cmd; + chip->bbt_erase_shift = chip->phys_erase_shift = + ffs(mtd->erasesize) - 1; + chip->chip_shift = ffs(chip->chipsize) - 1; - /* Do not replace user supplied command function ! */ - if (mtd->oobblock > 512 && this->cmdfunc == nand_command) - this->cmdfunc = nand_command_lp; + /* Set the bad block position */ + chip->badblockpos = mtd->writesize > 512 ? + NAND_LARGE_BADBLOCK_POS : NAND_SMALL_BADBLOCK_POS; - /* Try to identify manufacturer */ - for (j = 0; nand_manuf_ids[j].id != 0x0; j++) { - if (nand_manuf_ids[j].id == nand_maf_id) - break; - } - break; - } + /* Get chip options, preserve non chip based options */ + chip->options &= ~NAND_CHIPOPTIONS_MSK; + chip->options |= type->options & NAND_CHIPOPTIONS_MSK; - if (!nand_flash_ids[i].name) { -#ifndef CFG_NAND_QUIET_TEST - printk (KERN_WARNING "No NAND device found!!!\n"); -#endif - this->select_chip(mtd, -1); - return 1; - } + /* + * Set chip as a default. Board drivers can override it, if necessary + */ + chip->options |= NAND_NO_AUTOINCR; - for (i=1; i < maxchips; i++) { - this->select_chip(mtd, i); + /* Check if chip is a not a samsung device. Do not clear the + * options for chips which are not having an extended id. + */ + if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) + chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; - /* Send the command for reading device ID */ - this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); + /* Check for AND chips with 4 page planes */ + if (chip->options & NAND_4PAGE_ARRAY) + chip->erase_cmd = multi_erase_cmd; + else + chip->erase_cmd = single_erase_cmd; + + /* Do not replace user supplied command function ! */ + if (mtd->writesize > 512 && chip->cmdfunc == nand_command) + chip->cmdfunc = nand_command_lp; + + printk(KERN_INFO "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, + nand_manuf_ids[maf_idx].name, type->name); + + return type; +} + +/** + * nand_scan_ident - [NAND Interface] Scan for the NAND device + * @mtd: MTD device structure + * @maxchips: Number of chips to scan for + * + * This is the first phase of the normal nand_scan() function. It + * reads the flash ID and sets up MTD fields accordingly. + * + * The mtd->owner field must be set to the module of the caller. + */ +int nand_scan_ident(struct mtd_info *mtd, int maxchips) +{ + int i, busw, nand_maf_id; + struct nand_chip *chip = mtd->priv; + struct nand_flash_dev *type; + + /* Get buswidth to select the correct functions */ + busw = chip->options & NAND_BUSWIDTH_16; + /* Set the default functions */ + nand_set_defaults(chip, busw); + + /* Read the flash type */ + type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id); + + if (IS_ERR(type)) { + printk(KERN_WARNING "No NAND device found!!!\n"); + chip->select_chip(mtd, -1); + return PTR_ERR(type); + } + /* Check for a chip array */ + for (i = 1; i < maxchips; i++) { + chip->select_chip(mtd, i); + /* Send the command for reading device ID */ + chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ - if (nand_maf_id != this->read_byte(mtd) || - nand_dev_id != this->read_byte(mtd)) + if (nand_maf_id != chip->read_byte(mtd) || + type->id != chip->read_byte(mtd)) break; } if (i > 1) printk(KERN_INFO "%d NAND chips detected\n", i); - /* Allocate buffers, if neccecary */ - if (!this->oob_buf) { - size_t len; - len = mtd->oobsize << (this->phys_erase_shift - this->page_shift); - this->oob_buf = kmalloc (len, GFP_KERNEL); - if (!this->oob_buf) { - printk (KERN_ERR "nand_scan(): Cannot allocate oob_buf\n"); - return -ENOMEM; - } - this->options |= NAND_OOBBUF_ALLOC; - } + /* Store the number of chips and calc total size for mtd */ + chip->numchips = i; + mtd->size = i * chip->chipsize; - if (!this->data_buf) { - size_t len; - len = mtd->oobblock + mtd->oobsize; - this->data_buf = kmalloc (len, GFP_KERNEL); - if (!this->data_buf) { - if (this->options & NAND_OOBBUF_ALLOC) - kfree (this->oob_buf); - printk (KERN_ERR "nand_scan(): Cannot allocate data_buf\n"); - return -ENOMEM; - } - this->options |= NAND_DATABUF_ALLOC; - } + return 0; +} - /* Store the number of chips and calc total size for mtd */ - this->numchips = i; - mtd->size = i * this->chipsize; - /* Convert chipsize to number of pages per chip -1. */ - this->pagemask = (this->chipsize >> this->page_shift) - 1; - /* Preset the internal oob buffer */ - memset(this->oob_buf, 0xff, mtd->oobsize << (this->phys_erase_shift - this->page_shift)); - - /* If no default placement scheme is given, select an - * appropriate one */ - if (!this->autooob) { - /* Select the appropriate default oob placement scheme for - * placement agnostic filesystems */ + +/** + * nand_scan_tail - [NAND Interface] Scan for the NAND device + * @mtd: MTD device structure + * @maxchips: Number of chips to scan for + * + * This is the second phase of the normal nand_scan() function. It + * fills out all the uninitialized function pointers with the defaults + * and scans for a bad block table if appropriate. + */ +int nand_scan_tail(struct mtd_info *mtd) +{ + int i; + struct nand_chip *chip = mtd->priv; + + if (!(chip->options & NAND_OWN_BUFFERS)) + chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL); + if (!chip->buffers) + return -ENOMEM; + + /* Set the internal oob buffer location, just after the page data */ + chip->oob_poi = chip->buffers->databuf + mtd->writesize; + + /* + * If no default placement scheme is given, select an appropriate one + */ + if (!chip->ecc.layout) { switch (mtd->oobsize) { case 8: - this->autooob = &nand_oob_8; + chip->ecc.layout = &nand_oob_8; break; case 16: - this->autooob = &nand_oob_16; + chip->ecc.layout = &nand_oob_16; break; case 64: - this->autooob = &nand_oob_64; + chip->ecc.layout = &nand_oob_64; break; case 128: - this->autooob = &nand_oob_128; + chip->ecc.layout = &nand_oob_128; break; default: - printk (KERN_WARNING "No oob scheme defined for oobsize %d\n", - mtd->oobsize); -/* BUG(); */ + printk(KERN_WARNING "No oob scheme defined for " + "oobsize %d\n", mtd->oobsize); +// BUG(); } } - /* The number of bytes available for the filesystem to place fs dependend - * oob data */ - mtd->oobavail = 0; - for (i=0; this->autooob->oobfree[i][1]; i++) - mtd->oobavail += this->autooob->oobfree[i][1]; + if (!chip->write_page) + chip->write_page = nand_write_page; /* - * check ECC mode, default to software - * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize - * fallback to software ECC - */ - this->eccsize = 256; /* set default eccsize */ - this->eccbytes = 3; - - switch (this->eccmode) { - case NAND_ECC_HW12_2048: - if (mtd->oobblock < 2048) { - printk(KERN_WARNING "2048 byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", - mtd->oobblock); - this->eccmode = NAND_ECC_SOFT; - this->calculate_ecc = nand_calculate_ecc; - this->correct_data = nand_correct_data; - } else - this->eccsize = 2048; - break; - - case NAND_ECC_HW3_512: - case NAND_ECC_HW6_512: - case NAND_ECC_HW8_512: - if (mtd->oobblock == 256) { - printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n"); - this->eccmode = NAND_ECC_SOFT; - this->calculate_ecc = nand_calculate_ecc; - this->correct_data = nand_correct_data; - } else - this->eccsize = 512; /* set eccsize to 512 */ - break; + * check ECC mode, default to software if 3byte/512byte hardware ECC is + * selected and we have 256 byte pagesize fallback to software ECC + */ + if (!chip->ecc.read_page_raw) + chip->ecc.read_page_raw = nand_read_page_raw; + if (!chip->ecc.write_page_raw) + chip->ecc.write_page_raw = nand_write_page_raw; + + switch (chip->ecc.mode) { + case NAND_ECC_HW: + /* Use standard hwecc read page function ? */ + if (!chip->ecc.read_page) + chip->ecc.read_page = nand_read_page_hwecc; + if (!chip->ecc.write_page) + chip->ecc.write_page = nand_write_page_hwecc; + if (!chip->ecc.read_oob) + chip->ecc.read_oob = nand_read_oob_std; + if (!chip->ecc.write_oob) + chip->ecc.write_oob = nand_write_oob_std; + + case NAND_ECC_HW_SYNDROME: + if (!chip->ecc.calculate || !chip->ecc.correct || + !chip->ecc.hwctl) { + printk(KERN_WARNING "No ECC functions supplied, " + "Hardware ECC not possible\n"); + BUG(); + } + /* Use standard syndrome read/write page function ? */ + if (!chip->ecc.read_page) + chip->ecc.read_page = nand_read_page_syndrome; + if (!chip->ecc.write_page) + chip->ecc.write_page = nand_write_page_syndrome; + if (!chip->ecc.read_oob) + chip->ecc.read_oob = nand_read_oob_syndrome; + if (!chip->ecc.write_oob) + chip->ecc.write_oob = nand_write_oob_syndrome; + + if (mtd->writesize >= chip->ecc.size) + break; + printk(KERN_WARNING "%d byte HW ECC not possible on " + "%d byte page size, fallback to SW ECC\n", + chip->ecc.size, mtd->writesize); + chip->ecc.mode = NAND_ECC_SOFT; - case NAND_ECC_HW3_256: + case NAND_ECC_SOFT: + chip->ecc.calculate = nand_calculate_ecc; + chip->ecc.correct = nand_correct_data; + chip->ecc.read_page = nand_read_page_swecc; + chip->ecc.write_page = nand_write_page_swecc; + chip->ecc.read_oob = nand_read_oob_std; + chip->ecc.write_oob = nand_write_oob_std; + chip->ecc.size = 256; + chip->ecc.bytes = 3; break; case NAND_ECC_NONE: - printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n"); - this->eccmode = NAND_ECC_NONE; - break; - - case NAND_ECC_SOFT: - this->calculate_ecc = nand_calculate_ecc; - this->correct_data = nand_correct_data; + printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " + "This is not recommended !!\n"); + chip->ecc.read_page = nand_read_page_raw; + chip->ecc.write_page = nand_write_page_raw; + chip->ecc.read_oob = nand_read_oob_std; + chip->ecc.write_oob = nand_write_oob_std; + chip->ecc.size = mtd->writesize; + chip->ecc.bytes = 0; break; default: - printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); -/* BUG(); */ - } - - /* Check hardware ecc function availability and adjust number of ecc bytes per - * calculation step - */ - switch (this->eccmode) { - case NAND_ECC_HW12_2048: - this->eccbytes += 4; - case NAND_ECC_HW8_512: - this->eccbytes += 2; - case NAND_ECC_HW6_512: - this->eccbytes += 3; - case NAND_ECC_HW3_512: - case NAND_ECC_HW3_256: - if (this->calculate_ecc && this->correct_data && this->enable_hwecc) - break; - printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not possible\n"); -/* BUG(); */ + printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n", + chip->ecc.mode); + BUG(); } - mtd->eccsize = this->eccsize; + /* + * The number of bytes available for a client to place data into + * the out of band area + */ + chip->ecc.layout->oobavail = 0; + for (i = 0; chip->ecc.layout->oobfree[i].length; i++) + chip->ecc.layout->oobavail += + chip->ecc.layout->oobfree[i].length; + mtd->oobavail = chip->ecc.layout->oobavail; - /* Set the number of read / write steps for one page to ensure ECC generation */ - switch (this->eccmode) { - case NAND_ECC_HW12_2048: - this->eccsteps = mtd->oobblock / 2048; - break; - case NAND_ECC_HW3_512: - case NAND_ECC_HW6_512: - case NAND_ECC_HW8_512: - this->eccsteps = mtd->oobblock / 512; - break; - case NAND_ECC_HW3_256: - case NAND_ECC_SOFT: - this->eccsteps = mtd->oobblock / 256; - break; + /* + * Set the number of read / write steps for one page depending on ECC + * mode + */ + chip->ecc.steps = mtd->writesize / chip->ecc.size; + if(chip->ecc.steps * chip->ecc.size != mtd->writesize) { + printk(KERN_WARNING "Invalid ecc parameters\n"); + BUG(); + } + chip->ecc.total = chip->ecc.steps * chip->ecc.bytes; - case NAND_ECC_NONE: - this->eccsteps = 1; - break; + /* + * Allow subpage writes up to ecc.steps. Not possible for MLC + * FLASH. + */ + if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && + !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) { + switch(chip->ecc.steps) { + case 2: + mtd->subpage_sft = 1; + break; + case 4: + case 8: + mtd->subpage_sft = 2; + break; + } } + chip->subpagesize = mtd->writesize >> mtd->subpage_sft; -/* XXX U-BOOT XXX */ -#if 0 - /* Initialize state, waitqueue and spinlock */ - this->state = FL_READY; - init_waitqueue_head (&this->wq); - spin_lock_init (&this->chip_lock); -#endif + /* Initialize state */ + chip->state = FL_READY; /* De-select the device */ - this->select_chip(mtd, -1); + chip->select_chip(mtd, -1); /* Invalidate the pagebuffer reference */ - this->pagebuf = -1; + chip->pagebuf = -1; /* Fill in remaining MTD driver data */ mtd->type = MTD_NANDFLASH; - mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC; - mtd->ecctype = MTD_ECC_SW; + mtd->flags = MTD_CAP_NANDFLASH; mtd->erase = nand_erase; mtd->point = NULL; mtd->unpoint = NULL; mtd->read = nand_read; mtd->write = nand_write; - mtd->read_ecc = nand_read_ecc; - mtd->write_ecc = nand_write_ecc; mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; -/* XXX U-BOOT XXX */ -#if 0 - mtd->readv = NULL; - mtd->writev = nand_writev; - mtd->writev_ecc = nand_writev_ecc; -#endif mtd->sync = nand_sync; -/* XXX U-BOOT XXX */ -#if 0 mtd->lock = NULL; mtd->unlock = NULL; - mtd->suspend = NULL; - mtd->resume = NULL; -#endif + mtd->suspend = nand_suspend; + mtd->resume = nand_resume; mtd->block_isbad = nand_block_isbad; mtd->block_markbad = nand_block_markbad; - /* and make the autooob the default one */ - memcpy(&mtd->oobinfo, this->autooob, sizeof(mtd->oobinfo)); -/* XXX U-BOOT XXX */ + /* propagate ecc.layout to mtd_info */ + mtd->ecclayout = chip->ecc.layout; + + /* Check, if we should skip the bad block table scan */ + if (chip->options & NAND_SKIP_BBTSCAN) + return 0; + + /* Build bad block table */ + return chip->scan_bbt(mtd); +} + +/* module_text_address() isn't exported, and it's mostly a pointless + test if this is a module _anyway_ -- they'd have to try _really_ hard + to call us from in-kernel code if the core NAND support is modular. */ +#ifdef MODULE +#define caller_is_module() (1) +#else +#define caller_is_module() \ + module_text_address((unsigned long)__builtin_return_address(0)) +#endif + +/** + * nand_scan - [NAND Interface] Scan for the NAND device + * @mtd: MTD device structure + * @maxchips: Number of chips to scan for + * + * This fills out all the uninitialized function pointers + * with the defaults. + * The flash ID is read and the mtd/chip structures are + * filled with the appropriate values. + * The mtd->owner field must be set to the module of the caller + * + */ +int nand_scan(struct mtd_info *mtd, int maxchips) +{ + int ret; + + /* Many callers got this wrong, so check for it for a while... */ + /* XXX U-BOOT XXX */ #if 0 - mtd->owner = THIS_MODULE; + if (!mtd->owner && caller_is_module()) { + printk(KERN_CRIT "nand_scan() called with NULL mtd->owner!\n"); + BUG(); + } #endif - /* Build bad block table */ - return this->scan_bbt (mtd); + + ret = nand_scan_ident(mtd, maxchips); + if (!ret) + ret = nand_scan_tail(mtd); + return ret; } /** * nand_release - [NAND Interface] Free resources held by the NAND device * @mtd: MTD device structure - */ -void nand_release (struct mtd_info *mtd) +*/ +void nand_release(struct mtd_info *mtd) { - struct nand_chip *this = mtd->priv; + struct nand_chip *chip = mtd->priv; #ifdef CONFIG_MTD_PARTITIONS /* Deregister partitions */ - del_mtd_partitions (mtd); + del_mtd_partitions(mtd); #endif /* Deregister the device */ -/* XXX U-BOOT XXX */ + /* XXX U-BOOT XXX */ #if 0 - del_mtd_device (mtd); + del_mtd_device(mtd); #endif - /* Free bad block table memory, if allocated */ - if (this->bbt) - kfree (this->bbt); - /* Buffer allocated by nand_scan ? */ - if (this->options & NAND_OOBBUF_ALLOC) - kfree (this->oob_buf); - /* Buffer allocated by nand_scan ? */ - if (this->options & NAND_DATABUF_ALLOC) - kfree (this->data_buf); + + /* Free bad block table memory */ + kfree(chip->bbt); + if (!(chip->options & NAND_OWN_BUFFERS)) + kfree(chip->buffers); +} + +/* XXX U-BOOT XXX */ +#if 0 +EXPORT_SYMBOL_GPL(nand_scan); +EXPORT_SYMBOL_GPL(nand_scan_ident); +EXPORT_SYMBOL_GPL(nand_scan_tail); +EXPORT_SYMBOL_GPL(nand_release); + +static int __init nand_base_init(void) +{ + led_trigger_register_simple("nand-disk", &nand_led_trigger); + return 0; +} + +static void __exit nand_base_exit(void) +{ + led_trigger_unregister_simple(nand_led_trigger); } +module_init(nand_base_init); +module_exit(nand_base_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Steven J. Hill , Thomas Gleixner "); +MODULE_DESCRIPTION("Generic NAND flash driver code"); +#endif + #endif + diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index a97743b45e8..acf1cf54339 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -6,7 +6,7 @@ * * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * - * $Id: nand_bbt.c,v 1.28 2004/11/13 10:19:09 gleixner Exp $ + * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -48,7 +48,7 @@ * * Following assumptions are made: * - bbts start at a page boundary, if autolocated on a block boundary - * - the space neccecary for a bbt in FLASH does not exceed a block boundary + * - the space necessary for a bbt in FLASH does not exceed a block boundary * */ @@ -63,6 +63,19 @@ #include +/* XXX U-BOOT XXX */ +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + /** * check_pattern - [GENERIC] check if a pattern is in the buffer * @buf: the buffer to search @@ -76,9 +89,9 @@ * pattern area contain 0xff * */ -static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) +static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) { - int i, end; + int i, end = 0; uint8_t *p = buf; end = paglen + td->offs; @@ -96,9 +109,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des return -1; } - p += td->len; - end += td->len; if (td->options & NAND_BBT_SCANEMPTY) { + p += td->len; + end += td->len; for (i = end; i < len; i++) { if (*p++ != 0xff) return -1; @@ -107,6 +120,29 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des return 0; } +/** + * check_short_pattern - [GENERIC] check if a pattern is in the buffer + * @buf: the buffer to search + * @td: search pattern descriptor + * + * Check for a pattern at the given place. Used to search bad block + * tables and good / bad block identifiers. Same as check_pattern, but + * no optional empty check + * +*/ +static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) +{ + int i; + uint8_t *p = buf; + + /* Compare the pattern */ + for (i = 0; i < td->len; i++) { + if (p[td->offs + i] != td->pattern[i]) + return -1; + } + return 0; +} + /** * read_bbt - [GENERIC] Read the bad block table starting from page * @mtd: MTD device structure @@ -120,8 +156,8 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des * Read the bad block table starting from page. * */ -static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, - int bits, int offs, int reserved_block_code) +static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, + int bits, int offs, int reserved_block_code) { int res, i, j, act = 0; struct nand_chip *this = mtd->priv; @@ -130,17 +166,17 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, uint8_t msk = (uint8_t) ((1 << bits) - 1); totlen = (num * bits) >> 3; - from = ((loff_t)page) << this->page_shift; + from = ((loff_t) page) << this->page_shift; while (totlen) { - len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); - res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); + len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); + res = mtd->read(mtd, from, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk (KERN_INFO "nand_bbt: Error reading bad block table\n"); + printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); return res; } - printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); + printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); } /* Analyse data */ @@ -150,22 +186,23 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, uint8_t tmp = (dat >> j) & msk; if (tmp == msk) continue; - if (reserved_block_code && - (tmp == reserved_block_code)) { - printk (KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", - ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + if (reserved_block_code && (tmp == reserved_block_code)) { + printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%08x\n", + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); + mtd->ecc_stats.bbtblocks++; continue; } /* Leave it for now, if its matured we can move this * message to MTD_DEBUG_LEVEL0 */ - printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", - ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); + printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", + ((offs << 2) + (act >> 1)) << this->bbt_erase_shift); /* Factory marked bad or worn out ? */ if (tmp == 0) this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); else this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); + mtd->ecc_stats.badblocks++; } } totlen -= len; @@ -185,7 +222,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, * Read the bad block table for all chips starting at a given page * We assume that the bbt bits are in consecutive order. */ -static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) +static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) { struct nand_chip *this = mtd->priv; int res = 0, i; @@ -209,6 +246,42 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des return 0; } +/* + * Scan read raw data from flash + */ +static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, + size_t len) +{ + struct mtd_oob_ops ops; + + ops.mode = MTD_OOB_RAW; + ops.ooboffs = 0; + ops.ooblen = mtd->oobsize; + ops.oobbuf = buf; + ops.datbuf = buf; + ops.len = len; + + return mtd->read_oob(mtd, offs, &ops); +} + +/* + * Scan write data with oob to flash + */ +static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, + uint8_t *buf, uint8_t *oob) +{ + struct mtd_oob_ops ops; + + ops.mode = MTD_OOB_PLACE; + ops.ooboffs = 0; + ops.ooblen = mtd->oobsize; + ops.datbuf = buf; + ops.oobbuf = oob; + ops.len = len; + + return mtd->write_oob(mtd, offs, &ops); +} + /** * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page * @mtd: MTD device structure @@ -220,28 +293,84 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des * We assume that the bbt bits are in consecutive order. * */ -static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, - struct nand_bbt_descr *md) +static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, + struct nand_bbt_descr *td, struct nand_bbt_descr *md) { struct nand_chip *this = mtd->priv; /* Read the primary version, if available */ if (td->options & NAND_BBT_VERSION) { - nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); - td->version[0] = buf[mtd->oobblock + td->veroffs]; - printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); + scan_read_raw(mtd, buf, td->pages[0] << this->page_shift, + mtd->writesize); + td->version[0] = buf[mtd->writesize + td->veroffs]; + printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + td->pages[0], td->version[0]); } /* Read the mirror version, if available */ if (md && (md->options & NAND_BBT_VERSION)) { - nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); - md->version[0] = buf[mtd->oobblock + md->veroffs]; - printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); + scan_read_raw(mtd, buf, md->pages[0] << this->page_shift, + mtd->writesize); + md->version[0] = buf[mtd->writesize + md->veroffs]; + printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", + md->pages[0], md->version[0]); } - return 1; } +/* + * Scan a given block full + */ +static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, + loff_t offs, uint8_t *buf, size_t readlen, + int scanlen, int len) +{ + int ret, j; + + ret = scan_read_raw(mtd, buf, offs, readlen); + if (ret) + return ret; + + for (j = 0; j < len; j++, buf += scanlen) { + if (check_pattern(buf, scanlen, mtd->writesize, bd)) + return 1; + } + return 0; +} + +/* + * Scan a given block partially + */ +static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, + loff_t offs, uint8_t *buf, int len) +{ + struct mtd_oob_ops ops; + int j, ret; + + ops.ooblen = mtd->oobsize; + ops.oobbuf = buf; + ops.ooboffs = 0; + ops.datbuf = NULL; + ops.mode = MTD_OOB_PLACE; + + for (j = 0; j < len; j++) { + /* + * Read the full oob until read_oob is fixed to + * handle single byte reads for 16 bit + * buswidth + */ + ret = mtd->read_oob(mtd, offs, &ops); + if (ret) + return ret; + + if (check_short_pattern(buf, bd)) + return 1; + + offs += mtd->writesize; + } + return 0; +} + /** * create_bbt - [GENERIC] Create a bad block table by scanning the device * @mtd: MTD device structure @@ -253,13 +382,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de * Create a bad block table by scanning the device * for the given good/bad block identify pattern */ -static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) +static int create_bbt(struct mtd_info *mtd, uint8_t *buf, + struct nand_bbt_descr *bd, int chip) { struct nand_chip *this = mtd->priv; - int i, j, numblocks, len, scanlen; + int i, numblocks, len, scanlen; int startblock; loff_t from; - size_t readlen, ooblen; + size_t readlen; + + printk(KERN_INFO "Scanning device for bad blocks\n"); if (bd->options & NAND_BBT_SCANALLPAGES) len = 1 << (this->bbt_erase_shift - this->page_shift); @@ -269,21 +401,28 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc else len = 1; } - scanlen = mtd->oobblock + mtd->oobsize; - readlen = len * mtd->oobblock; - ooblen = len * mtd->oobsize; + + if (!(bd->options & NAND_BBT_SCANEMPTY)) { + /* We need only read few bytes from the OOB area */ + scanlen = 0; + readlen = bd->len; + } else { + /* Full page content should be read */ + scanlen = mtd->writesize + mtd->oobsize; + readlen = len * mtd->writesize; + } if (chip == -1) { - /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it - * makes shifting and masking less painful */ + /* Note that numblocks is 2 * (real numblocks) here, see i+=2 + * below as it makes shifting and masking less painful */ numblocks = mtd->size >> (this->bbt_erase_shift - 1); startblock = 0; from = 0; } else { if (chip >= this->numchips) { - printk (KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", - chip + 1, this->numchips); - return; + printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", + chip + 1, this->numchips); + return -EINVAL; } numblocks = this->chipsize >> (this->bbt_erase_shift - 1); startblock = chip * numblocks; @@ -292,16 +431,28 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc } for (i = startblock; i < numblocks;) { - nand_read_raw (mtd, buf, from, readlen, ooblen); - for (j = 0; j < len; j++) { - if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { - this->bbt[i >> 3] |= 0x03 << (i & 0x6); - break; - } + int ret; + + if (bd->options & NAND_BBT_SCANALLPAGES) + ret = scan_block_full(mtd, bd, from, buf, readlen, + scanlen, len); + else + ret = scan_block_fast(mtd, bd, from, buf, len); + + if (ret < 0) + return ret; + + if (ret) { + this->bbt[i >> 3] |= 0x03 << (i & 0x6); + printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", + i >> 1, (unsigned int)from); + mtd->ecc_stats.badblocks++; } + i += 2; from += (1 << this->bbt_erase_shift); } + return 0; } /** @@ -316,22 +467,23 @@ static void create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc * block. * If the option NAND_BBT_PERCHIP is given, each chip is searched * for a bbt, which contains the bad block information of this chip. - * This is neccecary to provide support for certain DOC devices. + * This is necessary to provide support for certain DOC devices. * * The bbt ident pattern resides in the oob area of the first page * in a block. */ -static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) +static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) { struct nand_chip *this = mtd->priv; int i, chips; int bits, startblock, block, dir; - int scanlen = mtd->oobblock + mtd->oobsize; + int scanlen = mtd->writesize + mtd->oobsize; int bbtblocks; + int blocktopage = this->bbt_erase_shift - this->page_shift; /* Search direction top -> down ? */ if (td->options & NAND_BBT_LASTBLOCK) { - startblock = (mtd->size >> this->bbt_erase_shift) -1; + startblock = (mtd->size >> this->bbt_erase_shift) - 1; dir = -1; } else { startblock = 0; @@ -357,13 +509,16 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr td->pages[i] = -1; /* Scan the maximum number of blocks */ for (block = 0; block < td->maxblocks; block++) { + int actblock = startblock + dir * block; + loff_t offs = actblock << this->bbt_erase_shift; + /* Read first page */ - nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); - if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { - td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); + scan_read_raw(mtd, buf, offs, mtd->writesize); + if (!check_pattern(buf, scanlen, mtd->writesize, td)) { + td->pages[i] = actblock << blocktopage; if (td->options & NAND_BBT_VERSION) { - td->version[i] = buf[mtd->oobblock + td->veroffs]; + td->version[i] = buf[mtd->writesize + td->veroffs]; } break; } @@ -373,9 +528,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr /* Check, if we found a bbt for each requested chip */ for (i = 0; i < chips; i++) { if (td->pages[i] == -1) - printk (KERN_WARNING "Bad block table not found for chip %d\n", i); + printk(KERN_WARNING "Bad block table not found for chip %d\n", i); else - printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); + printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], + td->version[i]); } return 0; } @@ -389,21 +545,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr * * Search and read the bad block table(s) */ -static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, - struct nand_bbt_descr *td, struct nand_bbt_descr *md) +static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) { /* Search the primary table */ - search_bbt (mtd, buf, td); + search_bbt(mtd, buf, td); /* Search the mirror table */ if (md) - search_bbt (mtd, buf, md); + search_bbt(mtd, buf, md); /* Force result check */ return 1; } - /** * write_bbt - [GENERIC] (Re)write the bad block table * @@ -416,25 +570,31 @@ static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, * (Re)write the bad block table * */ -static int write_bbt (struct mtd_info *mtd, uint8_t *buf, - struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) +static int write_bbt(struct mtd_info *mtd, uint8_t *buf, + struct nand_bbt_descr *td, struct nand_bbt_descr *md, + int chipsel) { struct nand_chip *this = mtd->priv; - struct nand_oobinfo oobinfo; struct erase_info einfo; int i, j, res, chip = 0; int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; - int nrchips, bbtoffs, pageoffs; + int nrchips, bbtoffs, pageoffs, ooboffs; uint8_t msk[4]; uint8_t rcode = td->reserved_block_code; size_t retlen, len = 0; loff_t to; + struct mtd_oob_ops ops; + + ops.ooblen = mtd->oobsize; + ops.ooboffs = 0; + ops.datbuf = NULL; + ops.mode = MTD_OOB_PLACE; if (!rcode) rcode = 0xff; /* Write bad block table per chip rather than per device ? */ if (td->options & NAND_BBT_PERCHIP) { - numblocks = (int) (this->chipsize >> this->bbt_erase_shift); + numblocks = (int)(this->chipsize >> this->bbt_erase_shift); /* Full device write or specific chip ? */ if (chipsel == -1) { nrchips = this->numchips; @@ -443,7 +603,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, chip = chipsel; } } else { - numblocks = (int) (mtd->size >> this->bbt_erase_shift); + numblocks = (int)(mtd->size >> this->bbt_erase_shift); nrchips = 1; } @@ -472,27 +632,38 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf, for (i = 0; i < td->maxblocks; i++) { int block = startblock + dir * i; /* Check, if the block is bad */ - switch ((this->bbt[block >> 2] >> (2 * (block & 0x03))) & 0x03) { + switch ((this->bbt[block >> 2] >> + (2 * (block & 0x03))) & 0x03) { case 0x01: case 0x03: continue; } - page = block << (this->bbt_erase_shift - this->page_shift); + page = block << + (this->bbt_erase_shift - this->page_shift); /* Check, if the block is used by the mirror table */ if (!md || md->pages[chip] != page) goto write; } - printk (KERN_ERR "No space left to write bad block table\n"); + printk(KERN_ERR "No space left to write bad block table\n"); return -ENOSPC; -write: + write: /* Set up shift count and masks for the flash table */ bits = td->options & NAND_BBT_NRBITS_MSK; + msk[2] = ~rcode; switch (bits) { - case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x01; break; - case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; msk[2] = ~rcode; msk[3] = 0x03; break; - case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; msk[2] = ~rcode; msk[3] = 0x0f; break; - case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; + case 1: sft = 3; sftmsk = 0x07; msk[0] = 0x00; msk[1] = 0x01; + msk[3] = 0x01; + break; + case 2: sft = 2; sftmsk = 0x06; msk[0] = 0x00; msk[1] = 0x01; + msk[3] = 0x03; + break; + case 4: sft = 1; sftmsk = 0x04; msk[0] = 0x00; msk[1] = 0x0C; + msk[3] = 0x0f; + break; + case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; + msk[3] = 0xff; + break; default: return -EINVAL; } @@ -500,82 +671,92 @@ write: to = ((loff_t) page) << this->page_shift; - memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); - oobinfo.useecc = MTD_NANDECC_PLACEONLY; - /* Must we save the block contents ? */ if (td->options & NAND_BBT_SAVECONTENT) { /* Make it block aligned */ to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); len = 1 << this->bbt_erase_shift; - res = mtd->read_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); + res = mtd->read(mtd, to, len, &retlen, buf); if (res < 0) { if (retlen != len) { - printk (KERN_INFO "nand_bbt: Error reading block for writing the bad block table\n"); + printk(KERN_INFO "nand_bbt: Error " + "reading block for writing " + "the bad block table\n"); return res; } - printk (KERN_WARNING "nand_bbt: ECC error while reading block for writing bad block table\n"); + printk(KERN_WARNING "nand_bbt: ECC error " + "while reading block for writing " + "bad block table\n"); } + /* Read oob data */ + ops.ooblen = (len >> this->page_shift) * mtd->oobsize; + ops.oobbuf = &buf[len]; + res = mtd->read_oob(mtd, to + mtd->writesize, &ops); + if (res < 0 || ops.oobretlen != ops.ooblen) + goto outerr; + /* Calc the byte offset in the buffer */ pageoffs = page - (int)(to >> this->page_shift); offs = pageoffs << this->page_shift; /* Preset the bbt area with 0xff */ - memset (&buf[offs], 0xff, (size_t)(numblocks >> sft)); - /* Preset the bbt's oob area with 0xff */ - memset (&buf[len + pageoffs * mtd->oobsize], 0xff, - ((len >> this->page_shift) - pageoffs) * mtd->oobsize); - if (td->options & NAND_BBT_VERSION) { - buf[len + (pageoffs * mtd->oobsize) + td->veroffs] = td->version[chip]; - } + memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); + ooboffs = len + (pageoffs * mtd->oobsize); + } else { /* Calc length */ len = (size_t) (numblocks >> sft); /* Make it page aligned ! */ - len = (len + (mtd->oobblock-1)) & ~(mtd->oobblock-1); + len = (len + (mtd->writesize - 1)) & + ~(mtd->writesize - 1); /* Preset the buffer with 0xff */ - memset (buf, 0xff, len + (len >> this->page_shift) * mtd->oobsize); + memset(buf, 0xff, len + + (len >> this->page_shift)* mtd->oobsize); offs = 0; + ooboffs = len; /* Pattern is located in oob area of first page */ - memcpy (&buf[len + td->offs], td->pattern, td->len); - if (td->options & NAND_BBT_VERSION) { - buf[len + td->veroffs] = td->version[chip]; - } + memcpy(&buf[ooboffs + td->offs], td->pattern, td->len); } + if (td->options & NAND_BBT_VERSION) + buf[ooboffs + td->veroffs] = td->version[chip]; + /* walk through the memory table */ - for (i = 0; i < numblocks; ) { + for (i = 0; i < numblocks;) { uint8_t dat; dat = this->bbt[bbtoffs + (i >> 2)]; - for (j = 0; j < 4; j++ , i++) { + for (j = 0; j < 4; j++, i++) { int sftcnt = (i << (3 - sft)) & sftmsk; /* Do not store the reserved bbt blocks ! */ - buf[offs + (i >> sft)] &= ~(msk[dat & 0x03] << sftcnt); + buf[offs + (i >> sft)] &= + ~(msk[dat & 0x03] << sftcnt); dat >>= 2; } } - memset (&einfo, 0, sizeof (einfo)); + memset(&einfo, 0, sizeof(einfo)); einfo.mtd = mtd; - einfo.addr = (unsigned long) to; + einfo.addr = (unsigned long)to; einfo.len = 1 << this->bbt_erase_shift; - res = nand_erase_nand (mtd, &einfo, 1); - if (res < 0) { - printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); - return res; - } + res = nand_erase_nand(mtd, &einfo, 1); + if (res < 0) + goto outerr; - res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); - if (res < 0) { - printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); - return res; - } - printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", - (unsigned int) to, td->version[chip]); + res = scan_write_bbt(mtd, to, len, buf, &buf[len]); + if (res < 0) + goto outerr; + + printk(KERN_DEBUG "Bad block table written to 0x%08x, version " + "0x%02X\n", (unsigned int)to, td->version[chip]); /* Mark it as used */ td->pages[chip] = page; } return 0; + + outerr: + printk(KERN_WARNING + "nand_bbt: Error while writing bad block table %d\n", res); + return res; } /** @@ -586,29 +767,27 @@ write: * The function creates a memory based bbt by scanning the device * for manufacturer / software marked good / bad blocks */ -static int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) +static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct nand_chip *this = mtd->priv; - /* Ensure that we only scan for the pattern and nothing else */ - bd->options = 0; - create_bbt (mtd, this->data_buf, bd, -1); - return 0; + bd->options &= ~NAND_BBT_SCANEMPTY; + return create_bbt(mtd, this->buffers->databuf, bd, -1); } /** - * check_create - [GENERIC] create and write bbt(s) if neccecary + * check_create - [GENERIC] create and write bbt(s) if necessary * @mtd: MTD device structure * @buf: temporary buffer * @bd: descriptor for the good/bad block search pattern * * The function checks the results of the previous call to read_bbt - * and creates / updates the bbt(s) if neccecary - * Creation is neccecary if no bbt was found for the chip/device - * Update is neccecary if one of the tables is missing or the + * and creates / updates the bbt(s) if necessary + * Creation is necessary if no bbt was found for the chip/device + * Update is necessary if one of the tables is missing or the * version nr. of one table is less than the other */ -static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) +static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) { int i, chips, writeops, chipsel, res; struct nand_chip *this = mtd->priv; @@ -676,35 +855,35 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des rd = td; goto writecheck; } -create: + create: /* Create the bad block table by scanning the device ? */ if (!(td->options & NAND_BBT_CREATE)) continue; /* Create the table in memory by scanning the chip(s) */ - create_bbt (mtd, buf, bd, chipsel); + create_bbt(mtd, buf, bd, chipsel); td->version[i] = 1; if (md) md->version[i] = 1; -writecheck: + writecheck: /* read back first ? */ if (rd) - read_abs_bbt (mtd, buf, rd, chipsel); + read_abs_bbt(mtd, buf, rd, chipsel); /* If they weren't versioned, read both. */ if (rd2) - read_abs_bbt (mtd, buf, rd2, chipsel); + read_abs_bbt(mtd, buf, rd2, chipsel); /* Write the bad block table to the device ? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { - res = write_bbt (mtd, buf, td, md, chipsel); + res = write_bbt(mtd, buf, td, md, chipsel); if (res < 0) return res; } /* Write the mirror bad block table to the device ? */ if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { - res = write_bbt (mtd, buf, md, td, chipsel); + res = write_bbt(mtd, buf, md, td, chipsel); if (res < 0) return res; } @@ -721,7 +900,7 @@ writecheck: * accidental erasures / writes. The regions are identified by * the mark 0x02. */ -static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) +static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) { struct nand_chip *this = mtd->priv; int i, j, chips, block, nrblocks, update; @@ -739,7 +918,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) for (i = 0; i < chips; i++) { if ((td->options & NAND_BBT_ABSPAGE) || !(td->options & NAND_BBT_WRITE)) { - if (td->pages[i] == -1) continue; + if (td->pages[i] == -1) + continue; block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); block <<= 1; oldval = this->bbt[(block >> 3)]; @@ -759,7 +939,8 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) oldval = this->bbt[(block >> 3)]; newval = oldval | (0x2 << (block & 0x06)); this->bbt[(block >> 3)] = newval; - if (oldval != newval) update = 1; + if (oldval != newval) + update = 1; block += 2; } /* If we want reserved blocks to be recorded to flash, and some @@ -784,7 +965,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td) * by calling the nand_free_bbt function. * */ -int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) +int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) { struct nand_chip *this = mtd->priv; int len, res = 0; @@ -793,53 +974,56 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) struct nand_bbt_descr *md = this->bbt_md; len = mtd->size >> (this->bbt_erase_shift + 2); - /* Allocate memory (2bit per block) */ - this->bbt = kmalloc (len, GFP_KERNEL); + /* Allocate memory (2bit per block) and clear the memory bad block table */ + this->bbt = kzalloc(len, GFP_KERNEL); if (!this->bbt) { - printk (KERN_ERR "nand_scan_bbt: Out of memory\n"); + printk(KERN_ERR "nand_scan_bbt: Out of memory\n"); return -ENOMEM; } - /* Clear the memory bad block table */ - memset (this->bbt, 0x00, len); /* If no primary table decriptor is given, scan the device * to build a memory based bad block table */ - if (!td) - return nand_memory_bbt(mtd, bd); + if (!td) { + if ((res = nand_memory_bbt(mtd, bd))) { + printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n"); + kfree(this->bbt); + this->bbt = NULL; + } + return res; + } /* Allocate a temporary buffer for one eraseblock incl. oob */ len = (1 << this->bbt_erase_shift); len += (len >> this->page_shift) * mtd->oobsize; - buf = kmalloc (len, GFP_KERNEL); + buf = vmalloc(len); if (!buf) { - printk (KERN_ERR "nand_bbt: Out of memory\n"); - kfree (this->bbt); + printk(KERN_ERR "nand_bbt: Out of memory\n"); + kfree(this->bbt); this->bbt = NULL; return -ENOMEM; } /* Is the bbt at a given page ? */ if (td->options & NAND_BBT_ABSPAGE) { - res = read_abs_bbts (mtd, buf, td, md); + res = read_abs_bbts(mtd, buf, td, md); } else { /* Search the bad block table using a pattern in oob */ - res = search_read_bbts (mtd, buf, td, md); + res = search_read_bbts(mtd, buf, td, md); } if (res) - res = check_create (mtd, buf, bd); + res = check_create(mtd, buf, bd); /* Prevent the bbt regions from erasing / writing */ - mark_bbt_region (mtd, td); + mark_bbt_region(mtd, td); if (md) - mark_bbt_region (mtd, md); + mark_bbt_region(mtd, md); - kfree (buf); + vfree(buf); return res; } - /** * nand_update_bbt - [NAND Interface] update bad block table(s) * @mtd: MTD device structure @@ -847,7 +1031,7 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) * * The function updates the bad block table(s) */ -int nand_update_bbt (struct mtd_info *mtd, loff_t offs) +int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { struct nand_chip *this = mtd->priv; int len, res = 0, writeops = 0; @@ -863,9 +1047,9 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) /* Allocate a temporary buffer for one eraseblock incl. oob */ len = (1 << this->bbt_erase_shift); len += (len >> this->page_shift) * mtd->oobsize; - buf = kmalloc (len, GFP_KERNEL); + buf = kmalloc(len, GFP_KERNEL); if (!buf) { - printk (KERN_ERR "nand_update_bbt: Out of memory\n"); + printk(KERN_ERR "nand_update_bbt: Out of memory\n"); return -ENOMEM; } @@ -873,7 +1057,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) /* Do we have a bbt per chip ? */ if (td->options & NAND_BBT_PERCHIP) { - chip = (int) (offs >> this->chip_shift); + chip = (int)(offs >> this->chip_shift); chipsel = chip; } else { chip = 0; @@ -886,29 +1070,26 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs) /* Write the bad block table to the device ? */ if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { - res = write_bbt (mtd, buf, td, md, chipsel); + res = write_bbt(mtd, buf, td, md, chipsel); if (res < 0) goto out; } /* Write the mirror bad block table to the device ? */ if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { - res = write_bbt (mtd, buf, md, td, chipsel); + res = write_bbt(mtd, buf, md, td, chipsel); } -out: - kfree (buf); + out: + kfree(buf); return res; } /* Define some generic bad / good block scan pattern which are used - * while scanning a device for factory marked good / bad blocks - * - * The memory based patterns just - */ + * while scanning a device for factory marked good / bad blocks. */ static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static struct nand_bbt_descr smallpage_memorybased = { - .options = 0, + .options = NAND_BBT_SCAN2NDPAGE, .offs = 5, .len = 1, .pattern = scan_ff_pattern @@ -922,14 +1103,14 @@ static struct nand_bbt_descr largepage_memorybased = { }; static struct nand_bbt_descr smallpage_flashbased = { - .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .options = NAND_BBT_SCAN2NDPAGE, .offs = 5, .len = 1, .pattern = scan_ff_pattern }; static struct nand_bbt_descr largepage_flashbased = { - .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, + .options = NAND_BBT_SCAN2NDPAGE, .offs = 0, .len = 2, .pattern = scan_ff_pattern @@ -977,7 +1158,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { * support for the device and calls the nand_scan_bbt function * */ -int nand_default_bbt (struct mtd_info *mtd) +int nand_default_bbt(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; @@ -987,7 +1168,7 @@ int nand_default_bbt (struct mtd_info *mtd) * of the good / bad information, so we _must_ store * this information in a good / bad table during * startup - */ + */ if (this->options & NAND_IS_AND) { /* Use the default pattern descriptors */ if (!this->bbt_td) { @@ -995,10 +1176,9 @@ int nand_default_bbt (struct mtd_info *mtd) this->bbt_md = &bbt_mirror_descr; } this->options |= NAND_USE_FLASH_BBT; - return nand_scan_bbt (mtd, &agand_flashbased); + return nand_scan_bbt(mtd, &agand_flashbased); } - /* Is a flash based bad block table requested ? */ if (this->options & NAND_USE_FLASH_BBT) { /* Use the default pattern descriptors */ @@ -1007,18 +1187,17 @@ int nand_default_bbt (struct mtd_info *mtd) this->bbt_md = &bbt_mirror_descr; } if (!this->badblock_pattern) { - this->badblock_pattern = (mtd->oobblock > 512) ? - &largepage_flashbased : &smallpage_flashbased; + this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased; } } else { this->bbt_td = NULL; this->bbt_md = NULL; if (!this->badblock_pattern) { - this->badblock_pattern = (mtd->oobblock > 512) ? - &largepage_memorybased : &smallpage_memorybased; + this->badblock_pattern = (mtd->writesize > 512) ? + &largepage_memorybased : &smallpage_memorybased; } } - return nand_scan_bbt (mtd, this->badblock_pattern); + return nand_scan_bbt(mtd, this->badblock_pattern); } /** @@ -1027,26 +1206,35 @@ int nand_default_bbt (struct mtd_info *mtd) * @offs: offset in the device * @allowbbt: allow access to bad block table region * - */ -int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt) +*/ +int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) { struct nand_chip *this = mtd->priv; int block; - uint8_t res; + uint8_t res; /* Get block number * 2 */ - block = (int) (offs >> (this->bbt_erase_shift - 1)); + block = (int)(offs >> (this->bbt_erase_shift - 1)); res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; MTDDEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: " "(block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1); switch ((int)res) { - case 0x00: return 0; - case 0x01: return 1; - case 0x02: return allowbbt ? 0 : 1; + case 0x00: + return 0; + case 0x01: + return 1; + case 0x02: + return allowbbt ? 0 : 1; } return 1; } +/* XXX U-BOOT XXX */ +#if 0 +EXPORT_SYMBOL(nand_scan_bbt); +EXPORT_SYMBOL(nand_default_bbt); +#endif + #endif diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 4c532b0794e..e1d5154db22 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -7,7 +7,9 @@ * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) * Toshiba America Electronics Components, Inc. * - * $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ + * Copyright (C) 2006 Thomas Gleixner + * + * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $ * * This file is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -39,6 +41,14 @@ #if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) +/* XXX U-BOOT XXX */ +#if 0 +#include +#include +#include +#include +#endif + #include /* @@ -128,6 +138,10 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, return 0; } +/* XXX U-BOOT XXX */ +#if 0 +EXPORT_SYMBOL(nand_calculate_ecc); +#endif #endif /* CONFIG_NAND_SPL */ static inline int countbits(uint32_t byte) @@ -197,4 +211,9 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, return -1; } +/* XXX U-BOOT XXX */ +#if 0 +EXPORT_SYMBOL(nand_correct_data); +#endif + #endif diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 73634903952..f8b96cf025d 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -2,8 +2,8 @@ * drivers/mtd/nandids.c * * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) - * - * $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 gleixner Exp $ + * + * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -16,7 +16,6 @@ #if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) #include - /* * Chip ID list * @@ -29,13 +28,15 @@ * 512 512 Byte page size */ struct nand_flash_dev nand_flash_ids[] = { + +#ifdef CONFIG_MTD_NAND_MUSEUM_IDS {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, - {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, @@ -44,6 +45,7 @@ struct nand_flash_dev nand_flash_ids[] = { {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, +#endif {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, @@ -61,52 +63,72 @@ struct nand_flash_dev nand_flash_ids[] = { {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, + {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, + {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, - /* These are the new chips with large page size. The pagesize - * and the erasesize is determined from the extended id bytes - */ + /* + * These are the new chips with large page size. The pagesize and the + * erasesize is determined from the extended id bytes + */ +#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR) +#define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16) + + /*512 Megabit */ + {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS}, + {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS}, + {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16}, + {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16}, + /* 1 Gigabit */ - {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS}, + {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, LP_OPTIONS}, + {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16}, + {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16}, /* 2 Gigabit */ - {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS}, + {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, LP_OPTIONS}, + {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, LP_OPTIONS16}, + {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, LP_OPTIONS16}, /* 4 Gigabit */ - {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, LP_OPTIONS}, + {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, LP_OPTIONS}, + {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, LP_OPTIONS16}, + {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, LP_OPTIONS16}, /* 8 Gigabit */ - {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, + {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS}, + {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS}, + {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16}, + {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16}, /* 16 Gigabit */ - {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, - {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, - - /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! - * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes - * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 - * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go - * There are more speed improvements for reads and writes possible, but not implemented now + {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS}, + {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS}, + {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, + {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, + + /* + * Renesas AND 1 Gigabit. Those chips do not support extended id and + * have a strange page/block layout ! The chosen minimum erasesize is + * 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page + * planes 1 block = 2 pages, but due to plane arrangement the blocks + * 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 Anyway JFFS2 would + * increase the eraseblock size so we chose a combined one which can be + * erased in one go There are more speed improvements for reads and + * writes possible, but not implemented now */ - {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, + {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, + NAND_IS_AND | NAND_NO_AUTOINCR |NAND_NO_READRDY | NAND_4PAGE_ARRAY | + BBT_AUTO_REFRESH + }, {NULL,} }; @@ -121,6 +143,7 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_NATIONAL, "National"}, {NAND_MFR_RENESAS, "Renesas"}, {NAND_MFR_STMICRO, "ST Micro"}, + {NAND_MFR_HYNIX, "Hynix"}, {NAND_MFR_MICRON, "Micron"}, {0x0, "Unknown"} }; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 828cc338adb..78e70cc807d 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -39,6 +39,9 @@ #include #include + +#include +#include #include #include @@ -69,71 +72,33 @@ static int nand_block_bad_scrub(struct mtd_info *mtd, loff_t ofs, int getchip) int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) { struct jffs2_unknown_node cleanmarker; - int clmpos = 0; - int clmlen = 8; erase_info_t erase; ulong erase_length; - int isNAND; int bbtest = 1; int result; int percent_complete = -1; int (*nand_block_bad_old)(struct mtd_info *, loff_t, int) = NULL; const char *mtd_device = meminfo->name; + struct mtd_oob_ops oob_opts; + struct nand_chip *chip = meminfo->priv; + uint8_t buf[64]; + memset(buf, 0, sizeof(buf)); memset(&erase, 0, sizeof(erase)); + memset(&oob_opts, 0, sizeof(oob_opts)); erase.mtd = meminfo; erase.len = meminfo->erasesize; erase.addr = opts->offset; erase_length = opts->length; - isNAND = meminfo->type == MTD_NANDFLASH ? 1 : 0; - if (opts->jffs2) { - cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); - cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); - if (isNAND) { - struct nand_oobinfo *oobinfo = &meminfo->oobinfo; - - /* check for autoplacement */ - if (oobinfo->useecc == MTD_NANDECC_AUTOPLACE) { - /* get the position of the free bytes */ - if (!oobinfo->oobfree[0][1]) { - printf(" Eeep. Autoplacement selected " - "and no empty space in oob\n"); - return -1; - } - clmpos = oobinfo->oobfree[0][0]; - clmlen = oobinfo->oobfree[0][1]; - if (clmlen > 8) - clmlen = 8; - } else { - /* legacy mode */ - switch (meminfo->oobsize) { - case 8: - clmpos = 6; - clmlen = 2; - break; - case 16: - clmpos = 8; - clmlen = 8; - break; - case 64: - clmpos = 16; - clmlen = 8; - break; - } - } - - cleanmarker.totlen = cpu_to_je32(8); - } else { - cleanmarker.totlen = - cpu_to_je32(sizeof(struct jffs2_unknown_node)); - } - cleanmarker.hdr_crc = cpu_to_je32( - crc32_no_comp(0, (unsigned char *) &cleanmarker, - sizeof(struct jffs2_unknown_node) - 4)); - } + cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK); + cleanmarker.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER); + cleanmarker.totlen = cpu_to_je32(8); + cleanmarker.hdr_crc = cpu_to_je32( + crc32_no_comp(0, (unsigned char *) &cleanmarker, + sizeof(struct jffs2_unknown_node) - 4)); /* scrub option allows to erase badblock. To prevent internal * check from erase() method, set block check method to dummy @@ -163,7 +128,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) for (; erase.addr < opts->offset + erase_length; erase.addr += meminfo->erasesize) { - + WATCHDOG_RESET (); if (!opts->scrub && bbtest) { @@ -194,25 +159,21 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) /* format for JFFS2 ? */ if (opts->jffs2) { - /* write cleanmarker */ - if (isNAND) { - size_t written; - result = meminfo->write_oob(meminfo, - erase.addr + clmpos, - clmlen, - &written, - (unsigned char *) - &cleanmarker); - if (result != 0) { - printf("\n%s: MTD writeoob failure: %d\n", - mtd_device, result); - continue; - } - } else { - printf("\n%s: this erase routine only supports" - " NAND devices!\n", - mtd_device); + chip->ops.len = chip->ops.ooblen = 64; + chip->ops.datbuf = NULL; + chip->ops.oobbuf = buf; + chip->ops.ooboffs = chip->badblockpos & ~0x01; + + result = meminfo->write_oob(meminfo, + erase.addr + meminfo->oobsize, + &chip->ops); + if (result != 0) { + printf("\n%s: MTD writeoob failure: %d\n", + mtd_device, result); + continue; } + else + printf("%s: MTD writeoob at 0x%08x\n",mtd_device, erase.addr + meminfo->oobsize ); } if (!opts->quiet) { @@ -232,11 +193,11 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) percent_complete = percent; printf("\rErasing at 0x%x -- %3d%% complete.", - erase.addr, percent); + erase.addr, percent); if (opts->jffs2 && result == 0) - printf(" Cleanmarker written at 0x%x.", - erase.addr); + printf(" Cleanmarker written at 0x%x.", + erase.addr); } } } @@ -253,6 +214,9 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) return 0; } +/* XXX U-BOOT XXX */ +#if 0 + #define MAX_PAGE_SIZE 2048 #define MAX_OOB_SIZE 64 @@ -263,26 +227,189 @@ static unsigned char data_buf[MAX_PAGE_SIZE]; static unsigned char oob_buf[MAX_OOB_SIZE]; /* OOB layouts to pass into the kernel as default */ -static struct nand_oobinfo none_oobinfo = { +static struct nand_ecclayout none_ecclayout = { .useecc = MTD_NANDECC_OFF, }; -static struct nand_oobinfo jffs2_oobinfo = { +static struct nand_ecclayout jffs2_ecclayout = { .useecc = MTD_NANDECC_PLACE, .eccbytes = 6, .eccpos = { 0, 1, 2, 3, 6, 7 } }; -static struct nand_oobinfo yaffs_oobinfo = { +static struct nand_ecclayout yaffs_ecclayout = { .useecc = MTD_NANDECC_PLACE, .eccbytes = 6, .eccpos = { 8, 9, 10, 13, 14, 15} }; -static struct nand_oobinfo autoplace_oobinfo = { +static struct nand_ecclayout autoplace_ecclayout = { .useecc = MTD_NANDECC_AUTOPLACE }; +#endif + +/** + * nand_fill_oob - [Internal] Transfer client buffer to oob + * @chip: nand chip structure + * @oob: oob data buffer + * @ops: oob ops structure + * + * Copied from nand_base.c + */ +static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, + struct mtd_oob_ops *ops) +{ + size_t len = ops->ooblen; + + switch(ops->mode) { + + case MTD_OOB_PLACE: + case MTD_OOB_RAW: + memcpy(chip->oob_poi + ops->ooboffs, oob, len); + return oob + len; + + case MTD_OOB_AUTO: { + struct nand_oobfree *free = chip->ecc.layout->oobfree; + uint32_t boffs = 0, woffs = ops->ooboffs; + size_t bytes = 0; + + for(; free->length && len; free++, len -= bytes) { + /* Write request not from offset 0 ? */ + if (unlikely(woffs)) { + if (woffs >= free->length) { + woffs -= free->length; + continue; + } + boffs = free->offset + woffs; + bytes = min_t(size_t, len, + (free->length - woffs)); + woffs = 0; + } else { + bytes = min_t(size_t, len, free->length); + boffs = free->offset; + } + memcpy(chip->oob_poi + boffs, oob, bytes); + oob += bytes; + } + return oob; + } + default: + BUG(); + } + return NULL; +} + +#define NOTALIGNED(x) (x & (chip->subpagesize - 1)) != 0 + + +/* copied from nand_base.c: nand_do_write_ops() + * Only very small changes + */ +int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops) +{ + int chipnr, realpage, page, blockmask, column; + struct nand_chip *chip = mtd->priv; + uint32_t writelen = ops->len; + uint8_t *oob = ops->oobbuf; + uint8_t *buf = ops->datbuf; + int ret, subpage; + + ops->retlen = 0; + if (!writelen) + return 0; + + printk("nand_write_opts: to: 0x%08x, ops->len: 0x%08x\n", to, ops->len); + + /* reject writes, which are not page aligned */ + if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { + printk(KERN_NOTICE "nand_write: " + "Attempt to write not page aligned data\n"); + return -EINVAL; + } + + column = to & (mtd->writesize - 1); + subpage = column || (writelen & (mtd->writesize - 1)); + + if (subpage && oob) { + printk(KERN_NOTICE "nand_write: " + "Attempt to write oob to subpage\n"); + return -EINVAL; + } + + chipnr = (int)(to >> chip->chip_shift); + chip->select_chip(mtd, chipnr); + + /* XXX U-BOOT XXX */ +#if 0 + /* Check, if it is write protected */ + if (nand_check_wp(mtd)) + return -EIO; +#endif + + realpage = (int)(to >> chip->page_shift); + page = realpage & chip->pagemask; + blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; + + /* Invalidate the page cache, when we write to the cached page */ + if (to <= (chip->pagebuf << chip->page_shift) && + (chip->pagebuf << chip->page_shift) < (to + ops->len)) + chip->pagebuf = -1; + + /* If we're not given explicit OOB data, let it be 0xFF */ + if (likely(!oob)) { + printf("!oob, writing %d bytes with 0xff to chip->oob_poi (0x%08x)\n", mtd->oobsize, chip->oob_poi); + memset(chip->oob_poi, 0xff, mtd->oobsize); + } + + while(1) { + int bytes = mtd->writesize; + int cached = writelen > bytes && page != blockmask; + uint8_t *wbuf = buf; + + /* Partial page write ? */ + if (unlikely(column || writelen < (mtd->writesize - 1))) { + cached = 0; + bytes = min_t(int, bytes - column, (int) writelen); + chip->pagebuf = -1; + memset(chip->buffers->databuf, 0xff, mtd->writesize); + memcpy(&chip->buffers->databuf[column], buf, bytes); + wbuf = chip->buffers->databuf; + } + + if (unlikely(oob)) + oob = nand_fill_oob(chip, oob, ops); + + ret = chip->write_page(mtd, chip, wbuf, page, cached, + (ops->mode == MTD_OOB_RAW)); + if (ret) + break; + + writelen -= bytes; + if (!writelen) + break; + + column = 0; + buf += bytes; + realpage++; + + page = realpage & chip->pagemask; + /* Check, if we cross a chip boundary */ + if (!page) { + chipnr++; + chip->select_chip(mtd, -1); + chip->select_chip(mtd, chipnr); + } + } + + ops->retlen = ops->len - writelen; + if (unlikely(oob)) + ops->oobretlen = ops->ooblen; + return ret; +} + +/* XXX U-BOOT XXX */ +#if 0 /** * nand_write_opts: - write image to NAND flash with support for various options * @@ -301,9 +428,9 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) int blockstart = -1; loff_t offs; int readlen; - int oobinfochanged = 0; + int ecclayoutchanged = 0; int percent_complete = -1; - struct nand_oobinfo old_oobinfo; + struct nand_ecclayout old_ecclayout; ulong mtdoffset = opts->offset; ulong erasesize_blockalign; u_char *buffer = opts->buffer; @@ -324,35 +451,35 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) } /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512) - && !(meminfo->oobsize == 8 && meminfo->oobblock == 256) - && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) { + if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) + && !(meminfo->oobsize == 8 && meminfo->writesize == 256) + && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { printf("Unknown flash (not normal NAND)\n"); return -1; } /* read the current oob info */ - memcpy(&old_oobinfo, &meminfo->oobinfo, sizeof(old_oobinfo)); + memcpy(&old_ecclayout, &meminfo->ecclayout, sizeof(old_ecclayout)); /* write without ecc? */ if (opts->noecc) { - memcpy(&meminfo->oobinfo, &none_oobinfo, - sizeof(meminfo->oobinfo)); - oobinfochanged = 1; + memcpy(&meminfo->ecclayout, &none_ecclayout, + sizeof(meminfo->ecclayout)); + ecclayoutchanged = 1; } /* autoplace ECC? */ - if (opts->autoplace && (old_oobinfo.useecc != MTD_NANDECC_AUTOPLACE)) { + if (opts->autoplace && (old_ecclayout.useecc != MTD_NANDECC_AUTOPLACE)) { - memcpy(&meminfo->oobinfo, &autoplace_oobinfo, - sizeof(meminfo->oobinfo)); - oobinfochanged = 1; + memcpy(&meminfo->ecclayout, &autoplace_ecclayout, + sizeof(meminfo->ecclayout)); + ecclayoutchanged = 1; } /* force OOB layout for jffs2 or yaffs? */ if (opts->forcejffs2 || opts->forceyaffs) { - struct nand_oobinfo *oobsel = - opts->forcejffs2 ? &jffs2_oobinfo : &yaffs_oobinfo; + struct nand_ecclayout *oobsel = + opts->forcejffs2 ? &jffs2_ecclayout : &yaffs_ecclayout; if (meminfo->oobsize == 8) { if (opts->forceyaffs) { @@ -361,15 +488,15 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) goto restoreoob; } /* Adjust number of ecc bytes */ - jffs2_oobinfo.eccbytes = 3; + jffs2_ecclayout.eccbytes = 3; } - memcpy(&meminfo->oobinfo, oobsel, sizeof(meminfo->oobinfo)); + memcpy(&meminfo->ecclayout, oobsel, sizeof(meminfo->ecclayout)); } /* get image length */ imglen = opts->length; - pagelen = meminfo->oobblock + pagelen = meminfo->writesize + ((opts->writeoob != 0) ? meminfo->oobsize : 0); /* check, if file is pagealigned */ @@ -379,11 +506,11 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) } /* check, if length fits into device */ - if (((imglen / pagelen) * meminfo->oobblock) + if (((imglen / pagelen) * meminfo->writesize) > (meminfo->size - opts->offset)) { printf("Image %d bytes, NAND page %d bytes, " "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->oobblock, meminfo->size); + imglen, pagelen, meminfo->writesize, meminfo->size); printf("Input block does not fit into device\n"); goto restoreoob; } @@ -437,11 +564,11 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) } while (offs < blockstart + erasesize_blockalign); } - readlen = meminfo->oobblock; + readlen = meminfo->writesize; if (opts->pad && (imglen < readlen)) { readlen = imglen; memset(data_buf + readlen, 0xff, - meminfo->oobblock - readlen); + meminfo->writesize - readlen); } /* read page data from input memory buffer */ @@ -474,7 +601,7 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) /* write out the page data */ result = meminfo->write(meminfo, mtdoffset, - meminfo->oobblock, + meminfo->writesize, &written, (unsigned char *) &data_buf); @@ -505,16 +632,16 @@ int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) } } - mtdoffset += meminfo->oobblock; + mtdoffset += meminfo->writesize; } if (!opts->quiet) printf("\n"); restoreoob: - if (oobinfochanged) { - memcpy(&meminfo->oobinfo, &old_oobinfo, - sizeof(meminfo->oobinfo)); + if (ecclayoutchanged) { + memcpy(&meminfo->ecclayout, &old_ecclayout, + sizeof(meminfo->ecclayout)); } if (imglen > 0) { @@ -548,22 +675,22 @@ int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) int result; /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->oobblock == 512) - && !(meminfo->oobsize == 8 && meminfo->oobblock == 256) - && !(meminfo->oobsize == 64 && meminfo->oobblock == 2048)) { + if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) + && !(meminfo->oobsize == 8 && meminfo->writesize == 256) + && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { printf("Unknown flash (not normal NAND)\n"); return -1; } - pagelen = meminfo->oobblock + pagelen = meminfo->writesize + ((opts->readoob != 0) ? meminfo->oobsize : 0); /* check, if length is not larger than device */ - if (((imglen / pagelen) * meminfo->oobblock) + if (((imglen / pagelen) * meminfo->writesize) > (meminfo->size - opts->offset)) { printf("Image %d bytes, NAND page %d bytes, " "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->oobblock, meminfo->size); + imglen, pagelen, meminfo->writesize, meminfo->size); printf("Input block is larger than device\n"); return -1; } @@ -621,7 +748,7 @@ int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) /* read page data to memory buffer */ result = meminfo->read(meminfo, mtdoffset, - meminfo->oobblock, + meminfo->writesize, &readlen, (unsigned char *) &data_buf); @@ -685,7 +812,7 @@ int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) } } - mtdoffset += meminfo->oobblock; + mtdoffset += meminfo->writesize; } if (!opts->quiet) @@ -699,7 +826,10 @@ int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) /* return happy */ return 0; } +#endif +/* XXX U-BOOT XXX */ +#if 0 /****************************************************************************** * Support for locking / unlocking operations of some NAND devices *****************************************************************************/ @@ -784,7 +914,7 @@ int nand_get_lock_status(nand_info_t *meminfo, ulong offset) this->select_chip(meminfo, chipnr); - if ((offset & (meminfo->oobblock - 1)) != 0) { + if ((offset & (meminfo->writesize - 1)) != 0) { printf ("nand_get_lock_status: " "Start address must be beginning of " "nand page!\n"); @@ -813,7 +943,7 @@ int nand_get_lock_status(nand_info_t *meminfo, ulong offset) * @param meminfo nand mtd instance * @param start start byte address * @param length number of bytes to unlock (must be a multiple of - * page size nand->oobblock) + * page size nand->writesize) * * @return 0 on success, -1 in case of error */ @@ -839,14 +969,14 @@ int nand_unlock(nand_info_t *meminfo, ulong start, ulong length) goto out; } - if ((start & (meminfo->oobblock - 1)) != 0) { + if ((start & (meminfo->writesize - 1)) != 0) { printf ("nand_unlock: Start address must be beginning of " "nand page!\n"); ret = -1; goto out; } - if (length == 0 || (length & (meminfo->oobblock - 1)) != 0) { + if (length == 0 || (length & (meminfo->writesize - 1)) != 0) { printf ("nand_unlock: Length must be a multiple of nand page " "size!\n"); ret = -1; @@ -875,5 +1005,6 @@ int nand_unlock(nand_info_t *meminfo, ulong start, ulong length) this->select_chip(meminfo, -1); return ret; } +#endif #endif diff --git a/include/common.h b/include/common.h index 2fcb1fd379f..06ed27806ff 100644 --- a/include/common.h +++ b/include/common.h @@ -119,11 +119,13 @@ typedef volatile unsigned char vu_char; #define debugX(level,fmt,args...) #endif /* DEBUG */ +#ifndef BUG #define BUG() do { \ printf("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ panic("BUG!"); \ } while (0) #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0) +#endif /* BUG */ typedef void (interrupt_handler_t)(void *); diff --git a/include/linux/err.h b/include/linux/err.h new file mode 100644 index 00000000000..4e08c4fe685 --- /dev/null +++ b/include/linux/err.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_ERR_H +#define _LINUX_ERR_H + +/* XXX U-BOOT XXX */ +#if 0 +#include +#else +#include +#endif + +#include + + +/* + * Kernel pointers have redundant information, so we can use a + * scheme where we can return either an error code or a dentry + * pointer with the same return value. + * + * This should be a per-architecture thing, to allow different + * error and pointer decisions. + */ +#define MAX_ERRNO 4095 + +#ifndef __ASSEMBLY__ + +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) + +static inline void *ERR_PTR(long error) +{ + return (void *) error; +} + +static inline long PTR_ERR(const void *ptr) +{ + return (long) ptr; +} + +static inline long IS_ERR(const void *ptr) +{ + return IS_ERR_VALUE((unsigned long)ptr); +} + +#endif + +#endif /* _LINUX_ERR_H */ diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h new file mode 100644 index 00000000000..d1ded51d7c7 --- /dev/null +++ b/include/linux/mtd/blktrans.h @@ -0,0 +1,81 @@ +/* + * $Id: blktrans.h,v 1.6 2005/11/07 11:14:54 gleixner Exp $ + * + * (C) 2003 David Woodhouse + * + * Interface to Linux block layer for MTD 'translation layers'. + * + */ + +#ifndef __MTD_TRANS_H__ +#define __MTD_TRANS_H__ + +/* XXX U-BOOT XXX */ +#if 0 +#include +#else +#include +#endif + +struct hd_geometry; +struct mtd_info; +struct mtd_blktrans_ops; +struct file; +struct inode; + +struct mtd_blktrans_dev { + struct mtd_blktrans_ops *tr; + struct list_head list; + struct mtd_info *mtd; +/* XXX U-BOOT XXX */ +#if 0 + struct mutex lock; +#endif + int devnum; + unsigned long size; + int readonly; + void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */ +}; + +struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */ + +struct mtd_blktrans_ops { + char *name; + int major; + int part_bits; + int blksize; + int blkshift; + + /* Access functions */ + int (*readsect)(struct mtd_blktrans_dev *dev, + unsigned long block, char *buffer); + int (*writesect)(struct mtd_blktrans_dev *dev, + unsigned long block, char *buffer); + + /* Block layer ioctls */ + int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); + int (*flush)(struct mtd_blktrans_dev *dev); + + /* Called with mtd_table_mutex held; no race with add/remove */ + int (*open)(struct mtd_blktrans_dev *dev); + int (*release)(struct mtd_blktrans_dev *dev); + + /* Called on {de,}registration and on subsequent addition/removal + of devices, with mtd_table_mutex held. */ + void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd); + void (*remove_dev)(struct mtd_blktrans_dev *dev); + + struct list_head devs; + struct list_head list; + struct module *owner; + + struct mtd_blkcore_priv *blkcore_priv; +}; + +extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); +extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); +extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); +extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); + + +#endif /* __MTD_TRANS_H__ */ diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h index fe55087ea93..86a6e43ca9a 100644 --- a/include/linux/mtd/compat.h +++ b/include/linux/mtd/compat.h @@ -18,7 +18,12 @@ #define KERN_DEBUG #define kmalloc(size, flags) malloc(size) -#define kfree(ptr) free(ptr) +#define kzalloc(size, flags) calloc(size, 1) +#define vmalloc(size) malloc(size) +#define kfree(ptr) free(ptr) +#define vfree(ptr) free(ptr) + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) /* * ..and if you can't take the strict diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h index 29f6767865f..12de2845a3b 100644 --- a/include/linux/mtd/doc2000.h +++ b/include/linux/mtd/doc2000.h @@ -1,15 +1,23 @@ - -/* Linux driver for Disk-On-Chip 2000 */ -/* (c) 1999 Machine Vision Holdings, Inc. */ -/* Author: David Woodhouse */ -/* $Id: doc2000.h,v 1.15 2001/09/19 00:22:15 dwmw2 Exp $ */ +/* + * Linux driver for Disk-On-Chip devices + * + * Copyright (C) 1999 Machine Vision Holdings, Inc. + * Copyright (C) 2001-2003 David Woodhouse + * Copyright (C) 2002-2003 Greg Ungerer + * Copyright (C) 2002-2003 SnapGear Inc + * + * $Id: doc2000.h,v 1.25 2005/11/07 11:14:54 gleixner Exp $ + * + * Released under GPL + */ #ifndef __MTD_DOC2000_H__ #define __MTD_DOC2000_H__ -struct DiskOnChip; - -#include +#include +#if 0 +#include +#endif #define DoC_Sig1 0 #define DoC_Sig2 1 @@ -40,10 +48,58 @@ struct DiskOnChip; #define DoC_Mil_CDSN_IO 0x0800 #define DoC_2k_CDSN_IO 0x1800 -#define ReadDOC_(adr, reg) ((volatile unsigned char)(*(volatile __u8 *)(((unsigned long)adr)+((reg))))) -#define WriteDOC_(d, adr, reg) do{ *(volatile __u8 *)(((unsigned long)adr)+((reg))) = (__u8)d; eieio();} while(0) - -#define DOC_IOREMAP_LEN 0x4000 +#define DoC_Mplus_NOP 0x1002 +#define DoC_Mplus_AliasResolution 0x1004 +#define DoC_Mplus_DOCControl 0x1006 +#define DoC_Mplus_AccessStatus 0x1008 +#define DoC_Mplus_DeviceSelect 0x1008 +#define DoC_Mplus_Configuration 0x100a +#define DoC_Mplus_OutputControl 0x100c +#define DoC_Mplus_FlashControl 0x1020 +#define DoC_Mplus_FlashSelect 0x1022 +#define DoC_Mplus_FlashCmd 0x1024 +#define DoC_Mplus_FlashAddress 0x1026 +#define DoC_Mplus_FlashData0 0x1028 +#define DoC_Mplus_FlashData1 0x1029 +#define DoC_Mplus_ReadPipeInit 0x102a +#define DoC_Mplus_LastDataRead 0x102c +#define DoC_Mplus_LastDataRead1 0x102d +#define DoC_Mplus_WritePipeTerm 0x102e +#define DoC_Mplus_ECCSyndrome0 0x1040 +#define DoC_Mplus_ECCSyndrome1 0x1041 +#define DoC_Mplus_ECCSyndrome2 0x1042 +#define DoC_Mplus_ECCSyndrome3 0x1043 +#define DoC_Mplus_ECCSyndrome4 0x1044 +#define DoC_Mplus_ECCSyndrome5 0x1045 +#define DoC_Mplus_ECCConf 0x1046 +#define DoC_Mplus_Toggle 0x1046 +#define DoC_Mplus_DownloadStatus 0x1074 +#define DoC_Mplus_CtrlConfirm 0x1076 +#define DoC_Mplus_Power 0x1fff + +/* How to access the device? + * On ARM, it'll be mmap'd directly with 32-bit wide accesses. + * On PPC, it's mmap'd and 16-bit wide. + * Others use readb/writeb + */ +#if defined(__arm__) +#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) +#define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) +#define DOC_IOREMAP_LEN 0x8000 +#elif defined(__ppc__) +#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) +#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) +#define DOC_IOREMAP_LEN 0x4000 +#else +#define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) +#define WriteDOC_(d, adr, reg) writeb(d, (void __iomem *)(adr) + (reg)) +#define DOC_IOREMAP_LEN 0x2000 + +#endif + +#if defined(__i386__) || defined(__x86_64__) +#define USE_MEMCPY +#endif /* These are provided to directly use the DoC_xxx defines */ #define ReadDOC(adr, reg) ReadDOC_(adr,DoC_##reg) @@ -54,14 +110,21 @@ struct DiskOnChip; #define DOC_MODE_RESERVED1 2 #define DOC_MODE_RESERVED2 3 -#define DOC_MODE_MDWREN 4 #define DOC_MODE_CLR_ERR 0x80 +#define DOC_MODE_RST_LAT 0x10 +#define DOC_MODE_BDECT 0x08 +#define DOC_MODE_MDWREN 0x04 -#define DOC_ChipID_UNKNOWN 0x00 #define DOC_ChipID_Doc2k 0x20 +#define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */ #define DOC_ChipID_DocMil 0x30 +#define DOC_ChipID_DocMilPlus32 0x40 +#define DOC_ChipID_DocMilPlus16 0x41 #define CDSN_CTRL_FR_B 0x80 +#define CDSN_CTRL_FR_B0 0x40 +#define CDSN_CTRL_FR_B1 0x80 + #define CDSN_CTRL_ECC_IO 0x20 #define CDSN_CTRL_FLASH_IO 0x10 #define CDSN_CTRL_WP 0x08 @@ -77,41 +140,47 @@ struct DiskOnChip; #define DOC_ECC_RESV 0x02 #define DOC_ECC_IGNORE 0x01 +#define DOC_FLASH_CE 0x80 +#define DOC_FLASH_WP 0x40 +#define DOC_FLASH_BANK 0x02 + /* We have to also set the reserved bit 1 for enable */ #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV) #define DOC_ECC_DIS (DOC_ECC_RESV) +struct Nand { + char floor, chip; + unsigned long curadr; + unsigned char curmode; + /* Also some erase/write/pipeline info when we get that far */ +}; + #define MAX_FLOORS 4 #define MAX_CHIPS 4 -#define MAX_FLOORS_MIL 4 +#define MAX_FLOORS_MIL 1 #define MAX_CHIPS_MIL 1 +#define MAX_FLOORS_MPLUS 2 +#define MAX_CHIPS_MPLUS 1 + #define ADDR_COLUMN 1 #define ADDR_PAGE 2 #define ADDR_COLUMN_PAGE 3 -struct Nand { - char floor, chip; - unsigned long curadr; - unsigned char curmode; - /* Also some erase/write/pipeline info when we get that far */ -}; - struct DiskOnChip { unsigned long physadr; - unsigned long virtadr; + void __iomem *virtadr; unsigned long totlen; - char* name; - char ChipID; /* Type of DiskOnChip */ + unsigned char ChipID; /* Type of DiskOnChip */ int ioreg; - char* chips_name; unsigned long mfr; /* Flash IDs - only one type of flash per device */ unsigned long id; int chipshift; char page256; char pageadrlen; + char interleave; /* Internal interleaving - Millennium Plus style */ unsigned long erasesize; int curfloor; @@ -119,98 +188,22 @@ struct DiskOnChip { int numchips; struct Nand *chips; - - int nftl_found; - struct NFTLrecord nftl; + struct mtd_info *nextdoc; +/* XXX U-BOOT XXX */ +#if 0 + struct mutex lock; +#endif }; -#define SECTORSIZE 512 - -/* Return codes from doc_write(), doc_read(), and doc_erase(). - */ -#define DOC_OK 0 -#define DOC_EIO 1 -#define DOC_EINVAL 2 -#define DOC_EECC 3 -#define DOC_ETIMEOUT 4 - -/* - * Function Prototypes - */ int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); -int doc_rw(struct DiskOnChip* this, int cmd, loff_t from, size_t len, - size_t *retlen, u_char *buf); -int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, - size_t *retlen, u_char *buf, u_char *eccbuf); -int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len, - size_t *retlen, const u_char *buf, u_char *eccbuf); -int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len, - size_t *retlen, u_char *buf); -int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len, - size_t *retlen, const u_char *buf); -int doc_erase (struct DiskOnChip* this, loff_t ofs, size_t len); - -void doc_probe(unsigned long physadr); - -void doc_print(struct DiskOnChip*); - -/* - * Standard NAND flash commands - */ -#define NAND_CMD_READ0 0 -#define NAND_CMD_READ1 1 -#define NAND_CMD_PAGEPROG 0x10 -#define NAND_CMD_READOOB 0x50 -#define NAND_CMD_ERASE1 0x60 -#define NAND_CMD_STATUS 0x70 -#define NAND_CMD_SEQIN 0x80 -#define NAND_CMD_READID 0x90 -#define NAND_CMD_ERASE2 0xd0 -#define NAND_CMD_RESET 0xff - +/* XXX U-BOOT XXX */ +#if 1 /* * NAND Flash Manufacturer ID Codes */ -#define NAND_MFR_TOSHIBA 0x98 -#define NAND_MFR_SAMSUNG 0xec - -/* - * NAND Flash Device ID Structure - * - * Structure overview: - * - * name - Complete name of device - * - * manufacture_id - manufacturer ID code of device. - * - * model_id - model ID code of device. - * - * chipshift - total number of address bits for the device which - * is used to calculate address offsets and the total - * number of bytes the device is capable of. - * - * page256 - denotes if flash device has 256 byte pages or not. - * - * pageadrlen - number of bytes minus one needed to hold the - * complete address into the flash array. Keep in - * mind that when a read or write is done to a - * specific address, the address is input serially - * 8 bits at a time. This structure member is used - * by the read/write routines as a loop index for - * shifting the address out 8 bits at a time. - * - * erasesize - size of an erase block in the flash device. - */ -struct nand_flash_dev { - char * name; - int manufacture_id; - int model_id; - int chipshift; - char page256; - char pageadrlen; - unsigned long erasesize; - int bus16; -}; +#define NAND_MFR_TOSHIBA 0x98 +#define NAND_MFR_SAMSUNG 0xec +#endif #endif /* __MTD_DOC2000_H__ */ diff --git a/include/linux/mtd/inftl-user.h b/include/linux/mtd/inftl-user.h new file mode 100644 index 00000000000..9b1e2526b45 --- /dev/null +++ b/include/linux/mtd/inftl-user.h @@ -0,0 +1,91 @@ +/* + * $Id: inftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * + * Parts of INFTL headers shared with userspace + * + */ + +#ifndef __MTD_INFTL_USER_H__ +#define __MTD_INFTL_USER_H__ + +#define OSAK_VERSION 0x5120 +#define PERCENTUSED 98 + +#define SECTORSIZE 512 + +/* Block Control Information */ + +struct inftl_bci { + uint8_t ECCsig[6]; + uint8_t Status; + uint8_t Status1; +} __attribute__((packed)); + +struct inftl_unithead1 { + uint16_t virtualUnitNo; + uint16_t prevUnitNo; + uint8_t ANAC; + uint8_t NACs; + uint8_t parityPerField; + uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unithead2 { + uint8_t parityPerField; + uint8_t ANAC; + uint16_t prevUnitNo; + uint16_t virtualUnitNo; + uint8_t NACs; + uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unittail { + uint8_t Reserved[4]; + uint16_t EraseMark; + uint16_t EraseMark1; +} __attribute__((packed)); + +union inftl_uci { + struct inftl_unithead1 a; + struct inftl_unithead2 b; + struct inftl_unittail c; +}; + +struct inftl_oob { + struct inftl_bci b; + union inftl_uci u; +}; + + +/* INFTL Media Header */ + +struct INFTLPartition { + __u32 virtualUnits; + __u32 firstUnit; + __u32 lastUnit; + __u32 flags; + __u32 spareUnits; + __u32 Reserved0; + __u32 Reserved1; +} __attribute__((packed)); + +struct INFTLMediaHeader { + char bootRecordID[8]; + __u32 NoOfBootImageBlocks; + __u32 NoOfBinaryPartitions; + __u32 NoOfBDTLPartitions; + __u32 BlockMultiplierBits; + __u32 FormatFlags; + __u32 OsakVersion; + __u32 PercentUsed; + struct INFTLPartition Partitions[4]; +} __attribute__((packed)); + +/* Partition flag types */ +#define INFTL_BINARY 0x20000000 +#define INFTL_BDTL 0x40000000 +#define INFTL_LAST 0x80000000 + +#endif /* __MTD_INFTL_USER_H__ */ + + diff --git a/include/linux/mtd/jffs2-user.h b/include/linux/mtd/jffs2-user.h new file mode 100644 index 00000000000..d508ef0ae09 --- /dev/null +++ b/include/linux/mtd/jffs2-user.h @@ -0,0 +1,35 @@ +/* + * $Id: jffs2-user.h,v 1.1 2004/05/05 11:57:54 dwmw2 Exp $ + * + * JFFS2 definitions for use in user space only + */ + +#ifndef __JFFS2_USER_H__ +#define __JFFS2_USER_H__ + +/* This file is blessed for inclusion by userspace */ +#include +#include +#include + +#undef cpu_to_je16 +#undef cpu_to_je32 +#undef cpu_to_jemode +#undef je16_to_cpu +#undef je32_to_cpu +#undef jemode_to_cpu + +extern int target_endian; + +#define t16(x) ({ uint16_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); }) +#define t32(x) ({ uint32_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); }) + +#define cpu_to_je16(x) ((jint16_t){t16(x)}) +#define cpu_to_je32(x) ((jint32_t){t32(x)}) +#define cpu_to_jemode(x) ((jmode_t){t32(x)}) + +#define je16_to_cpu(x) (t16((x).v16)) +#define je32_to_cpu(x) (t32((x).v32)) +#define jemode_to_cpu(x) (t32((x).m)) + +#endif /* __JFFS2_USER_H__ */ diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h index 4cebea95979..0ce2099d692 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h @@ -1,5 +1,5 @@ /* - * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ + * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $ * * Portions of MTD ABI definition which are shared by kernel and user space */ @@ -7,6 +7,10 @@ #ifndef __MTD_ABI_H__ #define __MTD_ABI_H__ +#if 1 +#include +#endif + struct erase_info_user { uint32_t start; uint32_t length; @@ -15,7 +19,7 @@ struct erase_info_user { struct mtd_oob_buf { uint32_t start; uint32_t length; - unsigned char *ptr; + unsigned char __user *ptr; }; #define MTD_ABSENT 0 @@ -23,47 +27,41 @@ struct mtd_oob_buf { #define MTD_ROM 2 #define MTD_NORFLASH 3 #define MTD_NANDFLASH 4 -#define MTD_PEROM 5 -#define MTD_OTHER 14 -#define MTD_UNKNOWN 15 - -#define MTD_CLEAR_BITS 1 /* Bits can be cleared (flash) */ -#define MTD_SET_BITS 2 /* Bits can be set */ -#define MTD_ERASEABLE 4 /* Has an erase function */ -#define MTD_WRITEB_WRITEABLE 8 /* Direct IO is possible */ -#define MTD_VOLATILE 16 /* Set for RAMs */ -#define MTD_XIP 32 /* eXecute-In-Place possible */ -#define MTD_OOB 64 /* Out-of-band data (NAND flash) */ -#define MTD_ECC 128 /* Device capable of automatic ECC */ -#define MTD_NO_VIRTBLOCKS 256 /* Virtual blocks not allowed */ - -/* Some common devices / combinations of capabilities */ -#define MTD_CAP_ROM 0 -#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) -#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) -#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) -#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) +#define MTD_DATAFLASH 6 +#define MTD_UBIVOLUME 7 +#define MTD_WRITEABLE 0x400 /* Device is writeable */ +#define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ +#define MTD_NO_ERASE 0x1000 /* No erase necessary */ +#define MTD_STUPID_LOCK 0x2000 /* Always locked after reset */ -/* Types of automatic ECC/Checksum available */ -#define MTD_ECC_NONE 0 /* No automatic ECC available */ -#define MTD_ECC_RS_DiskOnChip 1 /* Automatic ECC on DiskOnChip */ -#define MTD_ECC_SW 2 /* SW ECC for Toshiba & Samsung devices */ +// Some common devices / combinations of capabilities +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE) /* ECC byte placement */ -#define MTD_NANDECC_OFF 0 /* Switch off ECC (Not recommended) */ -#define MTD_NANDECC_PLACE 1 /* Use the given placement in the structure (YAFFS1 legacy mode) */ -#define MTD_NANDECC_AUTOPLACE 2 /* Use the default placement scheme */ -#define MTD_NANDECC_PLACEONLY 3 /* Use the given placement in the structure (Do not store ecc result on read) */ -#define MTD_NANDECC_AUTOPL_USR 4 /* Use the given autoplacement scheme rather than using the default */ +#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme +#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF 0 +#define MTD_OTP_FACTORY 1 +#define MTD_OTP_USER 2 struct mtd_info_user { uint8_t type; uint32_t flags; - uint32_t size; /* Total size of the MTD */ + uint32_t size; // Total size of the MTD uint32_t erasesize; - uint32_t oobblock; /* Size of OOB blocks (e.g. 512) */ - uint32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ + uint32_t writesize; + uint32_t oobsize; // Amount of OOB data per block (e.g. 16) + /* The below two fields are obsolete and broken, do not use them + * (TODO: remove at some point) */ uint32_t ecctype; uint32_t eccsize; }; @@ -76,19 +74,36 @@ struct region_info_user { uint32_t regionindex; }; -#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) -#define MEMERASE _IOW('M', 2, struct erase_info_user) -#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) -#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) -#define MEMLOCK _IOW('M', 5, struct erase_info_user) -#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +struct otp_info { + uint32_t start; + uint32_t length; + uint32_t locked; +}; + +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) #define MEMGETREGIONCOUNT _IOR('M', 7, int) #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) #define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) #define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) #define MEMGETBADBLOCK _IOW('M', 11, loff_t) #define MEMSETBADBLOCK _IOW('M', 12, loff_t) +#define OTPSELECT _IOR('M', 13, int) +#define OTPGETREGIONCOUNT _IOW('M', 14, int) +#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info) +#define OTPLOCK _IOR('M', 16, struct otp_info) +#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) +#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) +#define MTDFILEMODE _IO('M', 19) +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */ struct nand_oobinfo { uint32_t useecc; uint32_t eccbytes; @@ -96,4 +111,46 @@ struct nand_oobinfo { uint32_t eccpos[48]; }; +struct nand_oobfree { + uint32_t offset; + uint32_t length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES 8 +/* + * ECC layout control structure. Exported to userspace for + * diagnosis and to allow creation of raw images + */ +struct nand_ecclayout { + uint32_t eccbytes; + uint32_t eccpos[64]; + uint32_t oobavail; + struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected: number of corrected bits + * @failed: number of uncorrectable errors + * @badblocks: number of bad blocks in this partition + * @bbtblocks: number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { + uint32_t corrected; + uint32_t failed; + uint32_t badblocks; + uint32_t bbtblocks; +}; + +/* + * Read/write file modes for access to MTD + */ +enum mtd_file_modes { + MTD_MODE_NORMAL = MTD_OTP_OFF, + MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY, + MTD_MODE_OTP_USER = MTD_OTP_USER, + MTD_MODE_RAW, +}; + #endif /* __MTD_ABI_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 05ba375a825..8e0dc00f757 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -1,5 +1,5 @@ /* - * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ + * $Id: mtd.h,v 1.61 2005/11/07 11:14:54 gleixner Exp $ * * Copyright (C) 1999-2003 David Woodhouse et al. * @@ -8,10 +8,13 @@ #ifndef __MTD_MTD_H__ #define __MTD_MTD_H__ + #include #include -#define MAX_MTD_DEVICES 16 +#define MTD_CHAR_MAJOR 90 +#define MTD_BLOCK_MAJOR 31 +#define MAX_MTD_DEVICES 32 #define MTD_ERASE_PENDING 0x01 #define MTD_ERASING 0x02 @@ -41,32 +44,83 @@ struct mtd_erase_region_info { u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ u_int32_t erasesize; /* For this region */ u_int32_t numblocks; /* Number of blocks of erasesize in this region */ + unsigned long *lockmap; /* If keeping bitmap of locks */ +}; + +/* + * oob operation modes + * + * MTD_OOB_PLACE: oob data are placed at the given offset + * MTD_OOB_AUTO: oob data are automatically placed at the free areas + * which are defined by the ecclayout + * MTD_OOB_RAW: mode to read raw data+oob in one chunk. The oob data + * is inserted into the data. Thats a raw image of the + * flash contents. + */ +typedef enum { + MTD_OOB_PLACE, + MTD_OOB_AUTO, + MTD_OOB_RAW, +} mtd_oob_mode_t; + +/** + * struct mtd_oob_ops - oob operation operands + * @mode: operation mode + * + * @len: number of data bytes to write/read + * + * @retlen: number of data bytes written/read + * + * @ooblen: number of oob bytes to write/read + * @oobretlen: number of oob bytes written/read + * @ooboffs: offset of oob data in the oob area (only relevant when + * mode = MTD_OOB_PLACE) + * @datbuf: data buffer - if NULL only oob data are read/written + * @oobbuf: oob data buffer + * + * Note, it is allowed to read more then one OOB area at one go, but not write. + * The interface assumes that the OOB write requests program only one page's + * OOB area. + */ +struct mtd_oob_ops { + mtd_oob_mode_t mode; + size_t len; + size_t retlen; + size_t ooblen; + size_t oobretlen; + uint32_t ooboffs; + uint8_t *datbuf; + uint8_t *oobbuf; }; struct mtd_info { u_char type; u_int32_t flags; - u_int32_t size; /* Total size of the MTD */ + u_int32_t size; // Total size of the MTD - /* "Major" erase size for the device. Naïve users may take this + /* "Major" erase size for the device. Naïve users may take this * to be the only erase size available, or may use the more detailed * information below if they desire */ u_int32_t erasesize; + /* Minimal writable flash unit size. In case of NOR flash it is 1 (even + * though individual bits can be cleared), in case of NAND flash it is + * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR + * it is of ECC block size, etc. It is illegal to have writesize = 0. + * Any driver registering a struct mtd_info must ensure a writesize of + * 1 or larger. + */ + u_int32_t writesize; - u_int32_t oobblock; /* Size of OOB blocks (e.g. 512) */ - u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ - u_int32_t oobavail; /* Number of bytes in OOB area available for fs */ - u_int32_t ecctype; - u_int32_t eccsize; - + u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) + u_int32_t oobavail; // Available OOB bytes per block - /* Kernel-only stuff starts here. */ + // Kernel-only stuff starts here. char *name; int index; - /* oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) */ - struct nand_oobinfo oobinfo; + /* ecc layout structure pointer - read only ! */ + struct nand_ecclayout *ecclayout; /* Data for variable erase regions. If numeraseregions is zero, * it means that the whole device has erasesize as given above. @@ -74,9 +128,6 @@ struct mtd_info { int numeraseregions; struct mtd_erase_region_info *eraseregions; - /* This really shouldn't be here. It can go away in 2.5 */ - u_int32_t bank_size; - int (*erase) (struct mtd_info *mtd, struct erase_info *instr); /* This stuff for eXecute-In-Place */ @@ -89,39 +140,35 @@ struct mtd_info { int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); - int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); - int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); - - int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); + int (*read_oob) (struct mtd_info *mtd, loff_t from, + struct mtd_oob_ops *ops); + int (*write_oob) (struct mtd_info *mtd, loff_t to, + struct mtd_oob_ops *ops); /* * Methods to access the protection register area, present in some * flash devices. The user data is one time programmable but the * factory data is read only. */ - int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - + int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); - - /* This function is not yet implemented */ + int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); + int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); + int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); + +/* XXX U-BOOT XXX */ #if 0 - /* kvec-based read/write methods. We need these especially for NAND flash, - with its limited number of write cycles per erase. + /* kvec-based read/write methods. NB: The 'count' parameter is the number of _vectors_, each of which contains an (ofs, len) tuple. */ - int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); - int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, - size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); - int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, - size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); #endif + /* Sync */ void (*sync) (struct mtd_info *mtd); -#if 0 + /* Chip-supported device locking */ int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); @@ -129,15 +176,32 @@ struct mtd_info { /* Power Management functions */ int (*suspend) (struct mtd_info *mtd); void (*resume) (struct mtd_info *mtd); -#endif + /* Bad block management functions */ int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); +/* XXX U-BOOT XXX */ +#if 0 + struct notifier_block reboot_notifier; /* default mode before reboot */ +#endif + + /* ECC status information */ + struct mtd_ecc_stats ecc_stats; + /* Subpage shift (NAND) */ + int subpage_sft; + void *priv; struct module *owner; int usecount; + + /* If the driver is something smart, like UBI, it may need to maintain + * its own reference counting. The below functions are only for driver. + * The driver may register its callbacks. These callbacks are not + * supposed to be called by MTD users */ + int (*get_device) (struct mtd_info *mtd); + void (*put_device) (struct mtd_info *mtd); }; @@ -147,9 +211,11 @@ extern int add_mtd_device(struct mtd_info *mtd); extern int del_mtd_device (struct mtd_info *mtd); extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); +extern struct mtd_info *get_mtd_device_nm(const char *name); extern void put_mtd_device(struct mtd_info *mtd); +/* XXX U-BOOT XXX */ #if 0 struct mtd_notifier { void (*add)(struct mtd_info *mtd); @@ -157,7 +223,6 @@ struct mtd_notifier { struct list_head list; }; - extern void register_mtd_user (struct mtd_notifier *new); extern int unregister_mtd_user (struct mtd_notifier *old); @@ -168,20 +233,6 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); #endif -#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) -#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) -#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) -#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) -#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) -#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) -#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) -#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) -#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) -#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) -#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) -#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) - - #ifdef CONFIG_MTD_PARTITIONS void mtd_erase_callback(struct erase_info *instr); #else @@ -208,7 +259,6 @@ static inline void mtd_erase_callback(struct erase_info *instr) } while(0) #else /* CONFIG_MTD_DEBUG */ #define MTDDEBUG(n, args...) do { } while(0) - #endif /* CONFIG_MTD_DEBUG */ #endif /* __MTD_MTD_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index e2a25a60d84..db8bd7ba22e 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -2,114 +2,123 @@ * linux/include/linux/mtd/nand.h * * Copyright (c) 2000 David Woodhouse - * Steven J. Hill + * Steven J. Hill * Thomas Gleixner * - * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ + * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * Info: - * Contains standard defines and IDs for NAND flash devices + * Info: + * Contains standard defines and IDs for NAND flash devices * - * Changelog: - * 01-31-2000 DMW Created - * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers - * so it can be used by other NAND flash device - * drivers. I also changed the copyright since none - * of the original contents of this file are specific - * to DoC devices. David can whack me with a baseball - * bat later if I did something naughty. - * 10-11-2000 SJH Added private NAND flash structure for driver - * 10-24-2000 SJH Added prototype for 'nand_scan' function - * 10-29-2001 TG changed nand_chip structure to support - * hardwarespecific function for accessing control lines - * 02-21-2002 TG added support for different read/write adress and - * ready/busy line access function - * 02-26-2002 TG added chip_delay to nand_chip structure to optimize - * command delay times for different chips - * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate - * defines in jffs2/wbuf.c - * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if - * CONFIG_MTD_NAND_ECC_JFFS2 is not set - * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC - * - * 08-29-2002 tglx nand_chip structure: data_poi for selecting - * internal / fs-driver buffer - * support for 6byte/512byte hardware ECC - * read_ecc, write_ecc extended for different oob-layout - * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, - * NAND_YAFFS_OOB - * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL - * Split manufacturer and device ID structures - * - * 02-08-2004 tglx added option field to nand structure for chip anomalities - * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id - * update of nand_chip structure description + * Changelog: + * See git changelog. */ #ifndef __LINUX_MTD_NAND_H #define __LINUX_MTD_NAND_H -#include +/* XXX U-BOOT XXX */ +#if 0 +#include +#include #include +#endif + +#include "config.h" + +#include "linux/mtd/compat.h" +#include "linux/mtd/mtd.h" + struct mtd_info; /* Scan and identify a NAND device */ extern int nand_scan (struct mtd_info *mtd, int max_chips); +/* Separate phases of nand_scan(), allowing board driver to intervene + * and override command or ECC setup according to flash type */ +extern int nand_scan_ident(struct mtd_info *mtd, int max_chips); +extern int nand_scan_tail(struct mtd_info *mtd); + /* Free resources held by the NAND device */ extern void nand_release (struct mtd_info *mtd); -/* Read raw data from the device without ECC */ -extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); +/* Internal helper for board drivers which need to override command function */ +extern void nand_wait_ready(struct mtd_info *mtd); +/* The maximum number of NAND chips in an array */ +#ifndef NAND_MAX_CHIPS +#define NAND_MAX_CHIPS 8 +#endif /* This constant declares the max. oobsize / page, which * is supported now. If you add a chip with bigger oobsize/page * adjust this accordingly. */ -#define NAND_MAX_OOBSIZE 64 +#define NAND_MAX_OOBSIZE 128 +#define NAND_MAX_PAGESIZE 4096 /* * Constants for hardware specific CLE/ALE/NCE function -*/ + * + * These are bits which can be or'ed to set/clear multiple + * bits in one go. + */ /* Select the chip by setting nCE to low */ -#define NAND_CTL_SETNCE 1 -/* Deselect the chip by setting nCE to high */ -#define NAND_CTL_CLRNCE 2 +#define NAND_NCE 0x01 /* Select the command latch by setting CLE to high */ -#define NAND_CTL_SETCLE 3 -/* Deselect the command latch by setting CLE to low */ -#define NAND_CTL_CLRCLE 4 +#define NAND_CLE 0x02 /* Select the address latch by setting ALE to high */ -#define NAND_CTL_SETALE 5 -/* Deselect the address latch by setting ALE to low */ -#define NAND_CTL_CLRALE 6 -/* Set write protection by setting WP to high. Not used! */ -#define NAND_CTL_SETWP 7 -/* Clear write protection by setting WP to low. Not used! */ -#define NAND_CTL_CLRWP 8 +#define NAND_ALE 0x04 + +#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE) +#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE) +#define NAND_CTRL_CHANGE 0x80 /* * Standard NAND flash commands */ #define NAND_CMD_READ0 0 #define NAND_CMD_READ1 1 +#define NAND_CMD_RNDOUT 5 #define NAND_CMD_PAGEPROG 0x10 #define NAND_CMD_READOOB 0x50 #define NAND_CMD_ERASE1 0x60 #define NAND_CMD_STATUS 0x70 #define NAND_CMD_STATUS_MULTI 0x71 #define NAND_CMD_SEQIN 0x80 +#define NAND_CMD_RNDIN 0x85 #define NAND_CMD_READID 0x90 #define NAND_CMD_ERASE2 0xd0 #define NAND_CMD_RESET 0xff /* Extended commands for large page devices */ #define NAND_CMD_READSTART 0x30 +#define NAND_CMD_RNDOUTSTART 0xE0 #define NAND_CMD_CACHEDPROG 0x15 +/* Extended commands for AG-AND device */ +/* + * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but + * there is no way to distinguish that from NAND_CMD_READ0 + * until the remaining sequence of commands has been completed + * so add a high order bit and mask it off in the command. + */ +#define NAND_CMD_DEPLETE1 0x100 +#define NAND_CMD_DEPLETE2 0x38 +#define NAND_CMD_STATUS_MULTI 0x71 +#define NAND_CMD_STATUS_ERROR 0x72 +/* multi-bank error status (banks 0-3) */ +#define NAND_CMD_STATUS_ERROR0 0x73 +#define NAND_CMD_STATUS_ERROR1 0x74 +#define NAND_CMD_STATUS_ERROR2 0x75 +#define NAND_CMD_STATUS_ERROR3 0x76 +#define NAND_CMD_STATUS_RESET 0x7f +#define NAND_CMD_STATUS_CLEAR 0xff + +#define NAND_CMD_NONE -1 + /* Status bits */ #define NAND_STATUS_FAIL 0x01 #define NAND_STATUS_FAIL_N1 0x02 @@ -120,25 +129,16 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ /* * Constants for ECC_MODES */ - -/* No ECC. Usage is not recommended ! */ -#define NAND_ECC_NONE 0 -/* Software ECC 3 byte ECC per 256 Byte data */ -#define NAND_ECC_SOFT 1 -/* Hardware ECC 3 byte ECC per 256 Byte data */ -#define NAND_ECC_HW3_256 2 -/* Hardware ECC 3 byte ECC per 512 Byte data */ -#define NAND_ECC_HW3_512 3 -/* Hardware ECC 6 byte ECC per 512 Byte data */ -#define NAND_ECC_HW6_512 4 -/* Hardware ECC 8 byte ECC per 512 Byte data */ -#define NAND_ECC_HW8_512 6 -/* Hardware ECC 12 byte ECC per 2048 Byte data */ -#define NAND_ECC_HW12_2048 7 +typedef enum { + NAND_ECC_NONE, + NAND_ECC_SOFT, + NAND_ECC_HW, + NAND_ECC_HW_SYNDROME, +} nand_ecc_modes_t; /* * Constants for Hardware ECC -*/ + */ /* Reset Hardware ECC for read */ #define NAND_ECC_READ 0 /* Reset Hardware ECC for write */ @@ -146,6 +146,10 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ /* Enable Hardware ECC before syndrom is read back from flash */ #define NAND_ECC_READSYN 2 +/* Bit mask for flags passed to do_nand_read_ecc */ +#define NAND_GET_DEVICE 0x80 + + /* Option constants for bizarre disfunctionality and real * features */ @@ -165,6 +169,17 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ /* Chip has a array of 4 pages which can be read without * additional ready /busy waits */ #define NAND_4PAGE_ARRAY 0x00000040 +/* Chip requires that BBT is periodically rewritten to prevent + * bits from adjacent blocks from 'leaking' in altering data. + * This happens with the Renesas AG-AND chips, possibly others. */ +#define BBT_AUTO_REFRESH 0x00000080 +/* Chip does not require ready check on read. True + * for all large page devices, as they do not support + * autoincrement.*/ +#define NAND_NO_READRDY 0x00000100 +/* Chip does not allow subpage writes */ +#define NAND_NO_SUBPAGE_WRITE 0x00000200 + /* Options valid for Samsung large page devices */ #define NAND_SAMSUNG_LP_OPTIONS \ @@ -183,18 +198,18 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_ /* Use a flash based bad block table. This option is passed to the * default bad block table function. */ #define NAND_USE_FLASH_BBT 0x00010000 -/* The hw ecc generator provides a syndrome instead a ecc value on read - * This can only work if we have the ecc bytes directly behind the - * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ -#define NAND_HWECC_SYNDROME 0x00020000 - - +/* This option skips the bbt scan during initialization. */ +#define NAND_SKIP_BBTSCAN 0x00020000 +/* This option is defined if the board driver allocates its own buffers + (e.g. because it needs them DMA-coherent */ +#define NAND_OWN_BUFFERS 0x00040000 /* Options set by nand scan */ -/* Nand scan has allocated oob_buf */ -#define NAND_OOBBUF_ALLOC 0x40000000 -/* Nand scan has allocated data_buf */ -#define NAND_DATABUF_ALLOC 0x80000000 +/* Nand scan has allocated controller struct */ +#define NAND_CONTROLLER_ALLOC 0x80000000 +/* Cell info constants */ +#define NAND_CI_CHIPNR_MSK 0x03 +#define NAND_CI_CELLTYPE_MSK 0x0C /* * nand_state_t - chip states @@ -207,135 +222,216 @@ typedef enum { FL_ERASING, FL_SYNCING, FL_CACHEDPRG, + FL_PM_SUSPENDED, } nand_state_t; /* Keep gcc happy */ struct nand_chip; -#if 0 /** - * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices - * @lock: protection lock + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices + * @lock: protection lock * @active: the mtd device which holds the controller currently + * @wq: wait queue to sleep on if a NAND operation is in progress + * used instead of the per chip wait queue when a hw controller is available */ struct nand_hw_control { - spinlock_t lock; - struct nand_chip *active; -}; +#if 0 + spinlock_t lock; + wait_queue_head_t wq; #endif + struct nand_chip *active; +}; + +/** + * struct nand_ecc_ctrl - Control structure for ecc + * @mode: ecc mode + * @steps: number of ecc steps per page + * @size: data bytes per ecc step + * @bytes: ecc bytes per step + * @total: total number of ecc bytes per page + * @prepad: padding information for syndrome based ecc generators + * @postpad: padding information for syndrome based ecc generators + * @layout: ECC layout control struct pointer + * @hwctl: function to control hardware ecc generator. Must only + * be provided if an hardware ECC is available + * @calculate: function for ecc calculation or readback from ecc hardware + * @correct: function for ecc correction, matching to ecc generator (sw/hw) + * @read_page_raw: function to read a raw page without ECC + * @write_page_raw: function to write a raw page without ECC + * @read_page: function to read a page according to the ecc generator requirements + * @write_page: function to write a page according to the ecc generator requirements + * @read_oob: function to read chip OOB data + * @write_oob: function to write chip OOB data + */ +struct nand_ecc_ctrl { + nand_ecc_modes_t mode; + int steps; + int size; + int bytes; + int total; + int prepad; + int postpad; + struct nand_ecclayout *layout; + void (*hwctl)(struct mtd_info *mtd, int mode); + int (*calculate)(struct mtd_info *mtd, + const uint8_t *dat, + uint8_t *ecc_code); + int (*correct)(struct mtd_info *mtd, uint8_t *dat, + uint8_t *read_ecc, + uint8_t *calc_ecc); + int (*read_page_raw)(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf); + void (*write_page_raw)(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf); + int (*read_page)(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf); + void (*write_page)(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf); + int (*read_oob)(struct mtd_info *mtd, + struct nand_chip *chip, + int page, + int sndcmd); + int (*write_oob)(struct mtd_info *mtd, + struct nand_chip *chip, + int page); +}; + +/** + * struct nand_buffers - buffer structure for read/write + * @ecccalc: buffer for calculated ecc + * @ecccode: buffer for ecc read from flash + * @databuf: buffer for data - dynamically sized + * + * Do not change the order of buffers. databuf and oobrbuf must be in + * consecutive order. + */ +struct nand_buffers { + uint8_t ecccalc[NAND_MAX_OOBSIZE]; + uint8_t ecccode[NAND_MAX_OOBSIZE]; + uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE]; +}; /** * struct nand_chip - NAND Private Flash Chip Data * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device * @read_byte: [REPLACEABLE] read one byte from the chip - * @write_byte: [REPLACEABLE] write one byte to the chip * @read_word: [REPLACEABLE] read one word from the chip - * @write_word: [REPLACEABLE] write one word to the chip * @write_buf: [REPLACEABLE] write data from the buffer to the chip * @read_buf: [REPLACEABLE] read data from the chip into the buffer * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data * @select_chip: [REPLACEABLE] select chip nr * @block_bad: [REPLACEABLE] check, if the block is bad * @block_markbad: [REPLACEABLE] mark the block bad - * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines + * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling + * ALE/CLE/nCE. Also used to write command and address * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line * If set to NULL no access to ready/busy is available and the ready/busy information * is read from the chip status register * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready - * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware - * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) - * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only - * be provided if a hardware ECC is available + * @ecc: [BOARDSPECIFIC] ecc control ctructure + * @buffers: buffer structure for read/write + * @hwcontrol: platform-specific hardware control structure + * @ops: oob operation operands * @erase_cmd: [INTERN] erase command write function, selectable due to AND support * @scan_bbt: [REPLACEABLE] function to scan bad block table - * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines - * @eccsize: [INTERN] databytes used per ecc-calculation - * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step - * @eccsteps: [INTERN] number of ecc calculation steps per page * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) - * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress * @state: [INTERN] the current state of the NAND device + * @oob_poi: poison value buffer * @page_shift: [INTERN] number of address bits in a page (column address bits) * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry * @chip_shift: [INTERN] number of address bits in one chip - * @data_buf: [INTERN] internal buffer for one page + oob - * @oob_buf: [INTERN] oob buffer for one eraseblock + * @datbuf: [INTERN] internal buffer for one page + oob + * @oobbuf: [INTERN] oob buffer for one eraseblock * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized * @data_poi: [INTERN] pointer to a data buffer * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about * special functionality. See the defines for further explanation * @badblockpos: [INTERN] position of the bad block marker in the oob area + * @cellinfo: [INTERN] MLC/multichip data from chip ident * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf - * @autooob: [REPLACEABLE] the default (auto)placement scheme + * @subpagesize: [INTERN] holds the subpagesize + * @ecclayout: [REPLACEABLE] the default ecc placement scheme * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup * @bbt_md: [REPLACEABLE] bad block table mirror descriptor * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan - * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices + * @controller: [REPLACEABLE] a pointer to a hardware controller structure + * which is shared among multiple independend devices * @priv: [OPTIONAL] pointer to private chip date + * @errstat: [OPTIONAL] hardware specific function to perform additional error status checks + * (determine if errors are correctable) + * @write_page: [REPLACEABLE] High-level page write function */ struct nand_chip { void __iomem *IO_ADDR_R; void __iomem *IO_ADDR_W; - u_char (*read_byte)(struct mtd_info *mtd); - void (*write_byte)(struct mtd_info *mtd, u_char byte); + uint8_t (*read_byte)(struct mtd_info *mtd); u16 (*read_word)(struct mtd_info *mtd); - void (*write_word)(struct mtd_info *mtd, u16 word); - - void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); - void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); - int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); + void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); + void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); + int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); void (*select_chip)(struct mtd_info *mtd, int chip); int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); - void (*hwcontrol)(struct mtd_info *mtd, int cmd); + void (*cmd_ctrl)(struct mtd_info *mtd, int dat, + unsigned int ctrl); int (*dev_ready)(struct mtd_info *mtd); void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); - int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); - int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); - int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); - void (*enable_hwecc)(struct mtd_info *mtd, int mode); + int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this); void (*erase_cmd)(struct mtd_info *mtd, int page); int (*scan_bbt)(struct mtd_info *mtd); - int eccmode; - int eccsize; - int eccbytes; - int eccsteps; + int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); + int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf, int page, int cached, int raw); + int chip_delay; -#if 0 - spinlock_t chip_lock; - wait_queue_head_t wq; - nand_state_t state; -#endif + unsigned int options; + int page_shift; int phys_erase_shift; int bbt_erase_shift; int chip_shift; - u_char *data_buf; - u_char *oob_buf; - int oobdirty; - u_char *data_poi; - unsigned int options; - int badblockpos; int numchips; unsigned long chipsize; int pagemask; int pagebuf; - struct nand_oobinfo *autooob; + int subpagesize; + uint8_t cellinfo; + int badblockpos; + + nand_state_t state; + + uint8_t *oob_poi; + struct nand_hw_control *controller; + struct nand_ecclayout *ecclayout; + + struct nand_ecc_ctrl ecc; + struct nand_buffers *buffers; + + struct nand_hw_control hwcontrol; + + struct mtd_oob_ops ops; + uint8_t *bbt; struct nand_bbt_descr *bbt_td; struct nand_bbt_descr *bbt_md; + struct nand_bbt_descr *badblock_pattern; - struct nand_hw_control *controller; + void *priv; }; @@ -348,11 +444,11 @@ struct nand_chip { #define NAND_MFR_NATIONAL 0x8f #define NAND_MFR_RENESAS 0x07 #define NAND_MFR_STMICRO 0x20 +#define NAND_MFR_HYNIX 0xad #define NAND_MFR_MICRON 0x2c /** * struct nand_flash_dev - NAND Flash Device ID Structure - * * @name: Identify the device type * @id: device ID code * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 @@ -403,7 +499,7 @@ extern struct nand_manufacturers nand_manuf_ids[]; * blocks is reserved at the end of the device where the tables are * written. * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than - * bad) block in the stored bbt + * bad) block in the stored bbt * @pattern: pattern to identify bad block table or factory marked good / * bad blocks, can be NULL, if len = 0 * @@ -417,11 +513,11 @@ struct nand_bbt_descr { int pages[NAND_MAX_CHIPS]; int offs; int veroffs; - uint8_t version[NAND_MAX_CHIPS]; + uint8_t version[NAND_MAX_CHIPS]; int len; int maxblocks; int reserved_block_code; - uint8_t *pattern; + uint8_t *pattern; }; /* Options for the bad block table descriptors */ @@ -433,7 +529,7 @@ struct nand_bbt_descr { #define NAND_BBT_4BIT 0x00000004 #define NAND_BBT_8BIT 0x00000008 /* The bad block table is in the last good block of the device */ -#define NAND_BBT_LASTBLOCK 0x00000010 +#define NAND_BBT_LASTBLOCK 0x00000010 /* The bbt is at the given page, else we must scan for the bbt */ #define NAND_BBT_ABSPAGE 0x00000020 /* The bbt is at the given page, else we must scan for the bbt */ @@ -456,13 +552,16 @@ struct nand_bbt_descr { #define NAND_BBT_SCAN2NDPAGE 0x00004000 /* The maximum number of blocks to scan for a bbt */ -#define NAND_BBT_SCAN_MAXBLOCKS 4 +#define NAND_BBT_SCAN_MAXBLOCKS 4 -extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); -extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); -extern int nand_default_bbt (struct mtd_info *mtd); -extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); -extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); +extern int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd); +extern int nand_update_bbt(struct mtd_info *mtd, loff_t offs); +extern int nand_default_bbt(struct mtd_info *mtd); +extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt); +extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, + int allowbbt); +extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, + size_t * retlen, uint8_t * buf); /* * Constants for oob configuration @@ -470,4 +569,67 @@ extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int #define NAND_SMALL_BADBLOCK_POS 5 #define NAND_LARGE_BADBLOCK_POS 0 +/** + * struct platform_nand_chip - chip level device structure + * @nr_chips: max. number of chips to scan for + * @chip_offset: chip number offset + * @nr_partitions: number of partitions pointed to by partitions (or zero) + * @partitions: mtd partition list + * @chip_delay: R/B delay value in us + * @options: Option flags, e.g. 16bit buswidth + * @ecclayout: ecc layout info structure + * @part_probe_types: NULL-terminated array of probe types + * @priv: hardware controller specific settings + */ +struct platform_nand_chip { + int nr_chips; + int chip_offset; + int nr_partitions; + struct mtd_partition *partitions; + struct nand_ecclayout *ecclayout; + int chip_delay; + unsigned int options; + const char **part_probe_types; + void *priv; +}; + +/** + * struct platform_nand_ctrl - controller level device structure + * @hwcontrol: platform specific hardware control structure + * @dev_ready: platform specific function to read ready/busy pin + * @select_chip: platform specific chip select function + * @cmd_ctrl: platform specific function for controlling + * ALE/CLE/nCE. Also used to write command and address + * @priv: private data to transport driver specific settings + * + * All fields are optional and depend on the hardware driver requirements + */ +struct platform_nand_ctrl { + void (*hwcontrol)(struct mtd_info *mtd, int cmd); + int (*dev_ready)(struct mtd_info *mtd); + void (*select_chip)(struct mtd_info *mtd, int chip); + void (*cmd_ctrl)(struct mtd_info *mtd, int dat, + unsigned int ctrl); + void *priv; +}; + +/** + * struct platform_nand_data - container structure for platform-specific data + * @chip: chip level chip structure + * @ctrl: controller level device structure + */ +struct platform_nand_data { + struct platform_nand_chip chip; + struct platform_nand_ctrl ctrl; +}; + +/* Some helpers to access the data structures */ +static inline +struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + + return chip->priv; +} + #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nftl-user.h b/include/linux/mtd/nftl-user.h new file mode 100644 index 00000000000..b2bca18e731 --- /dev/null +++ b/include/linux/mtd/nftl-user.h @@ -0,0 +1,76 @@ +/* + * $Id: nftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * + * Parts of NFTL headers shared with userspace + * + */ + +#ifndef __MTD_NFTL_USER_H__ +#define __MTD_NFTL_USER_H__ + +/* Block Control Information */ + +struct nftl_bci { + unsigned char ECCSig[6]; + uint8_t Status; + uint8_t Status1; +}__attribute__((packed)); + +/* Unit Control Information */ + +struct nftl_uci0 { + uint16_t VirtUnitNum; + uint16_t ReplUnitNum; + uint16_t SpareVirtUnitNum; + uint16_t SpareReplUnitNum; +} __attribute__((packed)); + +struct nftl_uci1 { + uint32_t WearInfo; + uint16_t EraseMark; + uint16_t EraseMark1; +} __attribute__((packed)); + +struct nftl_uci2 { + uint16_t FoldMark; + uint16_t FoldMark1; + uint32_t unused; +} __attribute__((packed)); + +union nftl_uci { + struct nftl_uci0 a; + struct nftl_uci1 b; + struct nftl_uci2 c; +}; + +struct nftl_oob { + struct nftl_bci b; + union nftl_uci u; +}; + +/* NFTL Media Header */ + +struct NFTLMediaHeader { + char DataOrgID[6]; + uint16_t NumEraseUnits; + uint16_t FirstPhysicalEUN; + uint32_t FormattedSize; + unsigned char UnitSizeFactor; +} __attribute__((packed)); + +#define MAX_ERASE_ZONES (8192 - 512) + +#define ERASE_MARK 0x3c69 +#define SECTOR_FREE 0xff +#define SECTOR_USED 0x55 +#define SECTOR_IGNORE 0x11 +#define SECTOR_DELETED 0x00 + +#define FOLD_MARK_IN_PROGRESS 0x5555 + +#define ZONE_GOOD 0xff +#define ZONE_BAD_ORIGINAL 0 +#define ZONE_BAD_MARKED 7 + + +#endif /* __MTD_NFTL_USER_H__ */ diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h index b0337c34011..04963a52e5e 100644 --- a/include/linux/mtd/nftl.h +++ b/include/linux/mtd/nftl.h @@ -1,75 +1,16 @@ - -/* Defines for NAND Flash Translation Layer */ -/* (c) 1999 Machine Vision Holdings, Inc. */ -/* Author: David Woodhouse */ -/* $Id: nftl.h,v 1.10 2000/12/29 00:25:38 dwmw2 Exp $ */ +/* + * $Id: nftl.h,v 1.16 2004/06/30 14:49:00 dbrown Exp $ + * + * (C) 1999-2003 David Woodhouse + */ #ifndef __MTD_NFTL_H__ #define __MTD_NFTL_H__ -/* Block Control Information */ - -struct nftl_bci { - unsigned char ECCSig[6]; - __u8 Status; - __u8 Status1; -}__attribute__((packed)); - -/* Unit Control Information */ - -struct nftl_uci0 { - __u16 VirtUnitNum; - __u16 ReplUnitNum; - __u16 SpareVirtUnitNum; - __u16 SpareReplUnitNum; -} __attribute__((packed)); - -struct nftl_uci1 { - __u32 WearInfo; - __u16 EraseMark; - __u16 EraseMark1; -} __attribute__((packed)); +#include +#include -struct nftl_uci2 { - __u16 FoldMark; - __u16 FoldMark1; - __u32 unused; -} __attribute__((packed)); - -union nftl_uci { - struct nftl_uci0 a; - struct nftl_uci1 b; - struct nftl_uci2 c; -}; - -struct nftl_oob { - struct nftl_bci b; - union nftl_uci u; -}; - -/* NFTL Media Header */ - -struct NFTLMediaHeader { - char DataOrgID[6]; - __u16 NumEraseUnits; - __u16 FirstPhysicalEUN; - __u32 FormattedSize; - unsigned char UnitSizeFactor; -} __attribute__((packed)); - -#define MAX_ERASE_ZONES (8192 - 512) - -#define ERASE_MARK 0x3c69 -#define SECTOR_FREE 0xff -#define SECTOR_USED 0x55 -#define SECTOR_IGNORE 0x11 -#define SECTOR_DELETED 0x00 - -#define FOLD_MARK_IN_PROGRESS 0x5555 - -#define ZONE_GOOD 0xff -#define ZONE_BAD_ORIGINAL 0 -#define ZONE_BAD_MARKED 7 +#include /* these info are used in ReplUnitTable */ #define BLOCK_NIL 0xffff /* last block of a chain */ @@ -78,7 +19,7 @@ struct NFTLMediaHeader { #define BLOCK_RESERVED 0xfffc /* bios block or bad block */ struct NFTLrecord { - struct DiskOnChip *mtd; + struct mtd_blktrans_dev mbd; __u16 MediaUnit, SpareMediaUnit; __u32 EraseSize; struct NFTLMediaHeader MediaHdr; @@ -90,16 +31,24 @@ struct NFTLrecord { __u16 lastEUN; /* should be suppressed */ __u16 numfreeEUNs; __u16 LastFreeEUN; /* To speed up finding a free EUN */ - __u32 nr_sects; int head,sect,cyl; __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */ __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */ - unsigned int nb_blocks; /* number of physical blocks */ - unsigned int nb_boot_blocks; /* number of blocks used by the bios */ + unsigned int nb_blocks; /* number of physical blocks */ + unsigned int nb_boot_blocks; /* number of blocks used by the bios */ + struct erase_info instr; + struct nand_ecclayout oobinfo; }; +int NFTL_mount(struct NFTLrecord *s); +int NFTL_formatblock(struct NFTLrecord *s, int block); + +#ifndef NFTL_MAJOR +#define NFTL_MAJOR 93 +#endif + #define MAX_NFTLS 16 -#define MAX_SECTORS_PER_UNIT 32 +#define MAX_SECTORS_PER_UNIT 64 #define NFTL_PARTN_BITS 4 #endif /* __MTD_NFTL_H__ */ diff --git a/include/linux/mtd/ubi-header.h b/include/linux/mtd/ubi-header.h new file mode 100644 index 00000000000..fa479c71aa3 --- /dev/null +++ b/include/linux/mtd/ubi-header.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (Битюцкий Ðртём) + * Thomas Gleixner + * Frank Haverkamp + * Oliver Lohmann + * Andreas Arnez + */ + +/* + * This file defines the layout of UBI headers and all the other UBI on-flash + * data structures. May be included by user-space. + */ + +#ifndef __UBI_HEADER_H__ +#define __UBI_HEADER_H__ + +#include + +/* The version of UBI images supported by this implementation */ +#define UBI_VERSION 1 + +/* The highest erase counter value supported by this implementation */ +#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF + +/* The initial CRC32 value used when calculating CRC checksums */ +#define UBI_CRC32_INIT 0xFFFFFFFFU + +/* Erase counter header magic number (ASCII "UBI#") */ +#define UBI_EC_HDR_MAGIC 0x55424923 +/* Volume identifier header magic number (ASCII "UBI!") */ +#define UBI_VID_HDR_MAGIC 0x55424921 + +/* + * Volume type constants used in the volume identifier header. + * + * @UBI_VID_DYNAMIC: dynamic volume + * @UBI_VID_STATIC: static volume + */ +enum { + UBI_VID_DYNAMIC = 1, + UBI_VID_STATIC = 2 +}; + +/* + * Compatibility constants used by internal volumes. + * + * @UBI_COMPAT_DELETE: delete this internal volume before anything is written + * to the flash + * @UBI_COMPAT_RO: attach this device in read-only mode + * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its + * physical eraseblocks, don't allow the wear-leveling unit to move them + * @UBI_COMPAT_REJECT: reject this UBI image + */ +enum { + UBI_COMPAT_DELETE = 1, + UBI_COMPAT_RO = 2, + UBI_COMPAT_PRESERVE = 4, + UBI_COMPAT_REJECT = 5 +}; + +/* + * ubi16_t/ubi32_t/ubi64_t - 16, 32, and 64-bit integers used in UBI on-flash + * data structures. + */ +typedef struct { + uint16_t int16; +} __attribute__ ((packed)) ubi16_t; + +typedef struct { + uint32_t int32; +} __attribute__ ((packed)) ubi32_t; + +typedef struct { + uint64_t int64; +} __attribute__ ((packed)) ubi64_t; + +/* + * In this implementation of UBI uses the big-endian format for on-flash + * integers. The below are the corresponding conversion macros. + */ +#define cpu_to_ubi16(x) ((ubi16_t){__cpu_to_be16(x)}) +#define ubi16_to_cpu(x) ((uint16_t)__be16_to_cpu((x).int16)) + +#define cpu_to_ubi32(x) ((ubi32_t){__cpu_to_be32(x)}) +#define ubi32_to_cpu(x) ((uint32_t)__be32_to_cpu((x).int32)) + +#define cpu_to_ubi64(x) ((ubi64_t){__cpu_to_be64(x)}) +#define ubi64_to_cpu(x) ((uint64_t)__be64_to_cpu((x).int64)) + +/* Sizes of UBI headers */ +#define UBI_EC_HDR_SIZE sizeof(struct ubi_ec_hdr) +#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) + +/* Sizes of UBI headers without the ending CRC */ +#define UBI_EC_HDR_SIZE_CRC (UBI_EC_HDR_SIZE - sizeof(ubi32_t)) +#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(ubi32_t)) + +/** + * struct ubi_ec_hdr - UBI erase counter header. + * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) + * @version: version of UBI implementation which is supposed to accept this + * UBI image + * @padding1: reserved for future, zeroes + * @ec: the erase counter + * @vid_hdr_offset: where the VID header starts + * @data_offset: where the user data start + * @padding2: reserved for future, zeroes + * @hdr_crc: erase counter header CRC checksum + * + * The erase counter header takes 64 bytes and has a plenty of unused space for + * future usage. The unused fields are zeroed. The @version field is used to + * indicate the version of UBI implementation which is supposed to be able to + * work with this UBI image. If @version is greater then the current UBI + * version, the image is rejected. This may be useful in future if something + * is changed radically. This field is duplicated in the volume identifier + * header. + * + * The @vid_hdr_offset and @data_offset fields contain the offset of the the + * volume identifier header and user data, relative to the beginning of the + * physical eraseblock. These values have to be the same for all physical + * eraseblocks. + */ +struct ubi_ec_hdr { + ubi32_t magic; + uint8_t version; + uint8_t padding1[3]; + ubi64_t ec; /* Warning: the current limit is 31-bit anyway! */ + ubi32_t vid_hdr_offset; + ubi32_t data_offset; + uint8_t padding2[36]; + ubi32_t hdr_crc; +} __attribute__ ((packed)); + +/** + * struct ubi_vid_hdr - on-flash UBI volume identifier header. + * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) + * @version: UBI implementation version which is supposed to accept this UBI + * image (%UBI_VERSION) + * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @copy_flag: if this logical eraseblock was copied from another physical + * eraseblock (for wear-leveling reasons) + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @vol_id: ID of this volume + * @lnum: logical eraseblock number + * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be + * removed, kept only for not breaking older UBI users) + * @data_size: how many bytes of data this logical eraseblock contains + * @used_ebs: total number of used logical eraseblocks in this volume + * @data_pad: how many bytes at the end of this physical eraseblock are not + * used + * @data_crc: CRC checksum of the data stored in this logical eraseblock + * @padding1: reserved for future, zeroes + * @sqnum: sequence number + * @padding2: reserved for future, zeroes + * @hdr_crc: volume identifier header CRC checksum + * + * The @sqnum is the value of the global sequence counter at the time when this + * VID header was created. The global sequence counter is incremented each time + * UBI writes a new VID header to the flash, i.e. when it maps a logical + * eraseblock to a new physical eraseblock. The global sequence counter is an + * unsigned 64-bit integer and we assume it never overflows. The @sqnum + * (sequence number) is used to distinguish between older and newer versions of + * logical eraseblocks. + * + * There are 2 situations when there may be more then one physical eraseblock + * corresponding to the same logical eraseblock, i.e., having the same @vol_id + * and @lnum values in the volume identifier header. Suppose we have a logical + * eraseblock L and it is mapped to the physical eraseblock P. + * + * 1. Because UBI may erase physical eraseblocks asynchronously, the following + * situation is possible: L is asynchronously erased, so P is scheduled for + * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, + * so P1 is written to, then an unclean reboot happens. Result - there are 2 + * physical eraseblocks P and P1 corresponding to the same logical eraseblock + * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the + * flash. + * + * 2. From time to time UBI moves logical eraseblocks to other physical + * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P + * to P1, and an unclean reboot happens before P is physically erased, there + * are two physical eraseblocks P and P1 corresponding to L and UBI has to + * select one of them when the flash is attached. The @sqnum field says which + * PEB is the original (obviously P will have lower @sqnum) and the copy. But + * it is not enough to select the physical eraseblock with the higher sequence + * number, because the unclean reboot could have happen in the middle of the + * copying process, so the data in P is corrupted. It is also not enough to + * just select the physical eraseblock with lower sequence number, because the + * data there may be old (consider a case if more data was added to P1 after + * the copying). Moreover, the unclean reboot may happen when the erasure of P + * was just started, so it result in unstable P, which is "mostly" OK, but + * still has unstable bits. + * + * UBI uses the @copy_flag field to indicate that this logical eraseblock is a + * copy. UBI also calculates data CRC when the data is moved and stores it at + * the @data_crc field of the copy (P1). So when UBI needs to pick one physical + * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is + * examined. If it is cleared, the situation* is simple and the newer one is + * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC + * checksum is correct, this physical eraseblock is selected (P1). Otherwise + * the older one (P) is selected. + * + * Note, there is an obsolete @leb_ver field which was used instead of @sqnum + * in the past. But it is not used anymore and we keep it in order to be able + * to deal with old UBI images. It will be removed at some point. + * + * There are 2 sorts of volumes in UBI: user volumes and internal volumes. + * Internal volumes are not seen from outside and are used for various internal + * UBI purposes. In this implementation there is only one internal volume - the + * layout volume. Internal volumes are the main mechanism of UBI extensions. + * For example, in future one may introduce a journal internal volume. Internal + * volumes have their own reserved range of IDs. + * + * The @compat field is only used for internal volumes and contains the "degree + * of their compatibility". It is always zero for user volumes. This field + * provides a mechanism to introduce UBI extensions and to be still compatible + * with older UBI binaries. For example, if someone introduced a journal in + * future, he would probably use %UBI_COMPAT_DELETE compatibility for the + * journal volume. And in this case, older UBI binaries, which know nothing + * about the journal volume, would just delete this volume and work perfectly + * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image + * - it just ignores the Ext3fs journal. + * + * The @data_crc field contains the CRC checksum of the contents of the logical + * eraseblock if this is a static volume. In case of dynamic volumes, it does + * not contain the CRC checksum as a rule. The only exception is when the + * data of the physical eraseblock was moved by the wear-leveling unit, then + * the wear-leveling unit calculates the data CRC and stores it in the + * @data_crc field. And of course, the @copy_flag is %in this case. + * + * The @data_size field is used only for static volumes because UBI has to know + * how many bytes of data are stored in this eraseblock. For dynamic volumes, + * this field usually contains zero. The only exception is when the data of the + * physical eraseblock was moved to another physical eraseblock for + * wear-leveling reasons. In this case, UBI calculates CRC checksum of the + * contents and uses both @data_crc and @data_size fields. In this case, the + * @data_size field contains data size. + * + * The @used_ebs field is used only for static volumes and indicates how many + * eraseblocks the data of the volume takes. For dynamic volumes this field is + * not used and always contains zero. + * + * The @data_pad is calculated when volumes are created using the alignment + * parameter. So, effectively, the @data_pad field reduces the size of logical + * eraseblocks of this volume. This is very handy when one uses block-oriented + * software (say, cramfs) on top of the UBI volume. + */ +struct ubi_vid_hdr { + ubi32_t magic; + uint8_t version; + uint8_t vol_type; + uint8_t copy_flag; + uint8_t compat; + ubi32_t vol_id; + ubi32_t lnum; + ubi32_t leb_ver; /* obsolete, to be removed, don't use */ + ubi32_t data_size; + ubi32_t used_ebs; + ubi32_t data_pad; + ubi32_t data_crc; + uint8_t padding1[4]; + ubi64_t sqnum; + uint8_t padding2[12]; + ubi32_t hdr_crc; +} __attribute__ ((packed)); + +/* Internal UBI volumes count */ +#define UBI_INT_VOL_COUNT 1 + +/* + * Starting ID of internal volumes. There is reserved room for 4096 internal + * volumes. + */ +#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) + +/* The layout volume contains the volume table */ + +#define UBI_LAYOUT_VOL_ID UBI_INTERNAL_VOL_START +#define UBI_LAYOUT_VOLUME_EBS 2 +#define UBI_LAYOUT_VOLUME_NAME "layout volume" +#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT + +/* The maximum number of volumes per one UBI device */ +#define UBI_MAX_VOLUMES 128 + +/* The maximum volume name length */ +#define UBI_VOL_NAME_MAX 127 + +/* Size of the volume table record */ +#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) + +/* Size of the volume table record without the ending CRC */ +#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(ubi32_t)) + +/** + * struct ubi_vtbl_record - a record in the volume table. + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @upd_marker: if volume update was started but not finished + * @name_len: volume name length + * @name: the volume name + * @padding2: reserved, zeroes + * @crc: a CRC32 checksum of the record + * + * The volume table records are stored in the volume table, which is stored in + * the layout volume. The layout volume consists of 2 logical eraseblock, each + * of which contains a copy of the volume table (i.e., the volume table is + * duplicated). The volume table is an array of &struct ubi_vtbl_record + * objects indexed by the volume ID. + * + * If the size of the logical eraseblock is large enough to fit + * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES + * records. Otherwise, it contains as many records as it can fit (i.e., size of + * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). + * + * The @upd_marker flag is used to implement volume update. It is set to %1 + * before update and set to %0 after the update. So if the update operation was + * interrupted, UBI knows that the volume is corrupted. + * + * The @alignment field is specified when the volume is created and cannot be + * later changed. It may be useful, for example, when a block-oriented file + * system works on top of UBI. The @data_pad field is calculated using the + * logical eraseblock size and @alignment. The alignment must be multiple to the + * minimal flash I/O unit. If @alignment is 1, all the available space of + * the physical eraseblocks is used. + * + * Empty records contain all zeroes and the CRC checksum of those zeroes. + */ +struct ubi_vtbl_record { + ubi32_t reserved_pebs; + ubi32_t alignment; + ubi32_t data_pad; + uint8_t vol_type; + uint8_t upd_marker; + ubi16_t name_len; + uint8_t name[UBI_VOL_NAME_MAX+1]; + uint8_t padding2[24]; + ubi32_t crc; +} __attribute__ ((packed)); + +#endif /* !__UBI_HEADER_H__ */ diff --git a/include/linux/mtd/ubi-user.h b/include/linux/mtd/ubi-user.h new file mode 100644 index 00000000000..fe06ded0e6b --- /dev/null +++ b/include/linux/mtd/ubi-user.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (Битюцкий Ðртём) + */ + +#ifndef __UBI_USER_H__ +#define __UBI_USER_H__ + +/* + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * + * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a + * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * + * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed + * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * + * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly + * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * + * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update + * size should be passed to the IOCTL. After then, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: + * + * fd = open("/dev/my_volume"); + * ioctl(fd, UBI_IOCVOLUP, &image_size); + * write(fd, buf, image_size); + * close(fd); + */ + +/* + * When a new volume is created, users may either specify the volume number they + * want to create or to let UBI automatically assign a volume number using this + * constant. + */ +#define UBI_VOL_NUM_AUTO (-1) + +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + +/* IOCTL commands of UBI character devices */ + +#define UBI_IOC_MAGIC 'o' + +/* Create an UBI volume */ +#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) +/* Remove an UBI volume */ +#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) +/* Re-size an UBI volume */ +#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) + +/* IOCTL commands of UBI volume character devices */ + +#define UBI_VOL_IOC_MAGIC 'O' + +/* Start UBI volume update */ +#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +/* An eraseblock erasure command, used for debugging, disabled by default */ +#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) + +/* + * UBI volume type constants. + * + * @UBI_DYNAMIC_VOLUME: dynamic volume + * @UBI_STATIC_VOLUME: static volume + */ +enum { + UBI_DYNAMIC_VOLUME = 3, + UBI_STATIC_VOLUME = 4 +}; + +/** + * struct ubi_mkvol_req - volume description data structure used in + * volume creation requests. + * @vol_id: volume number + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @padding1: reserved for future, not used + * @name_len: volume name length + * @padding2: reserved for future, not used + * @name: volume name + * + * This structure is used by userspace programs when creating new volumes. The + * @used_bytes field is only necessary when creating static volumes. + * + * The @alignment field specifies the required alignment of the volume logical + * eraseblock. This means, that the size of logical eraseblocks will be aligned + * to this number, i.e., + * (UBI device logical eraseblock size) mod (@alignment) = 0. + * + * To put it differently, the logical eraseblock of this volume may be slightly + * shortened in order to make it properly aligned. The alignment has to be + * multiple of the flash minimal input/output unit, or %1 to utilize the entire + * available space of logical eraseblocks. + * + * The @alignment field may be useful, for example, when one wants to maintain + * a block device on top of an UBI volume. In this case, it is desirable to fit + * an integer number of blocks in logical eraseblocks of this UBI volume. With + * alignment it is possible to update this volume using plane UBI volume image + * BLOBs, without caring about how to properly align them. + */ +struct ubi_mkvol_req { + int32_t vol_id; + int32_t alignment; + int64_t bytes; + int8_t vol_type; + int8_t padding1; + int16_t name_len; + int8_t padding2[4]; + char name[UBI_MAX_VOLUME_NAME+1]; +} __attribute__ ((packed)); + +/** + * struct ubi_rsvol_req - a data structure used in volume re-size requests. + * @vol_id: ID of the volume to re-size + * @bytes: new size of the volume in bytes + * + * Re-sizing is possible for both dynamic and static volumes. But while dynamic + * volumes may be re-sized arbitrarily, static volumes cannot be made to be + * smaller then the number of bytes they bear. To arbitrarily shrink a static + * volume, it must be wiped out first (by means of volume update operation with + * zero number of bytes). + */ +struct ubi_rsvol_req { + int64_t bytes; + int32_t vol_id; +} __attribute__ ((packed)); + +#endif /* __UBI_USER_H__ */ diff --git a/include/nand.h b/include/nand.h index e1285cdae97..83d597dc7db 100644 --- a/include/nand.h +++ b/include/nand.h @@ -84,6 +84,7 @@ struct nand_write_options { }; typedef struct nand_write_options nand_write_options_t; +typedef struct mtd_oob_ops mtd_oob_ops_t; struct nand_read_options { u_char *buffer; /* memory block in which read image is written*/ @@ -107,7 +108,7 @@ struct nand_erase_options { typedef struct nand_erase_options nand_erase_options_t; -int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts); +int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops); int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts); int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); -- cgit v1.3.1 From 4cbb651b29cb64d378a06729970e1e153bb605b1 Mon Sep 17 00:00:00 2001 From: William Juul Date: Thu, 8 Nov 2007 10:39:53 +0100 Subject: Remove white space at end. Signed-off-by: William Juul Signed-off-by: Scott Wood --- board/bf537-stamp/nand.c | 4 ++-- board/dave/PPChameleonEVB/nand.c | 2 +- board/nc650/nand.c | 2 +- board/netstar/nand.c | 2 +- board/prodrive/alpr/nand.c | 2 +- board/sc3/sc3nand.c | 4 ++-- common/cmd_nand.c | 2 +- cpu/arm926ejs/davinci/nand.c | 2 +- drivers/mtd/nand/nand_base.c | 4 ++-- drivers/mtd/nand/nand_util.c | 10 +++++----- include/linux/mtd/nand.h | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index bdf1d6ee456..d90bdd071c9 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -50,7 +50,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if( ctrl & NAND_ALE ) IO_ADDR_W = CFG_NAND_BASE + BFIN_NAND_ALE; else - IO_ADDR_W = CFG_NAND_BASE; + IO_ADDR_W = CFG_NAND_BASE; this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } this->IO_ADDR_R = this->IO_ADDR_W; @@ -59,7 +59,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) SSYNC(); if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } int bfin_device_ready(struct mtd_info *mtd) diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index 4bc4257c889..ea6400c0497 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -52,7 +52,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int } if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } diff --git a/board/nc650/nand.c b/board/nc650/nand.c index faec6053f7e..f59f5e2c9c5 100644 --- a/board/nc650/nand.c +++ b/board/nc650/nand.c @@ -48,7 +48,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) } if (cmd != NAND_CMD_NONE) - writeb(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } #elif defined(CONFIG_IDS852_REV2) /* diff --git a/board/netstar/nand.c b/board/netstar/nand.c index 302d78efef1..961c92112d1 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -46,7 +46,7 @@ static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c IO_ADDR_W |= MASK_ALE; } this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; - + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index 3224d3dd638..e1495feea10 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -57,7 +57,7 @@ static struct alpr_ndfc_regs *alpr_ndfc = NULL; * There are 2 NAND devices on the board, a Hynix HY27US08561A (1 GByte). */ static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ +{ struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c index 2f2e7458975..8ead7c850a8 100644 --- a/board/sc3/sc3nand.c +++ b/board/sc3/sc3nand.c @@ -46,7 +46,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if ( ctrl & NAND_CLE ) set_bit (SC3_NAND_CLE, sc3_control_base); else - clear_bit (SC3_NAND_CLE, sc3_control_base); + clear_bit (SC3_NAND_CLE, sc3_control_base); if ( ctrl & NAND_ALE ) set_bit (SC3_NAND_ALE, sc3_control_base); else @@ -54,7 +54,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) if ( ctrl & NAND_NCE ) set_bit (SC3_NAND_CE, sc3_control_base); else - clear_bit (SC3_NAND_CE, sc3_control_base); + clear_bit (SC3_NAND_CE, sc3_control_base); } if (cmd != NAND_CMD_NONE) diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 3e76d8207d6..f825234a7c8 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -328,7 +328,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) printf("\nNAND %s: ", read ? "read" : "write"); if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0) return 1; - + s = strchr(cmd, '.'); if (s != NULL && (!strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i"))) { diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 43041b635c0..196fc146b38 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -376,7 +376,7 @@ int board_nand_init(struct nand_chip *nand) // nand->autooob = &davinci_nand_oobinfo; nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; - nand->ecc.hwctl = nand_davinci_enable_hwecc; + nand->ecc.hwctl = nand_davinci_enable_hwecc; #else nand->ecc.mode = NAND_ECC_SOFT; #endif diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index aeb179731d6..e21a18baa4a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2080,7 +2080,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, /* Calculate pages in each block */ pages_per_block = 1 << (chip->phys_erase_shift - chip->page_shift); - + /* Select the NAND device */ chip->select_chip(mtd, chipnr); @@ -2748,7 +2748,7 @@ int nand_scan(struct mtd_info *mtd, int maxchips) BUG(); } #endif - + ret = nand_scan_ident(mtd, maxchips); if (!ret) ret = nand_scan_tail(mtd); diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 78e70cc807d..9fe486698c1 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -128,7 +128,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) for (; erase.addr < opts->offset + erase_length; erase.addr += meminfo->erasesize) { - + WATCHDOG_RESET (); if (!opts->scrub && bbtest) { @@ -163,7 +163,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts) chip->ops.datbuf = NULL; chip->ops.oobbuf = buf; chip->ops.ooboffs = chip->badblockpos & ~0x01; - + result = meminfo->write_oob(meminfo, erase.addr + meminfo->oobsize, &chip->ops); @@ -254,7 +254,7 @@ static struct nand_ecclayout autoplace_ecclayout = { * @chip: nand chip structure * @oob: oob data buffer * @ops: oob ops structure - * + * * Copied from nand_base.c */ static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, @@ -314,13 +314,13 @@ int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops) uint8_t *oob = ops->oobbuf; uint8_t *buf = ops->datbuf; int ret, subpage; - + ops->retlen = 0; if (!writelen) return 0; printk("nand_write_opts: to: 0x%08x, ops->len: 0x%08x\n", to, ops->len); - + /* reject writes, which are not page aligned */ if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { printk(KERN_NOTICE "nand_write: " diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index db8bd7ba22e..2984f5f282f 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -421,7 +421,7 @@ struct nand_chip { struct nand_ecc_ctrl ecc; struct nand_buffers *buffers; - + struct nand_hw_control hwcontrol; struct mtd_oob_ops ops; -- cgit v1.3.1 From 5e1dae5c3db7f4026f31b6a2a81ecd9e9dee475f Mon Sep 17 00:00:00 2001 From: William Juul Date: Fri, 9 Nov 2007 13:32:30 +0100 Subject: Fixing coding style issues - Fixing leading white spaces - Fixing indentation where 4 spaces are used instead of tab - Removing C++ comments (//), wherever I introduced them Signed-off-by: William Juul Signed-off-by: Scott Wood --- board/bf537-stamp/nand.c | 2 +- board/dave/PPChameleonEVB/nand.c | 4 +- board/delta/nand.c | 2 +- board/esd/common/esd405ep_nand.c | 6 +-- board/nc650/nand.c | 8 +-- board/netstar/nand.c | 2 +- board/prodrive/alpr/nand.c | 2 +- board/prodrive/pdnb3/nand.c | 2 +- board/sc3/sc3nand.c | 6 +-- board/tqc/tqm8272/tqm8272.c | 2 +- board/zylonite/nand.c | 2 +- common/cmd_nand.c | 110 +++++++++++++++++++++------------------ cpu/arm926ejs/davinci/nand.c | 18 +++---- cpu/ppc4xx/ndfc.c | 14 ++--- drivers/mtd/nand/diskonchip.c | 10 ++-- drivers/mtd/nand/nand_base.c | 2 +- include/linux/mtd/compat.h | 6 +-- include/linux/mtd/nand.h | 7 +-- 18 files changed, 106 insertions(+), 99 deletions(-) (limited to 'drivers') diff --git a/board/bf537-stamp/nand.c b/board/bf537-stamp/nand.c index d90bdd071c9..9800083c9e9 100644 --- a/board/bf537-stamp/nand.c +++ b/board/bf537-stamp/nand.c @@ -40,7 +40,7 @@ static void bfin_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { register struct nand_chip *this = mtd->priv; - u32 IO_ADDR_W = (u32) this->IO_ADDR_W; + u32 IO_ADDR_W = (u32) this->IO_ADDR_W; if (ctrl & NAND_CTRL_CHANGE) { if( ctrl & NAND_CLE ) diff --git a/board/dave/PPChameleonEVB/nand.c b/board/dave/PPChameleonEVB/nand.c index ea6400c0497..3ccbf650db4 100644 --- a/board/dave/PPChameleonEVB/nand.c +++ b/board/dave/PPChameleonEVB/nand.c @@ -36,7 +36,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int struct nand_chip *this = mtd->priv; ulong base = (ulong) this->IO_ADDR_W; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) MACRO_NAND_CTL_SETCLE((unsigned long)base); else @@ -51,7 +51,7 @@ static void ppchameleonevb_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int MACRO_NAND_DISABLE_CE((unsigned long)base); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/delta/nand.c b/board/delta/nand.c index 51520f5fb03..b007b090d05 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -549,7 +549,7 @@ int board_nand_init(struct nand_chip *nand) nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; -// nand->autooob = &delta_oob; +/* nand->autooob = &delta_oob; */ nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/board/esd/common/esd405ep_nand.c b/board/esd/common/esd405ep_nand.c index 4bf81ab4aac..40d1efb081b 100644 --- a/board/esd/common/esd405ep_nand.c +++ b/board/esd/common/esd405ep_nand.c @@ -32,8 +32,8 @@ */ static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CLE); else @@ -48,7 +48,7 @@ static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CFG_NAND_CE); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/nc650/nand.c b/board/nc650/nand.c index f59f5e2c9c5..7dca97fdf4a 100644 --- a/board/nc650/nand.c +++ b/board/nc650/nand.c @@ -36,7 +36,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) this->IO_ADDR_W += 2; else @@ -47,7 +47,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) this->IO_ADDR_W -= 1; } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } #elif defined(CONFIG_IDS852_REV2) @@ -58,7 +58,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) writeb(0, (volatile __u8 *) this->IO_ADDR_W + 0xa); else @@ -73,7 +73,7 @@ static void nc650_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) writeb(0, (volatile __u8 *) this->IO_ADDR_W) + 0xc); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } #else diff --git a/board/netstar/nand.c b/board/netstar/nand.c index 961c92112d1..e3ab66f2fbc 100644 --- a/board/netstar/nand.c +++ b/board/netstar/nand.c @@ -47,7 +47,7 @@ static void netstar_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c } this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/prodrive/alpr/nand.c b/board/prodrive/alpr/nand.c index e1495feea10..99f5737b85a 100644 --- a/board/prodrive/alpr/nand.c +++ b/board/prodrive/alpr/nand.c @@ -58,7 +58,7 @@ static struct alpr_ndfc_regs *alpr_ndfc = NULL; */ static void alpr_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/prodrive/pdnb3/nand.c b/board/prodrive/pdnb3/nand.c index 281ae70af61..1ce3c8c618f 100644 --- a/board/prodrive/pdnb3/nand.c +++ b/board/prodrive/pdnb3/nand.c @@ -54,7 +54,7 @@ static struct pdnb3_ndfc_regs *pdnb3_ndfc; */ static void pdnb3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/sc3/sc3nand.c b/board/sc3/sc3nand.c index 8ead7c850a8..45eff28c0ae 100644 --- a/board/sc3/sc3nand.c +++ b/board/sc3/sc3nand.c @@ -41,8 +41,8 @@ static void *sc3_control_base = (void *)0xEF600700; static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; - if (ctrl & NAND_CTRL_CHANGE) { + struct nand_chip *this = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) set_bit (SC3_NAND_CLE, sc3_control_base); else @@ -57,7 +57,7 @@ static void sc3_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) clear_bit (SC3_NAND_CE, sc3_control_base); } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } diff --git a/board/tqc/tqm8272/tqm8272.c b/board/tqc/tqm8272/tqm8272.c index 5148f3de5fc..a0ec254cedd 100644 --- a/board/tqc/tqm8272/tqm8272.c +++ b/board/tqc/tqm8272/tqm8272.c @@ -1070,7 +1070,7 @@ static u8 hwctl = 0; static void upmnand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) diff --git a/board/zylonite/nand.c b/board/zylonite/nand.c index 47d5d4b0d73..09bcbb233d2 100644 --- a/board/zylonite/nand.c +++ b/board/zylonite/nand.c @@ -553,7 +553,7 @@ int board_nand_init(struct nand_chip *nand) nand->write_buf = dfc_write_buf; nand->cmdfunc = dfc_cmdfunc; -// nand->autooob = &delta_oob; +/* nand->autooob = &delta_oob; */ nand->badblock_pattern = &delta_bbt_descr; return 0; } diff --git a/common/cmd_nand.c b/common/cmd_nand.c index f825234a7c8..339d82b5da5 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -35,7 +35,7 @@ int mtdparts_init(void); int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, - u8 *part_num, struct part_info **part); + u8 *part_num, struct part_info **part); #endif static int nand_dump_oob(nand_info_t *nand, ulong off) @@ -340,7 +340,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) opts.length = size; opts.offset = off; opts.quiet = quiet; -// ret = nand_read_opts(nand, &opts); +/* ret = nand_read_opts(nand, &opts); */ } else { /* write */ mtd_oob_ops_t opts; @@ -406,44 +406,48 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } if (status) { -// ulong block_start = 0; ulong off; -// int last_status = -1; - +/* ulong block_start = 0; + int last_status = -1; +*/ struct nand_chip *nand_chip = nand->priv; /* check the WP bit */ nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1); printf("device is %swrite protected\n", (nand_chip->read_byte(nand) & 0x80 ? - "NOT " : "" ) ); + "NOT " : "")); for (off = 0; off < nand->size; off += nand->writesize) { -// int s = nand_get_lock_status(nand, off); -// -// /* print message only if status has changed -// * or at end of chip -// */ -// if (off == nand->size - nand->writesize -// || (s != last_status && off != 0)) { -// -// printf("%08lx - %08lx: %8d pages %s%s%s\n", -// block_start, -// off-1, -// (off-block_start)/nand->writesize, -// ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), -// ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), -// ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); -// } -// -// last_status = s; +#if 0 /* must be fixed */ + int s = nand_get_lock_status(nand, off); + + /* print message only if status has changed + * or at end of chip + */ + if (off == nand->size - nand->writesize + || (s != last_status && off != 0)) { + + printf("%08lx - %08lx: %8d pages %s%s%s\n", + block_start, + off-1, + (off-block_start)/nand->writesize, + ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), + ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""), + ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); + } + + last_status = s; +#endif } } else { -// if (!nand_lock(nand, tight)) { -// puts("NAND flash successfully locked\n"); -// } else { -// puts("Error locking NAND flash\n"); -// return 1; -// } +#if 0 /* must be fixed */ + if (!nand_lock(nand, tight)) { + puts("NAND flash successfully locked\n"); + } else { + puts("Error locking NAND flash\n"); + return 1; + } +#endif } return 0; } @@ -452,13 +456,15 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0) return 1; -// if (!nand_unlock(nand, off, size)) { -// puts("NAND flash successfully unlocked\n"); -// } else { -// puts("Error unlocking NAND flash, " -// "write and erase will probably fail\n"); -// return 1; -// } +#if 0 /* must be fixed */ + if (!nand_unlock(nand, off, size)) { + puts("NAND flash successfully unlocked\n"); + } else { + puts("Error unlocking NAND flash, " + "write and erase will probably fail\n"); + return 1; + } +#endif return 0; } @@ -691,7 +697,7 @@ U_BOOT_CMD(nboot, 4, 1, do_nandboot, void archflashwp(void *archdata, int wp); #endif -#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) +#define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) #undef NAND_DEBUG #undef PSYCHO_DEBUG @@ -715,9 +721,9 @@ void archflashwp(void *archdata, int wp); #define CONFIG_MTD_NAND_ECC_JFFS2 /* bits for nand_legacy_rw() `cmd'; or together as needed */ -#define NANDRW_READ 0x01 -#define NANDRW_WRITE 0x00 -#define NANDRW_JFFS2 0x02 +#define NANDRW_READ 0x01 +#define NANDRW_WRITE 0x00 +#define NANDRW_JFFS2 0x02 #define NANDRW_JFFS2_SKIP 0x04 /* @@ -726,15 +732,15 @@ void archflashwp(void *archdata, int wp); extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; extern int curr_device; extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, - size_t len, int clean); + size_t len, int clean); extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start, - size_t len, size_t *retlen, u_char *buf); + size_t len, size_t *retlen, u_char *buf); extern void nand_print(struct nand_chip *nand); extern void nand_print_bad(struct nand_chip *nand); extern int nand_read_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, u_char *buf); + size_t len, size_t *retlen, u_char *buf); extern int nand_write_oob(struct nand_chip *nand, size_t ofs, - size_t len, size_t *retlen, const u_char *buf); + size_t len, size_t *retlen, const u_char *buf); int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) @@ -828,11 +834,11 @@ int do_nand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) if (strncmp (argv[1], "read", 4) == 0 || strncmp (argv[1], "write", 5) == 0) { - ulong addr = simple_strtoul (argv[2], NULL, 16); - off_t off = simple_strtoul (argv[3], NULL, 16); - size_t size = simple_strtoul (argv[4], NULL, 16); - int cmd = (strncmp (argv[1], "read", 4) == 0) ? - NANDRW_READ : NANDRW_WRITE; + ulong addr = simple_strtoul (argv[2], NULL, 16); + off_t off = simple_strtoul (argv[3], NULL, 16); + size_t size = simple_strtoul (argv[4], NULL, 16); + int cmd = (strncmp (argv[1], "read", 4) == 0) ? + NANDRW_READ : NANDRW_WRITE; size_t total; int ret; char *cmdtail = strchr (argv[1], '.'); @@ -923,9 +929,9 @@ U_BOOT_CMD( "nand device [dev] - show or set current device\n" "nand read[.jffs2[s]] addr off size\n" "nand write[.jffs2] addr off size - read/write `size' bytes starting\n" - " at offset `off' to/from memory address `addr'\n" + " at offset `off' to/from memory address `addr'\n" "nand erase [clean] [off size] - erase `size' bytes from\n" - " offset `off' (entire device if not specified)\n" + " offset `off' (entire device if not specified)\n" "nand bad - show bad blocks\n" "nand read.oob addr off size - read out-of-band data\n" "nand write.oob addr off size - read out-of-band data\n" diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 196fc146b38..6afd4d252e7 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -68,7 +68,7 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c this->IO_ADDR_W = (void __iomem *) IO_ADDR_W; } - if (cmd != NAND_CMD_NONE) + if (cmd != NAND_CMD_NONE) writeb(cmd, this->IO_ADDR_W); } @@ -363,22 +363,22 @@ int board_nand_init(struct nand_chip *nand) #endif #ifdef CFG_NAND_HW_ECC #ifdef CFG_NAND_LARGEPAGE - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 2048; - nand->ecc.bytes = 12; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 2048; + nand->ecc.bytes = 12; #elif defined(CFG_NAND_SMALLPAGE) - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 512; - nand->ecc.bytes = 3; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 512; + nand->ecc.bytes = 3; #else #error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!" #endif -// nand->autooob = &davinci_nand_oobinfo; +/* nand->autooob = &davinci_nand_oobinfo; */ nand->ecc.calculate = nand_davinci_calculate_ecc; nand->ecc.correct = nand_davinci_correct_data; nand->ecc.hwctl = nand_davinci_enable_hwecc; #else - nand->ecc.mode = NAND_ECC_SOFT; + nand->ecc.mode = NAND_ECC_SOFT; #endif /* Set address of hardware control function */ diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 7818eb9c54b..86548293152 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -48,7 +48,7 @@ static u8 hwctl = 0; static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct nand_chip *this = mtd->priv; + struct nand_chip *this = mtd->priv; if (ctrl & NAND_CTRL_CHANGE) { if ( ctrl & NAND_CLE ) @@ -183,12 +183,12 @@ int board_nand_init(struct nand_chip *nand) nand->read_buf = ndfc_read_buf; nand->dev_ready = ndfc_dev_ready; - nand->ecc.correct = nand_correct_data; - nand->ecc.hwctl = ndfc_enable_hwecc; - nand->ecc.calculate = ndfc_calculate_ecc; - nand->ecc.mode = NAND_ECC_HW; - nand->ecc.size = 256; - nand->ecc.bytes = 3; + nand->ecc.correct = nand_correct_data; + nand->ecc.hwctl = ndfc_enable_hwecc; + nand->ecc.calculate = ndfc_calculate_ecc; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.size = 256; + nand->ecc.bytes = 3; #ifndef CONFIG_NAND_SPL nand->write_buf = ndfc_write_buf; diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index a03f982be5f..ce197f5ad16 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -500,11 +500,11 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) struct doc_priv *doc = this->priv; void __iomem *docptr = doc->virtadr; - //ReadDOC(docptr, CDSNSlowIO); + /*ReadDOC(docptr, CDSNSlowIO); */ /* 11.4.5 -- delay twice to allow extended length cycle */ DoC_Delay(doc, 2); ReadDOC(docptr, ReadPipeInit); - //return ReadDOC(docptr, Mil_CDSN_IO); + /*return ReadDOC(docptr, Mil_CDSN_IO); */ return ReadDOC(docptr, LastDataRead); } @@ -1051,7 +1051,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, return ret; } -//u_char mydatabuf[528]; +/*u_char mydatabuf[528]; */ /* The strange out-of-order .oobfree list below is a (possibly unneeded) * attempt to retain compatibility. It used to read: @@ -1623,11 +1623,11 @@ static int __init doc_probe(unsigned long physadr) if (ChipID == DOC_ChipID_DocMilPlus16) { WriteDOC(~newval, virtadr, Mplus_AliasResolution); oldval = ReadDOC(doc->virtadr, Mplus_AliasResolution); - WriteDOC(newval, virtadr, Mplus_AliasResolution); // restore it + WriteDOC(newval, virtadr, Mplus_AliasResolution); /* restore it */ } else { WriteDOC(~newval, virtadr, AliasResolution); oldval = ReadDOC(doc->virtadr, AliasResolution); - WriteDOC(newval, virtadr, AliasResolution); // restore it + WriteDOC(newval, virtadr, AliasResolution); /* restore it */ } newval = ~newval; if (oldval == newval) { diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index e21a18baa4a..4b1c564f750 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2557,7 +2557,7 @@ int nand_scan_tail(struct mtd_info *mtd) default: printk(KERN_WARNING "No oob scheme defined for " "oobsize %d\n", mtd->oobsize); -// BUG(); +/* BUG(); */ } } diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h index 86a6e43ca9a..9036b74f86e 100644 --- a/include/linux/mtd/compat.h +++ b/include/linux/mtd/compat.h @@ -18,10 +18,10 @@ #define KERN_DEBUG #define kmalloc(size, flags) malloc(size) -#define kzalloc(size, flags) calloc(size, 1) +#define kzalloc(size, flags) calloc(size, 1) #define vmalloc(size) malloc(size) -#define kfree(ptr) free(ptr) -#define vfree(ptr) free(ptr) +#define kfree(ptr) free(ptr) +#define vfree(ptr) free(ptr) #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 2984f5f282f..f9b7d36a73a 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -236,11 +236,12 @@ struct nand_chip; * used instead of the per chip wait queue when a hw controller is available */ struct nand_hw_control { +/* XXX U-BOOT XXX */ #if 0 - spinlock_t lock; - wait_queue_head_t wq; + spinlock_t lock; + wait_queue_head_t wq; #endif - struct nand_chip *active; + struct nand_chip *active; }; /** -- cgit v1.3.1 From 12072264528eba33737bc9674e19f0e925ffda23 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Sat, 5 Jan 2008 16:43:25 +0100 Subject: NAND: Change nand_wait_ready() to not call nand_wait() This patch changes nand_wait_ready() to not just call nand_wait(), since this will send a new command to the NAND chip. We just want to wait for the chip to become ready here. Signed-off-by: Stefan Roese --- drivers/mtd/nand/nand_base.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 4b1c564f750..f577ed6294c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -489,7 +489,16 @@ EXPORT_SYMBOL_GPL(nand_wait_ready); void nand_wait_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; - nand_wait(mtd, chip); + u32 timeo = (CFG_HZ * 20) / 1000; + + reset_timer(); + + /* wait until command is processed or timeout occures */ + while (get_timer(0) < timeo) { + if (chip->dev_ready) + if (chip->dev_ready(mtd)) + break; + } } #endif -- cgit v1.3.1 From e52b34d40a8a646e3d11638ea8797e96398dba13 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 10 Jan 2008 18:47:33 +0100 Subject: NAND: Make NAND driver less verbose per default This patch turns off printing of bad blocks per default upon bootup. This can always be shown via the "nand bad" command later. Signed-off-by: Stefan Roese --- drivers/mtd/nand/nand_base.c | 6 +++--- drivers/mtd/nand/nand_bbt.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index f577ed6294c..5661a8e4c70 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2466,9 +2466,9 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, if (mtd->writesize > 512 && chip->cmdfunc == nand_command) chip->cmdfunc = nand_command_lp; - printk(KERN_INFO "NAND device: Manufacturer ID:" - " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, - nand_manuf_ids[maf_idx].name, type->name); + MTDDEBUG (MTD_DEBUG_LEVEL0, "NAND device: Manufacturer ID:" + " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, + nand_manuf_ids[maf_idx].name, type->name); return type; } diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index acf1cf54339..84479473b6d 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -391,7 +391,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, loff_t from; size_t readlen; - printk(KERN_INFO "Scanning device for bad blocks\n"); + MTDDEBUG (MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n"); if (bd->options & NAND_BBT_SCANALLPAGES) len = 1 << (this->bbt_erase_shift - this->page_shift); @@ -444,8 +444,9 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, if (ret) { this->bbt[i >> 3] |= 0x03 << (i & 0x6); - printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", - i >> 1, (unsigned int)from); + MTDDEBUG (MTD_DEBUG_LEVEL0, + "Bad eraseblock %d at 0x%08x\n", + i >> 1, (unsigned int)from); mtd->ecc_stats.badblocks++; } -- cgit v1.3.1 From 41ef8c716e93fdf50efe9c1ba733ca6675daaca6 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 18 Mar 2008 15:29:14 -0500 Subject: Don't panic if a controller driver does ecc its own way. Some hardware, such as the enhanced local bus controller used on some mpc83xx chips, does ecc transparently when reading and writing data, rather than providing a generic calculate/correct mechanism that can be exported to the nand subsystem. The subsystem should not BUG() when calculate, correct, or hwctl are missing, if the methods that call them have been overridden. Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 5661a8e4c70..7bceea8ac3d 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2595,8 +2595,12 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.write_oob = nand_write_oob_std; case NAND_ECC_HW_SYNDROME: - if (!chip->ecc.calculate || !chip->ecc.correct || - !chip->ecc.hwctl) { + if ((!chip->ecc.calculate || !chip->ecc.correct || + !chip->ecc.hwctl) && + (!chip->ecc.read_page || + chip->ecc.read_page == nand_read_page_hwecc || + !chip->ecc.write_page || + chip->ecc.write_page == nand_write_page_hwecc)) { printk(KERN_WARNING "No ECC functions supplied, " "Hardware ECC not possible\n"); BUG(); -- cgit v1.3.1 From 9fd020d6b4b36b9fb67cd834bc1ae7fdba15ee9e Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 21 Mar 2008 16:12:51 -0500 Subject: Freescale eLBC FCM NAND driver This is a driver for the Flash Control Machine of the enhanched Local Bus Controller found on some Freescale chips (such as the mpc8313 and the mpc8379). Signed-off-by: Scott Wood --- drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/fsl_elbc_nand.c | 759 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 760 insertions(+) create mode 100644 drivers/mtd/nand/fsl_elbc_nand.c (limited to 'drivers') diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 7bd22a0c9d7..ffb31695945 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -32,6 +32,7 @@ COBJS-y += nand_ecc.o COBJS-y += nand_bbt.o COBJS-y += nand_util.o +COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o COBJS-y += fsl_upm.o COBJS := $(COBJS-y) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c new file mode 100644 index 00000000000..c1644c0f6af --- /dev/null +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -0,0 +1,759 @@ +/* Freescale Enhanced Local Bus Controller FCM NAND driver + * + * Copyright (c) 2006-2008 Freescale Semiconductor + * + * Authors: Nick Spence , + * Scott Wood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#ifdef VERBOSE_DEBUG +#define DEBUG_ELBC +#define vdbg(format, arg...) printf("DEBUG: " format, ##arg) +#else +#define vdbg(format, arg...) do {} while (0) +#endif + +/* Can't use plain old DEBUG because the linux mtd + * headers define it as a macro. + */ +#ifdef DEBUG_ELBC +#define dbg(format, arg...) printf("DEBUG: " format, ##arg) +#else +#define dbg(format, arg...) do {} while (0) +#endif + +#define MAX_BANKS 8 +#define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ +#define FCM_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for FCM */ + +#define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC) + +struct fsl_elbc_ctrl; + +/* mtd information per set */ + +struct fsl_elbc_mtd { + struct mtd_info mtd; + struct nand_chip chip; + struct fsl_elbc_ctrl *ctrl; + + struct device *dev; + int bank; /* Chip select bank number */ + u8 __iomem *vbase; /* Chip select base virtual address */ + int page_size; /* NAND page size (0=512, 1=2048) */ + unsigned int fmr; /* FCM Flash Mode Register value */ +}; + +/* overview of the fsl elbc controller */ + +struct fsl_elbc_ctrl { + struct nand_hw_control controller; + struct fsl_elbc_mtd *chips[MAX_BANKS]; + + /* device info */ + lbus83xx_t *regs; + u8 __iomem *addr; /* Address of assigned FCM buffer */ + unsigned int page; /* Last page written to / read from */ + unsigned int read_bytes; /* Number of bytes read during command */ + unsigned int column; /* Saved column from SEQIN */ + unsigned int index; /* Pointer to next byte to 'read' */ + unsigned int status; /* status read from LTESR after last op */ + unsigned int mdr; /* UPM/FCM Data Register value */ + unsigned int use_mdr; /* Non zero if the MDR is to be set */ + unsigned int oob; /* Non zero if operating on OOB data */ + uint8_t *oob_poi; /* Place to write ECC after read back */ +}; + +/* These map to the positions used by the FCM hardware ECC generator */ + +/* Small Page FLASH with FMR[ECCM] = 0 */ +static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { + .eccbytes = 3, + .eccpos = {6, 7, 8}, + .oobfree = { {0, 5}, {9, 7} }, + .oobavail = 12, +}; + +/* Small Page FLASH with FMR[ECCM] = 1 */ +static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { + .eccbytes = 3, + .eccpos = {8, 9, 10}, + .oobfree = { {0, 5}, {6, 2}, {11, 5} }, + .oobavail = 12, +}; + +/* Large Page FLASH with FMR[ECCM] = 0 */ +static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { + .eccbytes = 12, + .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, + .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, + .oobavail = 48, +}; + +/* Large Page FLASH with FMR[ECCM] = 1 */ +static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { + .eccbytes = 12, + .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, + .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, + .oobavail = 48, +}; + +/*=================================*/ + +/* + * Set up the FCM hardware block and page address fields, and the fcm + * structure addr field to point to the correct FCM buffer in memory + */ +static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + lbus83xx_t *lbc = ctrl->regs; + int buf_num; + + ctrl->page = page_addr; + + out_be32(&lbc->fbar, + page_addr >> (chip->phys_erase_shift - chip->page_shift)); + + if (priv->page_size) { + out_be32(&lbc->fpar, + ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) | + (oob ? FPAR_LP_MS : 0) | column); + buf_num = (page_addr & 1) << 2; + } else { + out_be32(&lbc->fpar, + ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) | + (oob ? FPAR_SP_MS : 0) | column); + buf_num = page_addr & 7; + } + + ctrl->addr = priv->vbase + buf_num * 1024; + ctrl->index = column; + + /* for OOB data point to the second half of the buffer */ + if (oob) + ctrl->index += priv->page_size ? 2048 : 512; + + vdbg("set_addr: bank=%d, ctrl->addr=0x%p (0x%p), " + "index %x, pes %d ps %d\n", + buf_num, ctrl->addr, priv->vbase, ctrl->index, + chip->phys_erase_shift, chip->page_shift); +} + +/* + * execute FCM command and wait for it to complete + */ +static int fsl_elbc_run_command(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + lbus83xx_t *lbc = ctrl->regs; + long long end_tick; + u32 ltesr; + + /* Setup the FMR[OP] to execute without write protection */ + out_be32(&lbc->fmr, priv->fmr | 3); + if (ctrl->use_mdr) + out_be32(&lbc->mdr, ctrl->mdr); + + vdbg("fsl_elbc_run_command: fmr=%08x fir=%08x fcr=%08x\n", + in_be32(&lbc->fmr), in_be32(&lbc->fir), in_be32(&lbc->fcr)); + vdbg("fsl_elbc_run_command: fbar=%08x fpar=%08x " + "fbcr=%08x bank=%d\n", + in_be32(&lbc->fbar), in_be32(&lbc->fpar), + in_be32(&lbc->fbcr), priv->bank); + + /* execute special operation */ + out_be32(&lbc->lsor, priv->bank); + + /* wait for FCM complete flag or timeout */ + end_tick = usec2ticks(FCM_TIMEOUT_MSECS * 1000) + get_ticks(); + + ltesr = 0; + while (end_tick > get_ticks()) { + ltesr = in_be32(&lbc->ltesr); + if (ltesr & LTESR_CC) + break; + } + + ctrl->status = ltesr & LTESR_NAND_MASK; + out_be32(&lbc->ltesr, ctrl->status); + out_be32(&lbc->lteatr, 0); + + /* store mdr value in case it was needed */ + if (ctrl->use_mdr) + ctrl->mdr = in_be32(&lbc->mdr); + + ctrl->use_mdr = 0; + + vdbg("fsl_elbc_run_command: stat=%08x mdr=%08x fmr=%08x\n", + ctrl->status, ctrl->mdr, in_be32(&lbc->fmr)); + + /* returns 0 on success otherwise non-zero) */ + return ctrl->status == LTESR_CC ? 0 : -EIO; +} + +static void fsl_elbc_do_read(struct nand_chip *chip, int oob) +{ + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + lbus83xx_t *lbc = ctrl->regs; + + if (priv->page_size) { + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_CW1 << FIR_OP3_SHIFT) | + (FIR_OP_RBW << FIR_OP4_SHIFT)); + + out_be32(&lbc->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | + (NAND_CMD_READSTART << FCR_CMD1_SHIFT)); + } else { + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_RBW << FIR_OP3_SHIFT)); + + if (oob) + out_be32(&lbc->fcr, + NAND_CMD_READOOB << FCR_CMD0_SHIFT); + else + out_be32(&lbc->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); + } +} + +/* cmdfunc send commands to the FCM */ +static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + lbus83xx_t *lbc = ctrl->regs; + + ctrl->use_mdr = 0; + + /* clear the read buffer */ + ctrl->read_bytes = 0; + if (command != NAND_CMD_PAGEPROG) + ctrl->index = 0; + + switch (command) { + /* READ0 and READ1 read the entire buffer to use hardware ECC. */ + case NAND_CMD_READ1: + column += 256; + + /* fall-through */ + case NAND_CMD_READ0: + vdbg("fsl_elbc_cmdfunc: NAND_CMD_READ0, page_addr:" + " 0x%x, column: 0x%x.\n", page_addr, column); + + out_be32(&lbc->fbcr, 0); /* read entire page to enable ECC */ + set_addr(mtd, 0, page_addr, 0); + + ctrl->read_bytes = mtd->writesize + mtd->oobsize; + ctrl->index += column; + + fsl_elbc_do_read(chip, 0); + fsl_elbc_run_command(mtd); + return; + + /* READOOB reads only the OOB because no ECC is performed. */ + case NAND_CMD_READOOB: + vdbg("fsl_elbc_cmdfunc: NAND_CMD_READOOB, page_addr:" + " 0x%x, column: 0x%x.\n", page_addr, column); + + out_be32(&lbc->fbcr, mtd->oobsize - column); + set_addr(mtd, column, page_addr, 1); + + ctrl->read_bytes = mtd->writesize + mtd->oobsize; + + fsl_elbc_do_read(chip, 1); + fsl_elbc_run_command(mtd); + + return; + + /* READID must read all 5 possible bytes while CEB is active */ + case NAND_CMD_READID: + vdbg("fsl_elbc_cmdfunc: NAND_CMD_READID.\n"); + + out_be32(&lbc->fir, (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_UA << FIR_OP1_SHIFT) | + (FIR_OP_RBW << FIR_OP2_SHIFT)); + out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); + /* 5 bytes for manuf, device and exts */ + out_be32(&lbc->fbcr, 5); + ctrl->read_bytes = 5; + ctrl->use_mdr = 1; + ctrl->mdr = 0; + + set_addr(mtd, 0, 0, 0); + fsl_elbc_run_command(mtd); + return; + + /* ERASE1 stores the block and page address */ + case NAND_CMD_ERASE1: + vdbg("fsl_elbc_cmdfunc: NAND_CMD_ERASE1, " + "page_addr: 0x%x.\n", page_addr); + set_addr(mtd, 0, page_addr, 0); + return; + + /* ERASE2 uses the block and page address from ERASE1 */ + case NAND_CMD_ERASE2: + vdbg("fsl_elbc_cmdfunc: NAND_CMD_ERASE2.\n"); + + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_PA << FIR_OP1_SHIFT) | + (FIR_OP_CM1 << FIR_OP2_SHIFT)); + + out_be32(&lbc->fcr, + (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) | + (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT)); + + out_be32(&lbc->fbcr, 0); + ctrl->read_bytes = 0; + + fsl_elbc_run_command(mtd); + return; + + /* SEQIN sets up the addr buffer and all registers except the length */ + case NAND_CMD_SEQIN: { + u32 fcr; + vdbg("fsl_elbc_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, " + "page_addr: 0x%x, column: 0x%x.\n", + page_addr, column); + + ctrl->column = column; + ctrl->oob = 0; + + if (priv->page_size) { + fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) | + (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT); + + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CA << FIR_OP1_SHIFT) | + (FIR_OP_PA << FIR_OP2_SHIFT) | + (FIR_OP_WB << FIR_OP3_SHIFT) | + (FIR_OP_CW1 << FIR_OP4_SHIFT)); + } else { + fcr = (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT) | + (NAND_CMD_SEQIN << FCR_CMD2_SHIFT); + + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_CM2 << FIR_OP1_SHIFT) | + (FIR_OP_CA << FIR_OP2_SHIFT) | + (FIR_OP_PA << FIR_OP3_SHIFT) | + (FIR_OP_WB << FIR_OP4_SHIFT) | + (FIR_OP_CW1 << FIR_OP5_SHIFT)); + + if (column >= mtd->writesize) { + /* OOB area --> READOOB */ + column -= mtd->writesize; + fcr |= NAND_CMD_READOOB << FCR_CMD0_SHIFT; + ctrl->oob = 1; + } else if (column < 256) { + /* First 256 bytes --> READ0 */ + fcr |= NAND_CMD_READ0 << FCR_CMD0_SHIFT; + } else { + /* Second 256 bytes --> READ1 */ + fcr |= NAND_CMD_READ1 << FCR_CMD0_SHIFT; + } + } + + out_be32(&lbc->fcr, fcr); + set_addr(mtd, column, page_addr, ctrl->oob); + return; + } + + /* PAGEPROG reuses all of the setup from SEQIN and adds the length */ + case NAND_CMD_PAGEPROG: { + int full_page; + vdbg("fsl_elbc_cmdfunc: NAND_CMD_PAGEPROG " + "writing %d bytes.\n", ctrl->index); + + /* if the write did not start at 0 or is not a full page + * then set the exact length, otherwise use a full page + * write so the HW generates the ECC. + */ + if (ctrl->oob || ctrl->column != 0 || + ctrl->index != mtd->writesize + mtd->oobsize) { + out_be32(&lbc->fbcr, ctrl->index); + full_page = 0; + } else { + out_be32(&lbc->fbcr, 0); + full_page = 1; + } + + fsl_elbc_run_command(mtd); + + /* Read back the page in order to fill in the ECC for the + * caller. Is this really needed? + */ + if (full_page && ctrl->oob_poi) { + out_be32(&lbc->fbcr, 3); + set_addr(mtd, 6, page_addr, 1); + + ctrl->read_bytes = mtd->writesize + 9; + + fsl_elbc_do_read(chip, 1); + fsl_elbc_run_command(mtd); + + memcpy_fromio(ctrl->oob_poi + 6, + &ctrl->addr[ctrl->index], 3); + ctrl->index += 3; + } + + ctrl->oob_poi = NULL; + return; + } + + /* CMD_STATUS must read the status byte while CEB is active */ + /* Note - it does not wait for the ready line */ + case NAND_CMD_STATUS: + out_be32(&lbc->fir, + (FIR_OP_CM0 << FIR_OP0_SHIFT) | + (FIR_OP_RBW << FIR_OP1_SHIFT)); + out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT); + out_be32(&lbc->fbcr, 1); + set_addr(mtd, 0, 0, 0); + ctrl->read_bytes = 1; + + fsl_elbc_run_command(mtd); + + /* The chip always seems to report that it is + * write-protected, even when it is not. + */ + out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP); + return; + + /* RESET without waiting for the ready line */ + case NAND_CMD_RESET: + dbg("fsl_elbc_cmdfunc: NAND_CMD_RESET.\n"); + out_be32(&lbc->fir, FIR_OP_CM0 << FIR_OP0_SHIFT); + out_be32(&lbc->fcr, NAND_CMD_RESET << FCR_CMD0_SHIFT); + fsl_elbc_run_command(mtd); + return; + + default: + printf("fsl_elbc_cmdfunc: error, unsupported command 0x%x.\n", + command); + } +} + +static void fsl_elbc_select_chip(struct mtd_info *mtd, int chip) +{ + /* The hardware does not seem to support multiple + * chips per bank. + */ +} + +/* + * Write buf to the FCM Controller Data Buffer + */ +static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + unsigned int bufsize = mtd->writesize + mtd->oobsize; + + if (len < 0) { + printf("write_buf of %d bytes", len); + ctrl->status = 0; + return; + } + + if ((unsigned int)len > bufsize - ctrl->index) { + printf("write_buf beyond end of buffer " + "(%d requested, %u available)\n", + len, bufsize - ctrl->index); + len = bufsize - ctrl->index; + } + + memcpy_toio(&ctrl->addr[ctrl->index], buf, len); + ctrl->index += len; +} + +/* + * read a byte from either the FCM hardware buffer if it has any data left + * otherwise issue a command to read a single byte. + */ +static u8 fsl_elbc_read_byte(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + + /* If there are still bytes in the FCM, then use the next byte. */ + if (ctrl->index < ctrl->read_bytes) + return in_8(&ctrl->addr[ctrl->index++]); + + printf("read_byte beyond end of buffer\n"); + return ERR_BYTE; +} + +/* + * Read from the FCM Controller Data Buffer + */ +static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + int avail; + + if (len < 0) + return; + + avail = min((unsigned int)len, ctrl->read_bytes - ctrl->index); + memcpy_fromio(buf, &ctrl->addr[ctrl->index], avail); + ctrl->index += avail; + + if (len > avail) + printf("read_buf beyond end of buffer " + "(%d requested, %d available)\n", + len, avail); +} + +/* + * Verify buffer against the FCM Controller Data Buffer + */ +static int fsl_elbc_verify_buf(struct mtd_info *mtd, + const u_char *buf, int len) +{ + struct nand_chip *chip = mtd->priv; + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + int i; + + if (len < 0) { + printf("write_buf of %d bytes", len); + return -EINVAL; + } + + if ((unsigned int)len > ctrl->read_bytes - ctrl->index) { + printf("verify_buf beyond end of buffer " + "(%d requested, %u available)\n", + len, ctrl->read_bytes - ctrl->index); + + ctrl->index = ctrl->read_bytes; + return -EINVAL; + } + + for (i = 0; i < len; i++) + if (in_8(&ctrl->addr[ctrl->index + i]) != buf[i]) + break; + + ctrl->index += len; + return i == len && ctrl->status == LTESR_CC ? 0 : -EIO; +} + +/* This function is called after Program and Erase Operations to + * check for success or failure. + */ +static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) +{ + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + lbus83xx_t *lbc = ctrl->regs; + + if (ctrl->status != LTESR_CC) + return NAND_STATUS_FAIL; + + /* Use READ_STATUS command, but wait for the device to be ready */ + ctrl->use_mdr = 0; + out_be32(&lbc->fir, + (FIR_OP_CW0 << FIR_OP0_SHIFT) | + (FIR_OP_RBW << FIR_OP1_SHIFT)); + out_be32(&lbc->fcr, NAND_CMD_STATUS << FCR_CMD0_SHIFT); + out_be32(&lbc->fbcr, 1); + set_addr(mtd, 0, 0, 0); + ctrl->read_bytes = 1; + + fsl_elbc_run_command(mtd); + + if (ctrl->status != LTESR_CC) + return NAND_STATUS_FAIL; + + /* The chip always seems to report that it is + * write-protected, even when it is not. + */ + out_8(ctrl->addr, in_8(ctrl->addr) | NAND_STATUS_WP); + return fsl_elbc_read_byte(mtd); +} + +static int fsl_elbc_read_page(struct mtd_info *mtd, + struct nand_chip *chip, + uint8_t *buf) +{ + fsl_elbc_read_buf(mtd, buf, mtd->writesize); + fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); + + if (fsl_elbc_wait(mtd, chip) & NAND_STATUS_FAIL) + mtd->ecc_stats.failed++; + + return 0; +} + +/* ECC will be calculated automatically, and errors will be detected in + * waitfunc. + */ +static void fsl_elbc_write_page(struct mtd_info *mtd, + struct nand_chip *chip, + const uint8_t *buf) +{ + struct fsl_elbc_mtd *priv = chip->priv; + struct fsl_elbc_ctrl *ctrl = priv->ctrl; + + fsl_elbc_write_buf(mtd, buf, mtd->writesize); + fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); + + ctrl->oob_poi = chip->oob_poi; +} + +static struct fsl_elbc_ctrl *elbc_ctrl; + +static void fsl_elbc_ctrl_init(void) +{ + immap_t *im = (immap_t *)CFG_IMMR; + + elbc_ctrl = kzalloc(sizeof(*elbc_ctrl), GFP_KERNEL); + if (!elbc_ctrl) + return; + + elbc_ctrl->regs = &im->lbus; + + /* clear event registers */ + out_be32(&elbc_ctrl->regs->ltesr, LTESR_NAND_MASK); + out_be32(&elbc_ctrl->regs->lteatr, 0); + + /* Enable interrupts for any detected events */ + out_be32(&elbc_ctrl->regs->lteir, LTESR_NAND_MASK); + + elbc_ctrl->read_bytes = 0; + elbc_ctrl->index = 0; + elbc_ctrl->addr = NULL; +} + +int board_nand_init(struct nand_chip *nand) +{ + struct fsl_elbc_mtd *priv; + uint32_t br, or; + + if (!elbc_ctrl) { + fsl_elbc_ctrl_init(); + if (!elbc_ctrl) + return -1; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->ctrl = elbc_ctrl; + priv->vbase = nand->IO_ADDR_R; + + /* Find which chip select it is connected to. It'd be nice + * if we could pass more than one datum to the NAND driver... + */ + for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) { + br = in_be32(&elbc_ctrl->regs->bank[priv->bank].br); + or = in_be32(&elbc_ctrl->regs->bank[priv->bank].or); + + if ((br & BR_V) && (br & BR_MSEL) == BR_MS_FCM && + (br & or & BR_BA) == (phys_addr_t)nand->IO_ADDR_R) + break; + } + + if (priv->bank >= MAX_BANKS) { + printf("fsl_elbc_nand: address did not match any " + "chip selects\n"); + return -ENODEV; + } + + elbc_ctrl->chips[priv->bank] = priv; + + /* fill in nand_chip structure */ + /* set up function call table */ + nand->read_byte = fsl_elbc_read_byte; + nand->write_buf = fsl_elbc_write_buf; + nand->read_buf = fsl_elbc_read_buf; + nand->verify_buf = fsl_elbc_verify_buf; + nand->select_chip = fsl_elbc_select_chip; + nand->cmdfunc = fsl_elbc_cmdfunc; + nand->waitfunc = fsl_elbc_wait; + + /* set up nand options */ + nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; + + nand->controller = &elbc_ctrl->controller; + nand->priv = priv; + + nand->ecc.read_page = fsl_elbc_read_page; + nand->ecc.write_page = fsl_elbc_write_page; + + /* If CS Base Register selects full hardware ECC then use it */ + if ((br & BR_DECC) == BR_DECC_CHK_GEN) { + nand->ecc.mode = NAND_ECC_HW; + + nand->ecc.layout = (priv->fmr & FMR_ECCM) ? + &fsl_elbc_oob_sp_eccm1 : + &fsl_elbc_oob_sp_eccm0; + + nand->ecc.size = 512; + nand->ecc.bytes = 3; + nand->ecc.steps = 1; + } else { + /* otherwise fall back to default software ECC */ + nand->ecc.mode = NAND_ECC_SOFT; + } + + priv->fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT); + + /* adjust Option Register and ECC to match Flash page size */ + if (or & OR_FCM_PGS) { + priv->page_size = 1; + + /* adjust ecc setup if needed */ + if ((br & BR_DECC) == BR_DECC_CHK_GEN) { + nand->ecc.steps = 4; + nand->ecc.layout = (priv->fmr & FMR_ECCM) ? + &fsl_elbc_oob_lp_eccm1 : + &fsl_elbc_oob_lp_eccm0; + } + } + + return 0; +} -- cgit v1.3.1 From 9c814b0a716aae884bec977b9a032dfa59cfb79a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 28 Mar 2008 22:10:54 +0300 Subject: fsl_elbc_nand: workaround for hangs during nand write Using current driver elbc sometimes hangs during nand write. Reading back last byte helps though (thanks to Scott Wood for the idea). Signed-off-by: Anton Vorontsov Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_elbc_nand.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index c1644c0f6af..ab3e0fdf564 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -489,7 +489,7 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) struct fsl_elbc_ctrl *ctrl = priv->ctrl; unsigned int bufsize = mtd->writesize + mtd->oobsize; - if (len < 0) { + if (len <= 0) { printf("write_buf of %d bytes", len); ctrl->status = 0; return; @@ -503,6 +503,15 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) } memcpy_toio(&ctrl->addr[ctrl->index], buf, len); + /* + * This is workaround for the weird elbc hangs during nand write, + * Scott Wood says: "...perhaps difference in how long it takes a + * write to make it through the localbus compared to a write to IMMR + * is causing problems, and sync isn't helping for some reason." + * Reading back the last byte helps though. + */ + in_8(&ctrl->addr[ctrl->index] + len - 1); + ctrl->index += len; } -- cgit v1.3.1 From 300253306acc72b1b2e9faf0987f86551151d7cf Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 22 May 2008 15:02:46 -0500 Subject: fsl_elbc_nand: Hard-code the FBAR/FPAR split. The hardware has separate registers for block and page-within-block, but the division between the two has no apparent relation to the actual erase block size of the NAND chip. Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_elbc_nand.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index ab3e0fdf564..0bd1bdbcf00 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -138,15 +138,14 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) ctrl->page = page_addr; - out_be32(&lbc->fbar, - page_addr >> (chip->phys_erase_shift - chip->page_shift)); - if (priv->page_size) { + out_be32(&lbc->fbar, page_addr >> 6); out_be32(&lbc->fpar, ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) | (oob ? FPAR_LP_MS : 0) | column); buf_num = (page_addr & 1) << 2; } else { + out_be32(&lbc->fbar, page_addr >> 5); out_be32(&lbc->fpar, ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) | (oob ? FPAR_SP_MS : 0) | column); -- cgit v1.3.1 From e1c3dbada349992875934575c97b328ab2cb33ca Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Thu, 12 Jun 2008 11:10:21 -0500 Subject: nand: fsl_upm: convert to updated MTD NAND infrastructure Signed-off-by: Anton Vorontsov Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_upm.c | 68 +++++++++++++++++++-------------------------- include/linux/mtd/fsl_upm.h | 3 ++ 2 files changed, 31 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 67ae9c8d5b1..e651903040b 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -20,8 +20,6 @@ #include #include -static int fsl_upm_in_pattern; - static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset) { clrsetbits_be32(upm->mxmr, MxMR_MAD_MSK, MxMR_OP_RUNP | pat_offset); @@ -51,49 +49,38 @@ static void fsl_upm_run_pattern(struct fsl_upm *upm, int width, u32 cmd) } } -static void nand_hwcontrol (struct mtd_info *mtd, int cmd) +static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; struct fsl_upm_nand *fun = chip->priv; - switch (cmd) { - case NAND_CTL_SETCLE: - fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); - fsl_upm_in_pattern++; - break; - case NAND_CTL_SETALE: - fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); - fsl_upm_in_pattern++; - break; - case NAND_CTL_CLRCLE: - case NAND_CTL_CLRALE: + if (!(ctrl & fun->last_ctrl)) { fsl_upm_end_pattern(&fun->upm); - fsl_upm_in_pattern--; - break; + + if (cmd == NAND_CMD_NONE) + return; + + fun->last_ctrl = ctrl & (NAND_ALE | NAND_CLE); } -} -static void nand_write_byte(struct mtd_info *mtd, u_char byte) -{ - struct nand_chip *chip = mtd->priv; + if (ctrl & NAND_CTRL_CHANGE) { + if (ctrl & NAND_ALE) + fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset); + else if (ctrl & NAND_CLE) + fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset); + } - if (fsl_upm_in_pattern) { - struct fsl_upm_nand *fun = chip->priv; - - fsl_upm_run_pattern(&fun->upm, fun->width, byte); - - /* - * Some boards/chips needs this. At least on MPC8360E-RDK we - * need it. Probably weird chip, because I don't see any need - * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are - * 0-2 unexpected busy states per block read. - */ - if (fun->wait_pattern) { - while (!fun->dev_ready()) - debug("unexpected busy state\n"); - } - } else { - out_8(chip->IO_ADDR_W, byte); + fsl_upm_run_pattern(&fun->upm, fun->width, cmd); + + /* + * Some boards/chips needs this. At least on MPC8360E-RDK we + * need it. Probably weird chip, because I don't see any need + * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are + * 0-2 unexpected busy states per block read. + */ + if (fun->wait_pattern) { + while (!fun->dev_ready()) + debug("unexpected busy state\n"); } } @@ -148,13 +135,14 @@ int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun) if (fun->width != 8 && fun->width != 16 && fun->width != 32) return -ENOSYS; + fun->last_ctrl = NAND_CLE; + chip->priv = fun; chip->chip_delay = fun->chip_delay; - chip->eccmode = NAND_ECC_SOFT; - chip->hwcontrol = nand_hwcontrol; + chip->ecc.mode = NAND_ECC_SOFT; + chip->cmd_ctrl = fun_cmd_ctrl; chip->read_byte = nand_read_byte; chip->read_buf = nand_read_buf; - chip->write_byte = nand_write_byte; chip->write_buf = nand_write_buf; chip->verify_buf = nand_verify_buf; if (fun->dev_ready) diff --git a/include/linux/mtd/fsl_upm.h b/include/linux/mtd/fsl_upm.h index 49fd8a60ff9..638a4e468de 100644 --- a/include/linux/mtd/fsl_upm.h +++ b/include/linux/mtd/fsl_upm.h @@ -31,6 +31,9 @@ struct fsl_upm_nand { int wait_pattern; int (*dev_ready)(void); int chip_delay; + + /* no need to fill */ + int last_ctrl; }; extern int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun); -- cgit v1.3.1 From dfbf617ff055e4216f78d358b0867c548916d14b Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 12 Jun 2008 13:20:16 -0500 Subject: NAND read/write fix Implement block-skipping read/write, based on a patch from Morten Ebbell Hestens . Signed-off-by: Morten Ebbell Hestnes Signed-off-by: Scott Wood --- common/cmd_nand.c | 36 +- drivers/mtd/nand/nand_util.c | 762 ++++++++++--------------------------------- include/nand.h | 7 +- 3 files changed, 194 insertions(+), 611 deletions(-) (limited to 'drivers') diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 2c421e948ed..520c15217c2 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -74,7 +74,8 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob) printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" " %02x %02x %02x %02x %02x %02x %02x %02x\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], - p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); + p[8], p[9], p[10], p[11], p[12], p[13], p[14], + p[15]); p += 16; } puts("OOB:\n"); @@ -317,7 +318,6 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } - /* read write */ if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { int read; @@ -334,31 +334,12 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) s = strchr(cmd, '.'); if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { - if (read) { - /* read */ - nand_read_options_t opts; - memset(&opts, 0, sizeof(opts)); - opts.buffer = (u_char*) addr; - opts.length = size; - opts.offset = off; - opts.quiet = quiet; -/* - * ! BROKEN ! - * - * TODO: Function must be implemented - * - * ret = nand_read_opts(nand, &opts); - */ - } else { - /* write */ - mtd_oob_ops_t opts; - memset(&opts, 0, sizeof(opts)); - opts.datbuf = (u_char*) addr; - opts.len = size; - opts.ooblen = 64; - opts.mode = MTD_OOB_AUTO; - ret = nand_write_opts(nand, off, &opts); - } + if (read) + ret = nand_read_skip_bad(nand, off, &size, + (u_char *)addr); + else + ret = nand_write_skip_bad(nand, off, &size, + (u_char *)addr); } else if (s != NULL && !strcmp(s, ".oob")) { /* out-of-band data */ mtd_oob_ops_t ops = { @@ -396,6 +377,7 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) } return 1; } + if (strcmp(cmd, "biterr") == 0) { /* todo */ return 1; diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 9fe486698c1..02fe914db8b 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -248,586 +248,6 @@ static struct nand_ecclayout autoplace_ecclayout = { }; #endif - -/** - * nand_fill_oob - [Internal] Transfer client buffer to oob - * @chip: nand chip structure - * @oob: oob data buffer - * @ops: oob ops structure - * - * Copied from nand_base.c - */ -static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, - struct mtd_oob_ops *ops) -{ - size_t len = ops->ooblen; - - switch(ops->mode) { - - case MTD_OOB_PLACE: - case MTD_OOB_RAW: - memcpy(chip->oob_poi + ops->ooboffs, oob, len); - return oob + len; - - case MTD_OOB_AUTO: { - struct nand_oobfree *free = chip->ecc.layout->oobfree; - uint32_t boffs = 0, woffs = ops->ooboffs; - size_t bytes = 0; - - for(; free->length && len; free++, len -= bytes) { - /* Write request not from offset 0 ? */ - if (unlikely(woffs)) { - if (woffs >= free->length) { - woffs -= free->length; - continue; - } - boffs = free->offset + woffs; - bytes = min_t(size_t, len, - (free->length - woffs)); - woffs = 0; - } else { - bytes = min_t(size_t, len, free->length); - boffs = free->offset; - } - memcpy(chip->oob_poi + boffs, oob, bytes); - oob += bytes; - } - return oob; - } - default: - BUG(); - } - return NULL; -} - -#define NOTALIGNED(x) (x & (chip->subpagesize - 1)) != 0 - - -/* copied from nand_base.c: nand_do_write_ops() - * Only very small changes - */ -int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops) -{ - int chipnr, realpage, page, blockmask, column; - struct nand_chip *chip = mtd->priv; - uint32_t writelen = ops->len; - uint8_t *oob = ops->oobbuf; - uint8_t *buf = ops->datbuf; - int ret, subpage; - - ops->retlen = 0; - if (!writelen) - return 0; - - printk("nand_write_opts: to: 0x%08x, ops->len: 0x%08x\n", to, ops->len); - - /* reject writes, which are not page aligned */ - if (NOTALIGNED(to) || NOTALIGNED(ops->len)) { - printk(KERN_NOTICE "nand_write: " - "Attempt to write not page aligned data\n"); - return -EINVAL; - } - - column = to & (mtd->writesize - 1); - subpage = column || (writelen & (mtd->writesize - 1)); - - if (subpage && oob) { - printk(KERN_NOTICE "nand_write: " - "Attempt to write oob to subpage\n"); - return -EINVAL; - } - - chipnr = (int)(to >> chip->chip_shift); - chip->select_chip(mtd, chipnr); - - /* XXX U-BOOT XXX */ -#if 0 - /* Check, if it is write protected */ - if (nand_check_wp(mtd)) - return -EIO; -#endif - - realpage = (int)(to >> chip->page_shift); - page = realpage & chip->pagemask; - blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; - - /* Invalidate the page cache, when we write to the cached page */ - if (to <= (chip->pagebuf << chip->page_shift) && - (chip->pagebuf << chip->page_shift) < (to + ops->len)) - chip->pagebuf = -1; - - /* If we're not given explicit OOB data, let it be 0xFF */ - if (likely(!oob)) { - printf("!oob, writing %d bytes with 0xff to chip->oob_poi (0x%08x)\n", mtd->oobsize, chip->oob_poi); - memset(chip->oob_poi, 0xff, mtd->oobsize); - } - - while(1) { - int bytes = mtd->writesize; - int cached = writelen > bytes && page != blockmask; - uint8_t *wbuf = buf; - - /* Partial page write ? */ - if (unlikely(column || writelen < (mtd->writesize - 1))) { - cached = 0; - bytes = min_t(int, bytes - column, (int) writelen); - chip->pagebuf = -1; - memset(chip->buffers->databuf, 0xff, mtd->writesize); - memcpy(&chip->buffers->databuf[column], buf, bytes); - wbuf = chip->buffers->databuf; - } - - if (unlikely(oob)) - oob = nand_fill_oob(chip, oob, ops); - - ret = chip->write_page(mtd, chip, wbuf, page, cached, - (ops->mode == MTD_OOB_RAW)); - if (ret) - break; - - writelen -= bytes; - if (!writelen) - break; - - column = 0; - buf += bytes; - realpage++; - - page = realpage & chip->pagemask; - /* Check, if we cross a chip boundary */ - if (!page) { - chipnr++; - chip->select_chip(mtd, -1); - chip->select_chip(mtd, chipnr); - } - } - - ops->retlen = ops->len - writelen; - if (unlikely(oob)) - ops->oobretlen = ops->ooblen; - return ret; -} - -/* XXX U-BOOT XXX */ -#if 0 -/** - * nand_write_opts: - write image to NAND flash with support for various options - * - * @param meminfo NAND device to erase - * @param opts write options (@see nand_write_options) - * @return 0 in case of success - * - * This code is ported from nandwrite.c from Linux mtd utils by - * Steven J. Hill and Thomas Gleixner. - */ -int nand_write_opts(nand_info_t *meminfo, const nand_write_options_t *opts) -{ - int imglen = 0; - int pagelen; - int baderaseblock; - int blockstart = -1; - loff_t offs; - int readlen; - int ecclayoutchanged = 0; - int percent_complete = -1; - struct nand_ecclayout old_ecclayout; - ulong mtdoffset = opts->offset; - ulong erasesize_blockalign; - u_char *buffer = opts->buffer; - size_t written; - int result; - - if (opts->pad && opts->writeoob) { - printf("Can't pad when oob data is present.\n"); - return -1; - } - - /* set erasesize to specified number of blocks - to match - * jffs2 (virtual) block size */ - if (opts->blockalign == 0) { - erasesize_blockalign = meminfo->erasesize; - } else { - erasesize_blockalign = meminfo->erasesize * opts->blockalign; - } - - /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) - && !(meminfo->oobsize == 8 && meminfo->writesize == 256) - && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { - printf("Unknown flash (not normal NAND)\n"); - return -1; - } - - /* read the current oob info */ - memcpy(&old_ecclayout, &meminfo->ecclayout, sizeof(old_ecclayout)); - - /* write without ecc? */ - if (opts->noecc) { - memcpy(&meminfo->ecclayout, &none_ecclayout, - sizeof(meminfo->ecclayout)); - ecclayoutchanged = 1; - } - - /* autoplace ECC? */ - if (opts->autoplace && (old_ecclayout.useecc != MTD_NANDECC_AUTOPLACE)) { - - memcpy(&meminfo->ecclayout, &autoplace_ecclayout, - sizeof(meminfo->ecclayout)); - ecclayoutchanged = 1; - } - - /* force OOB layout for jffs2 or yaffs? */ - if (opts->forcejffs2 || opts->forceyaffs) { - struct nand_ecclayout *oobsel = - opts->forcejffs2 ? &jffs2_ecclayout : &yaffs_ecclayout; - - if (meminfo->oobsize == 8) { - if (opts->forceyaffs) { - printf("YAFSS cannot operate on " - "256 Byte page size\n"); - goto restoreoob; - } - /* Adjust number of ecc bytes */ - jffs2_ecclayout.eccbytes = 3; - } - - memcpy(&meminfo->ecclayout, oobsel, sizeof(meminfo->ecclayout)); - } - - /* get image length */ - imglen = opts->length; - pagelen = meminfo->writesize - + ((opts->writeoob != 0) ? meminfo->oobsize : 0); - - /* check, if file is pagealigned */ - if ((!opts->pad) && ((imglen % pagelen) != 0)) { - printf("Input block length is not page aligned\n"); - goto restoreoob; - } - - /* check, if length fits into device */ - if (((imglen / pagelen) * meminfo->writesize) - > (meminfo->size - opts->offset)) { - printf("Image %d bytes, NAND page %d bytes, " - "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->writesize, meminfo->size); - printf("Input block does not fit into device\n"); - goto restoreoob; - } - - if (!opts->quiet) - printf("\n"); - - /* get data from input and write to the device */ - while (imglen && (mtdoffset < meminfo->size)) { - - WATCHDOG_RESET (); - - /* - * new eraseblock, check for bad block(s). Stay in the - * loop to be sure if the offset changes because of - * a bad block, that the next block that will be - * written to is also checked. Thus avoiding errors if - * the block(s) after the skipped block(s) is also bad - * (number of blocks depending on the blockalign - */ - while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) { - blockstart = mtdoffset & (~erasesize_blockalign+1); - offs = blockstart; - baderaseblock = 0; - - /* check all the blocks in an erase block for - * bad blocks */ - do { - int ret = meminfo->block_isbad(meminfo, offs); - - if (ret < 0) { - printf("Bad block check failed\n"); - goto restoreoob; - } - if (ret == 1) { - baderaseblock = 1; - if (!opts->quiet) - printf("\rBad block at 0x%lx " - "in erase block from " - "0x%x will be skipped\n", - (long) offs, - blockstart); - } - - if (baderaseblock) { - mtdoffset = blockstart - + erasesize_blockalign; - } - offs += erasesize_blockalign - / opts->blockalign; - } while (offs < blockstart + erasesize_blockalign); - } - - readlen = meminfo->writesize; - if (opts->pad && (imglen < readlen)) { - readlen = imglen; - memset(data_buf + readlen, 0xff, - meminfo->writesize - readlen); - } - - /* read page data from input memory buffer */ - memcpy(data_buf, buffer, readlen); - buffer += readlen; - - if (opts->writeoob) { - /* read OOB data from input memory block, exit - * on failure */ - memcpy(oob_buf, buffer, meminfo->oobsize); - buffer += meminfo->oobsize; - - /* write OOB data first, as ecc will be placed - * in there*/ - result = meminfo->write_oob(meminfo, - mtdoffset, - meminfo->oobsize, - &written, - (unsigned char *) - &oob_buf); - - if (result != 0) { - printf("\nMTD writeoob failure: %d\n", - result); - goto restoreoob; - } - imglen -= meminfo->oobsize; - } - - /* write out the page data */ - result = meminfo->write(meminfo, - mtdoffset, - meminfo->writesize, - &written, - (unsigned char *) &data_buf); - - if (result != 0) { - printf("writing NAND page at offset 0x%lx failed\n", - mtdoffset); - goto restoreoob; - } - imglen -= readlen; - - if (!opts->quiet) { - unsigned long long n = (unsigned long long) - (opts->length-imglen) * 100; - int percent; - - do_div(n, opts->length); - percent = (int)n; - - /* output progress message only at whole percent - * steps to reduce the number of messages printed - * on (slow) serial consoles - */ - if (percent != percent_complete) { - printf("\rWriting data at 0x%lx " - "-- %3d%% complete.", - mtdoffset, percent); - percent_complete = percent; - } - } - - mtdoffset += meminfo->writesize; - } - - if (!opts->quiet) - printf("\n"); - -restoreoob: - if (ecclayoutchanged) { - memcpy(&meminfo->ecclayout, &old_ecclayout, - sizeof(meminfo->ecclayout)); - } - - if (imglen > 0) { - printf("Data did not fit into device, due to bad blocks\n"); - return -1; - } - - /* return happy */ - return 0; -} - -/** - * nand_read_opts: - read image from NAND flash with support for various options - * - * @param meminfo NAND device to erase - * @param opts read options (@see struct nand_read_options) - * @return 0 in case of success - * - */ -int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts) -{ - int imglen = opts->length; - int pagelen; - int baderaseblock; - int blockstart = -1; - int percent_complete = -1; - loff_t offs; - size_t readlen; - ulong mtdoffset = opts->offset; - u_char *buffer = opts->buffer; - int result; - - /* make sure device page sizes are valid */ - if (!(meminfo->oobsize == 16 && meminfo->writesize == 512) - && !(meminfo->oobsize == 8 && meminfo->writesize == 256) - && !(meminfo->oobsize == 64 && meminfo->writesize == 2048)) { - printf("Unknown flash (not normal NAND)\n"); - return -1; - } - - pagelen = meminfo->writesize - + ((opts->readoob != 0) ? meminfo->oobsize : 0); - - /* check, if length is not larger than device */ - if (((imglen / pagelen) * meminfo->writesize) - > (meminfo->size - opts->offset)) { - printf("Image %d bytes, NAND page %d bytes, " - "OOB area %u bytes, device size %u bytes\n", - imglen, pagelen, meminfo->writesize, meminfo->size); - printf("Input block is larger than device\n"); - return -1; - } - - if (!opts->quiet) - printf("\n"); - - /* get data from input and write to the device */ - while (imglen && (mtdoffset < meminfo->size)) { - - WATCHDOG_RESET (); - - /* - * new eraseblock, check for bad block(s). Stay in the - * loop to be sure if the offset changes because of - * a bad block, that the next block that will be - * written to is also checked. Thus avoiding errors if - * the block(s) after the skipped block(s) is also bad - * (number of blocks depending on the blockalign - */ - while (blockstart != (mtdoffset & (~meminfo->erasesize+1))) { - blockstart = mtdoffset & (~meminfo->erasesize+1); - offs = blockstart; - baderaseblock = 0; - - /* check all the blocks in an erase block for - * bad blocks */ - do { - int ret = meminfo->block_isbad(meminfo, offs); - - if (ret < 0) { - printf("Bad block check failed\n"); - return -1; - } - if (ret == 1) { - baderaseblock = 1; - if (!opts->quiet) - printf("\rBad block at 0x%lx " - "in erase block from " - "0x%x will be skipped\n", - (long) offs, - blockstart); - } - - if (baderaseblock) { - mtdoffset = blockstart - + meminfo->erasesize; - } - offs += meminfo->erasesize; - - } while (offs < blockstart + meminfo->erasesize); - } - - - /* read page data to memory buffer */ - result = meminfo->read(meminfo, - mtdoffset, - meminfo->writesize, - &readlen, - (unsigned char *) &data_buf); - - if (result != 0) { - printf("reading NAND page at offset 0x%lx failed\n", - mtdoffset); - return -1; - } - - if (imglen < readlen) { - readlen = imglen; - } - - memcpy(buffer, data_buf, readlen); - buffer += readlen; - imglen -= readlen; - - if (opts->readoob) { - result = meminfo->read_oob(meminfo, - mtdoffset, - meminfo->oobsize, - &readlen, - (unsigned char *) - &oob_buf); - - if (result != 0) { - printf("\nMTD readoob failure: %d\n", - result); - return -1; - } - - - if (imglen < readlen) { - readlen = imglen; - } - - memcpy(buffer, oob_buf, readlen); - - buffer += readlen; - imglen -= readlen; - } - - if (!opts->quiet) { - unsigned long long n = (unsigned long long) - (opts->length-imglen) * 100; - int percent; - - do_div(n, opts->length); - percent = (int)n; - - /* output progress message only at whole percent - * steps to reduce the number of messages printed - * on (slow) serial consoles - */ - if (percent != percent_complete) { - if (!opts->quiet) - printf("\rReading data from 0x%lx " - "-- %3d%% complete.", - mtdoffset, percent); - percent_complete = percent; - } - } - - mtdoffset += meminfo->writesize; - } - - if (!opts->quiet) - printf("\n"); - - if (imglen > 0) { - printf("Could not read entire image due to bad blocks\n"); - return -1; - } - - /* return happy */ - return 0; -} -#endif - /* XXX U-BOOT XXX */ #if 0 /****************************************************************************** @@ -1007,4 +427,184 @@ int nand_unlock(nand_info_t *meminfo, ulong start, ulong length) } #endif -#endif +/** + * get_len_incl_bad + * + * Check if length including bad blocks fits into device. + * + * @param nand NAND device + * @param offset offset in flash + * @param length image length + * @return image length including bad blocks + */ +static size_t get_len_incl_bad (nand_info_t *nand, size_t offset, + const size_t length) +{ + size_t len_incl_bad = 0; + size_t len_excl_bad = 0; + size_t block_len; + + while (len_excl_bad < length) { + block_len = nand->erasesize - (offset & (nand->erasesize - 1)); + + if (!nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) + len_excl_bad += block_len; + + len_incl_bad += block_len; + offset += block_len; + + if ((offset + len_incl_bad) >= nand->size) + break; + } + + return len_incl_bad; +} + +/** + * nand_write_skip_bad: + * + * Write image to NAND flash. + * Blocks that are marked bad are skipped and the is written to the next + * block instead as long as the image is short enough to fit even after + * skipping the bad blocks. + * + * @param nand NAND device + * @param offset offset in flash + * @param length buffer length + * @param buf buffer to read from + * @return 0 in case of success + */ +int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer) +{ + int rval; + size_t left_to_write = *length; + size_t len_incl_bad; + u_char *p_buffer = buffer; + + /* Reject writes, which are not page aligned */ + if ((offset & (nand->writesize - 1)) != 0 || + (*length & (nand->writesize - 1)) != 0) { + printf ("Attempt to write non page aligned data\n"); + return -EINVAL; + } + + len_incl_bad = get_len_incl_bad (nand, offset, *length); + + if ((offset + len_incl_bad) >= nand->size) { + printf ("Attempt to write outside the flash area\n"); + return -EINVAL; + } + + if (len_incl_bad == *length) { + rval = nand_write (nand, offset, length, buffer); + if (rval != 0) { + printf ("NAND write to offset %x failed %d\n", + offset, rval); + return rval; + } + } + + while (left_to_write > 0) { + size_t block_offset = offset & (nand->erasesize - 1); + size_t write_size; + + if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { + printf ("Skip bad block 0x%08x\n", + offset & ~(nand->erasesize - 1)); + offset += nand->erasesize - block_offset; + continue; + } + + if (left_to_write < (nand->erasesize - block_offset)) + write_size = left_to_write; + else + write_size = nand->erasesize - block_offset; + + rval = nand_write (nand, offset, &write_size, p_buffer); + if (rval != 0) { + printf ("NAND write to offset %x failed %d\n", + offset, rval); + *length -= left_to_write; + return rval; + } + + left_to_write -= write_size; + offset += write_size; + p_buffer += write_size; + } + + return 0; +} + +/** + * nand_read_skip_bad: + * + * Read image from NAND flash. + * Blocks that are marked bad are skipped and the next block is readen + * instead as long as the image is short enough to fit even after skipping the + * bad blocks. + * + * @param nand NAND device + * @param offset offset in flash + * @param length buffer length, on return holds remaining bytes to read + * @param buffer buffer to write to + * @return 0 in case of success + */ +int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer) +{ + int rval; + size_t left_to_read = *length; + size_t len_incl_bad; + u_char *p_buffer = buffer; + + len_incl_bad = get_len_incl_bad (nand, offset, *length); + + if ((offset + len_incl_bad) >= nand->size) { + printf ("Attempt to read outside the flash area\n"); + return -EINVAL; + } + + if (len_incl_bad == *length) { + rval = nand_read (nand, offset, length, buffer); + if (rval != 0) { + printf ("NAND read from offset %x failed %d\n", + offset, rval); + return rval; + } + } + + while (left_to_read > 0) { + size_t block_offset = offset & (nand->erasesize - 1); + size_t read_length; + + if (nand_block_isbad (nand, offset & ~(nand->erasesize - 1))) { + printf ("Skipping bad block 0x%08x\n", + offset & ~(nand->erasesize - 1)); + offset += nand->erasesize - block_offset; + continue; + } + + if (left_to_read < (nand->erasesize - block_offset)) + read_length = left_to_read; + else + read_length = nand->erasesize - block_offset; + + rval = nand_read (nand, offset, &read_length, p_buffer); + if (rval != 0) { + printf ("NAND read from offset %x failed %d\n", + offset, rval); + *length -= left_to_read; + return rval; + } + + left_to_read -= read_length; + offset += read_length; + p_buffer += read_length; + } + + return 0; +} + +#endif /* defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) */ diff --git a/include/nand.h b/include/nand.h index 83d597dc7db..d5af4324cb2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -108,9 +108,10 @@ struct nand_erase_options { typedef struct nand_erase_options nand_erase_options_t; -int nand_write_opts(nand_info_t *mtd, loff_t to, mtd_oob_ops_t *ops); - -int nand_read_opts(nand_info_t *meminfo, const nand_read_options_t *opts); +int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer); +int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length, + u_char *buffer); int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts); #define NAND_LOCK_STATUS_TIGHT 0x01 -- cgit v1.3.1 From 13f0fd94e3cae6f8a0d9fba5d367e311edc8ebde Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Mon, 30 Jun 2008 15:34:40 +0200 Subject: NAND: Scan bad blocks lazily. Rather than scanning on boot, scan upon the first attempt to check the badness of a block. This speeds up boot when not using NAND, and reduces the likelihood of needing to reflash via JTAG if NAND becomes nonfunctional. Signed-off-by: Ilya Yanok Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 10 +++++++--- include/linux/mtd/nand.h | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 7bceea8ac3d..cf2f3745542 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -457,6 +457,11 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, { struct nand_chip *chip = mtd->priv; + if (!(chip->options & NAND_BBT_SCANNED)) { + chip->scan_bbt(mtd); + chip->options |= NAND_BBT_SCANNED; + } + if (!chip->bbt) return chip->block_bad(mtd, ofs, getchip); @@ -2721,10 +2726,9 @@ int nand_scan_tail(struct mtd_info *mtd) /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) - return 0; + chip->options |= NAND_BBT_SCANNED; - /* Build bad block table */ - return chip->scan_bbt(mtd); + return 0; } /* module_text_address() isn't exported, and it's mostly a pointless diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index f9b7d36a73a..2993a89e1b3 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -204,6 +204,8 @@ typedef enum { (e.g. because it needs them DMA-coherent */ #define NAND_OWN_BUFFERS 0x00040000 /* Options set by nand scan */ +/* bbt has already been read */ +#define NAND_BBT_SCANNED 0x40000000 /* Nand scan has allocated controller struct */ #define NAND_CONTROLLER_ALLOC 0x80000000 -- cgit v1.3.1 From eafcabd15f00c142156235c519fcc55b10993241 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Sun, 22 Jun 2008 16:30:06 +0200 Subject: NAND: chip->state does not always get set. Fixes an issue with chip->state not always being set causing troubles. Signed-off-by: Marcel Ziswiler Signed-off-by: Scott Wood --- drivers/mtd/nand/nand_base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index cf2f3745542..a29ff1146f2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -773,6 +773,7 @@ nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) #else static int nand_get_device (struct nand_chip *this, struct mtd_info *mtd, int new_state) { + this->state = new_state; return 0; } #endif -- cgit v1.3.1 From 195ccfc5991d48764b2519941e3507f693851d5d Mon Sep 17 00:00:00 2001 From: Fathi BOUDRA Date: Wed, 6 Aug 2008 10:06:20 +0200 Subject: OneNAND: Fill in MTD function pointers for OneNAND. onenand_print_device_info(): - Now returns a string to be placed in mtd->name, rather than calling printf. - Remove verbose parameter as it becomes useless. Signed-off-by: Fathi Boudra Signed-off-by: Scott Wood --- common/cmd_onenand.c | 2 +- drivers/mtd/onenand/onenand_base.c | 24 ++++++++++++++++++------ include/onenand_uboot.h | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index d6d337628ec..419bf70988f 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -38,7 +38,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) onenand_init(); return 0; } - onenand_print_device_info(onenand_chip.device_id, 1); + printf("%s\n", onenand_mtd.name); return 0; default: diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index a7054aebca6..ded1706abbe 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -19,6 +19,7 @@ #include #include +#include /* It should access 16-bit instead of 8-bit */ static inline void *memcpy_16(void *dst, const void *src, unsigned int len) @@ -1110,21 +1111,21 @@ int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) * * Print device ID */ -void onenand_print_device_info(int device, int verbose) +char * onenand_print_device_info(int device) { int vcc, demuxed, ddp, density; - - if (!verbose) - return; + char *dev_info = malloc(80); vcc = device & ONENAND_DEVICE_VCC_MASK; demuxed = device & ONENAND_DEVICE_IS_DEMUX; ddp = device & ONENAND_DEVICE_IS_DDP; density = device >> ONENAND_DEVICE_DENSITY_SHIFT; - printk(KERN_INFO "%sOneNAND%s %dMB %sV 16-bit (0x%02x)\n", + sprintf(dev_info, "%sOneNAND%s %dMB %sV 16-bit (0x%02x)", demuxed ? "" : "Muxed ", ddp ? "(DDP)" : "", (16 << density), vcc ? "2.65/3.3" : "1.8", device); + + return dev_info; } static const struct onenand_manufacturers onenand_manuf_ids[] = { @@ -1203,7 +1204,7 @@ static int onenand_probe(struct mtd_info *mtd) } /* Flash device information */ - onenand_print_device_info(dev_id, 0); + mtd->name = onenand_print_device_info(dev_id); this->device_id = dev_id; density = dev_id >> ONENAND_DEVICE_DENSITY_SHIFT; @@ -1239,6 +1240,17 @@ static int onenand_probe(struct mtd_info *mtd) this->options |= ONENAND_CONT_LOCK; } + mtd->erase = onenand_erase; + mtd->read = onenand_read; + mtd->write = onenand_write; + mtd->read_ecc = onenand_read_ecc; + mtd->write_ecc = onenand_write_ecc; + mtd->read_oob = onenand_read_oob; + mtd->write_oob = onenand_write_oob; + mtd->sync = onenand_sync; + mtd->block_isbad = onenand_block_isbad; + mtd->block_markbad = onenand_block_markbad; + return 0; } diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h index 4449f987bf7..4260ee7eb44 100644 --- a/include/onenand_uboot.h +++ b/include/onenand_uboot.h @@ -39,6 +39,6 @@ extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr); extern int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); -extern void onenand_print_device_info(int device, int verbose); +extern char *onenand_print_device_info(int device); #endif /* __UBOOT_ONENAND_H */ -- cgit v1.3.1 From 6c58a030f86829fa4f0d4337cf4b794c41a1823e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:38 +0200 Subject: serial: move CFG_SCIF_CONSOLE to CONFIG_SCIF_CONSOLE move also conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/serial/Makefile | 2 +- drivers/serial/serial_sh.c | 4 ---- include/configs/MigoR.h | 2 +- include/configs/mpr2.h | 2 +- include/configs/ms7720se.h | 2 +- include/configs/ms7722se.h | 2 +- include/configs/ms7750se.h | 2 +- include/configs/r2dplus.h | 2 +- include/configs/r7780mp.h | 2 +- include/configs/sh7763rdp.h | 2 +- 10 files changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index de6fbab740c..3716974c62e 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -35,7 +35,7 @@ COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o COBJS-y += serial_pl010.o COBJS-y += serial_pl011.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o -COBJS-y += serial_sh.o +COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o COBJS-$(CONFIG_USB_TTY) += usbtty.o COBJS := $(COBJS-y) diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 0801ac4a8c8..2b9eeed47e0 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -20,8 +20,6 @@ #include #include -#ifdef CFG_SCIF_CONSOLE - #if defined (CONFIG_CONS_SCIF0) #define SCIF_BASE SCIF0_BASE #elif defined (CONFIG_CONS_SCIF1) @@ -215,5 +213,3 @@ int serial_getc(void) return ch; } - -#endif /* CFG_SCIF_CONSOLE */ diff --git a/include/configs/MigoR.h b/include/configs/MigoR.h index fa0e5db0216..ffa9b54e135 100644 --- a/include/configs/MigoR.h +++ b/include/configs/MigoR.h @@ -67,7 +67,7 @@ #define CFG_BAUDRATE_TABLE { 115200 } /* List of legal baudrate settings for this board */ /* SCIF */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_CONS_SCIF0 1 #undef CFG_CONSOLE_INFO_QUIET /* Suppress display of console information at boot */ diff --git a/include/configs/mpr2.h b/include/configs/mpr2.h index 0fc0b970dba..2598b342f41 100644 --- a/include/configs/mpr2.h +++ b/include/configs/mpr2.h @@ -86,7 +86,7 @@ #define CFG_HZ (CONFIG_SYS_CLK_FREQ / TMU_CLK_DIVIDER) /* UART */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_CONS_SCIF0 1 #endif /* __MPR2_H */ diff --git a/include/configs/ms7720se.h b/include/configs/ms7720se.h index 5e79a271115..dc0af1594ee 100644 --- a/include/configs/ms7720se.h +++ b/include/configs/ms7720se.h @@ -63,7 +63,7 @@ #define CFG_BAUDRATE_TABLE { 115200 } /* SCIF */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_CONS_SCIF0 1 #define CFG_MEMTEST_START MS7720SE_SDRAM_BASE diff --git a/include/configs/ms7722se.h b/include/configs/ms7722se.h index 7298e55c708..910a44eb4a5 100644 --- a/include/configs/ms7722se.h +++ b/include/configs/ms7722se.h @@ -62,7 +62,7 @@ #define CFG_BAUDRATE_TABLE { 115200 } /* List of legal baudrate settings for this board */ /* SCIF */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_CONS_SCIF0 1 #undef CFG_CONSOLE_INFO_QUIET /* Suppress display of console information at boot */ #undef CFG_CONSOLE_OVERWRITE_ROUTINE diff --git a/include/configs/ms7750se.h b/include/configs/ms7750se.h index 3000c77c119..bee0aab1334 100644 --- a/include/configs/ms7750se.h +++ b/include/configs/ms7750se.h @@ -42,7 +42,7 @@ #define CONFIG_CMD_FLASH #define CONFIG_CMD_ENV -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_BAUDRATE 38400 #define CONFIG_CONS_SCIF1 1 #define BOARD_LATE_INIT 1 diff --git a/include/configs/r2dplus.h b/include/configs/r2dplus.h index e269336e82a..414e8dca571 100644 --- a/include/configs/r2dplus.h +++ b/include/configs/r2dplus.h @@ -26,7 +26,7 @@ #define CONFIG_DOS_PARTITION /* SCIF */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_BAUDRATE 115200 #define CONFIG_CONS_SCIF1 1 #define BOARD_LATE_INIT 1 diff --git a/include/configs/r7780mp.h b/include/configs/r7780mp.h index 4c82c5a2fdc..0b08f18be17 100644 --- a/include/configs/r7780mp.h +++ b/include/configs/r7780mp.h @@ -49,7 +49,7 @@ #define CONFIG_CMD_EXT2 #define CONFIG_DOS_PARTITION -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_BAUDRATE 115200 #define CONFIG_CONS_SCIF0 1 diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h index 5a6566320aa..47236341bdf 100644 --- a/include/configs/sh7763rdp.h +++ b/include/configs/sh7763rdp.h @@ -52,7 +52,7 @@ #undef CONFIG_SHOW_BOOT_PROGRESS /* SCIF */ -#define CFG_SCIF_CONSOLE 1 +#define CONFIG_SCIF_CONSOLE 1 #define CONFIG_BAUDRATE 115200 #define CONFIG_CONS_SCIF2 1 -- cgit v1.3.1 From 1a6ffbfaf4353bec379ed1fcfc54b6f1a30af09a Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:39 +0200 Subject: serial: move CFG_NS9750_UART to CONFIG_NS9750_UART move also conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/serial/Makefile | 2 +- drivers/serial/ns9750_serial.c | 4 ---- include/configs/ns9750dev.h | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 3716974c62e..2384735a2ce 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -27,7 +27,7 @@ LIB := $(obj)libserial.a COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o COBJS-$(CONFIG_MCFUART) += mcfuart.o -COBJS-y += ns9750_serial.o +COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o COBJS-y += ns16550.o COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o COBJS-y += serial.o diff --git a/drivers/serial/ns9750_serial.c b/drivers/serial/ns9750_serial.c index 02c0d395209..e9645a053de 100644 --- a/drivers/serial/ns9750_serial.c +++ b/drivers/serial/ns9750_serial.c @@ -28,8 +28,6 @@ #include -#ifdef CFG_NS9750_UART - #include "ns9750_bbus.h" /* for GPIOs */ #include "ns9750_ser.h" /* for serial configuration */ @@ -210,5 +208,3 @@ static unsigned int calcRxCharGapRegister( void ) { return NS9750_SER_RX_CHAR_TIMER_TRUN; } - -#endif /* CFG_NS9750_UART */ diff --git a/include/configs/ns9750dev.h b/include/configs/ns9750dev.h index f30cb46cf7c..746a56e9aa3 100644 --- a/include/configs/ns9750dev.h +++ b/include/configs/ns9750dev.h @@ -56,7 +56,7 @@ /* * Hardware drivers */ -#define CFG_NS9750_UART 1 /* use on-chip UART */ +#define CONFIG_NS9750_UART 1 /* use on-chip UART */ #define CONFIG_DRIVER_NS9750_ETHERNET 1 /* use on-chip ethernet */ /* -- cgit v1.3.1 From 1a02806c4b1b4a09ad4e95d3aac3783889e5f8d7 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:39 +0200 Subject: drivers/block: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/block/Makefile | 10 +++++----- drivers/block/ahci.c | 3 --- drivers/block/ata_piix.c | 4 ---- drivers/block/sil680.c | 5 +---- drivers/block/sym53c8xx.c | 5 ----- drivers/block/systemace.c | 3 --- include/configs/sc520_cdp.h | 2 +- 7 files changed, 7 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a09cd2a603b..642582b0881 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -25,14 +25,14 @@ include $(TOPDIR)/config.mk LIB := $(obj)libblock.a -COBJS-y += ahci.o -COBJS-y += ata_piix.o +COBJS-$(CONFIG_SCSI_AHCI) += ahci.o +COBJS-$(CONFIG_ATA_PIIX) += ata_piix.o COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o COBJS-$(CONFIG_LIBATA) += libata.o COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o -COBJS-y += sil680.o -COBJS-y += sym53c8xx.o -COBJS-y += systemace.o +COBJS-$(CONFIG_IDE_SIL680) += sil680.o +COBJS-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o +COBJS-$(CONFIG_SYSTEMACE) += systemace.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 3d82c625a35..52fd1080e61 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -26,8 +26,6 @@ */ #include -#ifdef CONFIG_SCSI_AHCI - #include #include #include @@ -700,4 +698,3 @@ void scsi_print_error(ccb * pccb) { /*The ahci error info can be read in the ahci driver*/ } -#endif diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index 441a4dcd8d6..4c26b36f5ab 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -35,8 +35,6 @@ #include #include -#ifdef CFG_ATA_PIIX /*ata_piix driver */ - extern block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE]; extern int curr_device; @@ -756,5 +754,3 @@ int scan_sata(int dev) { return 0; } - -#endif diff --git a/drivers/block/sil680.c b/drivers/block/sil680.c index a6143df4c06..052c3d3671a 100644 --- a/drivers/block/sil680.c +++ b/drivers/block/sil680.c @@ -27,7 +27,7 @@ * The following parameters must be defined in the configuration file * of the target board: * - * #define CFG_IDE_SIL680 + * #define CONFIG_IDE_SIL680 * * #define CONFIG_PCI_PNP * NOTE it may also be necessary to define this if the default of 8 is @@ -54,7 +54,6 @@ */ #include -#if defined(CFG_IDE_SIL680) #include #include #include @@ -106,5 +105,3 @@ int ide_preinit (void) void ide_set_reset (int flag) { return; } - -#endif /* CFG_IDE_SIL680 */ diff --git a/drivers/block/sym53c8xx.c b/drivers/block/sym53c8xx.c index b880435f1ec..44e998b5564 100644 --- a/drivers/block/sym53c8xx.c +++ b/drivers/block/sym53c8xx.c @@ -35,8 +35,6 @@ #include -#ifdef CONFIG_SCSI_SYM53C8XX - #include #include #include @@ -870,6 +868,3 @@ void scsi_chip_init(void) #endif } #endif - - -#endif /* CONFIG_SCSI_SYM53C8XX */ diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c index 7d82c27c6ed..dfaab528bf4 100644 --- a/drivers/block/systemace.c +++ b/drivers/block/systemace.c @@ -44,8 +44,6 @@ #include #include -#ifdef CONFIG_SYSTEMACE - /* * The ace_readw and writew functions read/write 16bit words, but the * offset value is the BYTE offset as most used in the Xilinx @@ -255,4 +253,3 @@ static unsigned long systemace_read(int dev, unsigned long start, return blkcnt; } -#endif /* CONFIG_SYSTEMACE */ diff --git a/include/configs/sc520_cdp.h b/include/configs/sc520_cdp.h index 0e830b878d4..e29655e6362 100644 --- a/include/configs/sc520_cdp.h +++ b/include/configs/sc520_cdp.h @@ -178,7 +178,7 @@ #define CFG_SATA_MAXBUS 2 /*Max Sata buses supported */ #define CFG_SATA_DEVS_PER_BUS 2 /*Max no. of devices per bus/port */ #define CFG_SATA_MAX_DEVICE (CFG_SATA_MAXBUS* CFG_SATA_DEVS_PER_BUS) -#define CFG_ATA_PIIX 1 /*Supports ata_piix driver */ +#define CONFIG_ATA_PIIX 1 /*Supports ata_piix driver */ /************************************************************ * DISK Partition support -- cgit v1.3.1 From 88f57e093114a44aa9a858d52b099bcc52034a8c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:39 +0200 Subject: drivers/dma: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/dma/MCD_dmaApi.c | 3 --- drivers/dma/MCD_tasks.c | 4 ---- drivers/dma/MCD_tasksInit.c | 4 ---- drivers/dma/Makefile | 2 +- 4 files changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/MCD_dmaApi.c b/drivers/dma/MCD_dmaApi.c index b0062b77329..5c95651d580 100644 --- a/drivers/dma/MCD_dmaApi.c +++ b/drivers/dma/MCD_dmaApi.c @@ -24,8 +24,6 @@ #include -#ifdef CONFIG_FSLDMAFEC - #include #include #include @@ -1023,4 +1021,3 @@ static void MCD_memcpy(int *dest, int *src, u32 size) for (i = 0; i < size; i += sizeof(int), dest++, src++) *dest = *src; } -#endif /* CONFIG_FSLDMAFEC */ diff --git a/drivers/dma/MCD_tasks.c b/drivers/dma/MCD_tasks.c index 06a2d532648..4f6e3462614 100644 --- a/drivers/dma/MCD_tasks.c +++ b/drivers/dma/MCD_tasks.c @@ -24,8 +24,6 @@ #include -#ifdef CONFIG_FSLDMAFEC - #include u32 MCD_varTab0[]; @@ -2430,5 +2428,3 @@ u32 MCD_ENetXmit_TDT[] = { #ifdef MCD_INCLUDE_EU MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; #endif - -#endif /* CONFIG_FSLDMAFEC */ diff --git a/drivers/dma/MCD_tasksInit.c b/drivers/dma/MCD_tasksInit.c index cf567db5a0b..2f198754e58 100644 --- a/drivers/dma/MCD_tasksInit.c +++ b/drivers/dma/MCD_tasksInit.c @@ -28,8 +28,6 @@ * Do not edit! */ -#ifdef CONFIG_FSLDMAFEC - #include extern dmaRegs *MCD_dmaBar; @@ -242,5 +240,3 @@ void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, /* Set the task's Enable bit in its Task Control Register */ MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; } - -#endif /* CONFIG_FSLDMAFEC */ diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 7e17360de54..cf29efa0272 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB := $(obj)libdma.a -COBJS-y += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o +COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) -- cgit v1.3.1 From 65e41ea0548b86e3d7892defac8e4dc1ea70aed1 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:40 +0200 Subject: drivers/input: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/input/Makefile | 8 +++++--- drivers/input/i8042.c | 4 ---- drivers/input/keyboard.c | 4 ---- drivers/input/pc_keyb.c | 4 ---- drivers/input/ps2mult.c | 4 ---- drivers/input/ps2ser.c | 4 ---- 6 files changed, 5 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/input/Makefile b/drivers/input/Makefile index 2933cb6451d..9a144073999 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -25,9 +25,11 @@ include $(TOPDIR)/config.mk LIB := $(obj)libinput.a -COBJS-y += i8042.o -COBJS-y += keyboard.o -COBJS-y += pc_keyb.o ps2ser.o ps2mult.o +COBJS-$(CONFIG_I8042_KBD) += i8042.o +ifdef CONFIG_PS2KBD +COBJS-y += keyboard.o pc_keyb.o +COBJS-$(CONFIG_PS2MULT) += ps2mult.o ps2ser.o +endif COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c index 22c2a4e3a02..d152768b8e0 100644 --- a/drivers/input/i8042.c +++ b/drivers/input/i8042.c @@ -27,8 +27,6 @@ #include -#ifdef CONFIG_I8042_KBD - #ifdef CONFIG_USE_CPCIDVI extern u8 gt_cpcidvi_in8(u32 offset); extern void gt_cpcidvi_out8(u32 offset, u8 data); @@ -670,5 +668,3 @@ static int kbd_reset (void) return 0; } - -#endif /* CONFIG_I8042_KBD */ diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c index 54182a79b1d..a634d76d6c2 100644 --- a/drivers/input/keyboard.c +++ b/drivers/input/keyboard.c @@ -11,8 +11,6 @@ #include -#ifdef CONFIG_PS2KBD - #include #include @@ -301,5 +299,3 @@ int kbd_init (void) } return error; } - -#endif /* CONFIG_PS2KBD */ diff --git a/drivers/input/pc_keyb.c b/drivers/input/pc_keyb.c index 33e7c5f1248..25ad3e40650 100644 --- a/drivers/input/pc_keyb.c +++ b/drivers/input/pc_keyb.c @@ -13,8 +13,6 @@ #include -#ifdef CONFIG_PS2KBD - #include #include @@ -252,5 +250,3 @@ void pckbd_leds(unsigned char leds) kbd_send_data(KBD_CMD_SET_LEDS); kbd_send_data(leds); } - -#endif /* CONFIG_PS2KBD */ diff --git a/drivers/input/ps2mult.c b/drivers/input/ps2mult.c index 9515a0fbf54..ecd585323f9 100644 --- a/drivers/input/ps2mult.c +++ b/drivers/input/ps2mult.c @@ -16,8 +16,6 @@ #include -#ifdef CONFIG_PS2MULT - #include #include #include @@ -462,5 +460,3 @@ int ps2mult_request_irq(void (*handler)(void *)) return 0; } - -#endif /* CONFIG_PS2MULT */ diff --git a/drivers/input/ps2ser.c b/drivers/input/ps2ser.c index c1741eac67d..480ffa25a2b 100644 --- a/drivers/input/ps2ser.c +++ b/drivers/input/ps2ser.c @@ -15,8 +15,6 @@ #include -#ifdef CONFIG_PS2SERIAL - #include #include #include @@ -326,5 +324,3 @@ static void ps2ser_interrupt(void *dev_id) ps2mult_callback(atomic_read(&ps2buf_cnt)); } } - -#endif /* CONFIG_PS2SERIAL */ -- cgit v1.3.1 From 55d6d2d39fe3fe87802e399aa17539368b495d2e Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:40 +0200 Subject: drivers/misc: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/misc/Makefile | 6 +++--- drivers/misc/ali512x.c | 5 ----- drivers/misc/ns87308.c | 4 ---- drivers/misc/status_led.c | 4 ---- drivers/serial/serial.c | 4 ++-- include/configs/BAB7xx.h | 2 +- include/configs/HIDDEN_DRAGON.h | 2 +- include/configs/Sandpoint8240.h | 2 +- include/configs/Sandpoint8245.h | 2 +- 9 files changed, 9 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index fe8d3d87e96..01e0f393d25 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -25,10 +25,10 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmisc.a -COBJS-y += ali512x.o -COBJS-y += ns87308.o -COBJS-y += status_led.o +COBJS-$(CONFIG_ALI152X) += ali512x.o COBJS-$(CONFIG_FSL_LAW) += fsl_law.o +COBJS-$(CONFIG_NS87308) += ns87308.o +COBJS-$(CONFIG_STATUS_LED) += status_led.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/misc/ali512x.c b/drivers/misc/ali512x.c index 90b45d98b8c..d6a2c1f5775 100644 --- a/drivers/misc/ali512x.c +++ b/drivers/misc/ali512x.c @@ -32,8 +32,6 @@ #include -#ifdef CONFIG_ALI152X - #include #include #include @@ -418,6 +416,3 @@ int ali512x_cio_in(int pin) return data & bit; } - - -#endif diff --git a/drivers/misc/ns87308.c b/drivers/misc/ns87308.c index cf4d3595e5d..6642c2e072d 100644 --- a/drivers/misc/ns87308.c +++ b/drivers/misc/ns87308.c @@ -23,8 +23,6 @@ #include -#ifdef CFG_NS87308 - #include void initialise_ns87308 (void) @@ -117,5 +115,3 @@ void initialise_ns87308 (void) PNP_PGCS_CSLINE_CONF(2, CFG_NS87308_CS2_CONF); #endif } - -#endif diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c index ddb6c22e890..4ba3e180440 100644 --- a/drivers/misc/status_led.c +++ b/drivers/misc/status_led.c @@ -35,8 +35,6 @@ /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_STATUS_LED - typedef struct { led_id_t mask; int state; @@ -127,5 +125,3 @@ void status_led_set (int led, int state) } __led_set (ld->mask, state); } - -#endif /* CONFIG_STATUS_LED */ diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 8bbfcf9c0cb..b361eef9a41 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -26,7 +26,7 @@ #ifdef CFG_NS16550_SERIAL #include -#ifdef CFG_NS87308 +#ifdef CONFIG_NS87308 #include #endif @@ -159,7 +159,7 @@ int serial_init (void) { int clock_divisor; -#ifdef CFG_NS87308 +#ifdef CONFIG_NS87308 initialise_ns87308(); #endif diff --git a/include/configs/BAB7xx.h b/include/configs/BAB7xx.h index 8ec70aa639c..799ce384726 100644 --- a/include/configs/BAB7xx.h +++ b/include/configs/BAB7xx.h @@ -346,7 +346,7 @@ extern unsigned char scsi_sym53c8xx_ccf; /* * NS87308 Configuration */ -#define CFG_NS87308 /* Nat Semi super-io cntr on ISA bus */ +#define CONFIG_NS87308 /* Nat Semi super-io cntr on ISA bus */ #define CFG_NS87308_BADDR_10 1 #define CFG_NS87308_DEVS (CFG_NS87308_UART1 | \ CFG_NS87308_UART2 | \ diff --git a/include/configs/HIDDEN_DRAGON.h b/include/configs/HIDDEN_DRAGON.h index 26dd954c18a..fea1f6c46a8 100644 --- a/include/configs/HIDDEN_DRAGON.h +++ b/include/configs/HIDDEN_DRAGON.h @@ -214,7 +214,7 @@ /* * NS87308 Configuration */ -#define CFG_NS87308 /* Nat Semi super-io controller on ISA bus */ +#define CONFIG_NS87308 /* Nat Semi super-io controller on ISA bus */ #define CFG_NS87308_BADDR_10 1 diff --git a/include/configs/Sandpoint8240.h b/include/configs/Sandpoint8240.h index 5bbe3c5919d..c5a57d36c71 100644 --- a/include/configs/Sandpoint8240.h +++ b/include/configs/Sandpoint8240.h @@ -246,7 +246,7 @@ /* * NS87308 Configuration */ -#define CFG_NS87308 /* Nat Semi super-io controller on ISA bus */ +#define CONFIG_NS87308 /* Nat Semi super-io controller on ISA bus */ #define CFG_NS87308_BADDR_10 1 diff --git a/include/configs/Sandpoint8245.h b/include/configs/Sandpoint8245.h index a08451eb30b..56853140c6e 100644 --- a/include/configs/Sandpoint8245.h +++ b/include/configs/Sandpoint8245.h @@ -214,7 +214,7 @@ /* * NS87308 Configuration */ -#define CFG_NS87308 /* Nat Semi super-io controller on ISA bus */ +#define CONFIG_NS87308 /* Nat Semi super-io controller on ISA bus */ #define CFG_NS87308_BADDR_10 1 -- cgit v1.3.1 From ab6878c7bc68a7b5e5b731655bdc13221bbfc493 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:40 +0200 Subject: drivers/pci: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/pci/Makefile | 10 ++++------ drivers/pci/fsl_pci_init.c | 4 ---- drivers/pci/pci.c | 4 ---- drivers/pci/pci_auto.c | 4 ---- drivers/pci/pci_indirect.c | 2 -- drivers/pci/tsi108_pci.c | 4 ---- drivers/pci/w83c553f.c | 4 ---- include/configs/BAB7xx.h | 2 +- include/configs/HIDDEN_DRAGON.h | 2 +- include/configs/Sandpoint8240.h | 2 +- include/configs/Sandpoint8245.h | 2 +- 11 files changed, 8 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index dec93b94d7e..bffb1eb1a13 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -25,15 +25,13 @@ include $(TOPDIR)/config.mk LIB := $(obj)libpci.a -COBJS-y += fsl_pci_init.o -COBJS-y += pci.o -COBJS-y += pci_auto.o -COBJS-y += pci_indirect.o -COBJS-y += tsi108_pci.o -COBJS-y += w83c553f.o +COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o +COBJS-$(CONFIG_PCI) += pci.o pci_auto.o pci_indirect.o COBJS-$(CONFIG_SH4_PCI) += pci_sh4.o COBJS-$(CONFIG_SH7751_PCI) +=pci_sh7751.o COBJS-$(CONFIG_SH7780_PCI) +=pci_sh7780.o +COBJS-$(CONFIG_TSI108_PCI) += tsi108_pci.o +COBJS-$(CONFIG_WINBOND_83C553) += w83c553f.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index a7afa908a2d..bb2813f1292 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -18,8 +18,6 @@ #include -#ifdef CONFIG_FSL_PCI_INIT - /* * PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's * @@ -197,5 +195,3 @@ fsl_pci_init(struct pci_controller *hose) pci_hose_write_config_word(hose, dev, PCI_SEC_STATUS, 0xffff); } } - -#endif /* CONFIG_FSL_PCI */ diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 16180cbe51a..b5eea89e7d4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -30,8 +30,6 @@ #include -#ifdef CONFIG_PCI - #include #include #include @@ -544,5 +542,3 @@ void pci_init(void) /* now call board specific pci_init()... */ pci_init_board(); } - -#endif /* CONFIG_PCI */ diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index eb6959376a7..2acf9bf7808 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -15,8 +15,6 @@ #include -#ifdef CONFIG_PCI - #include #undef DEBUG @@ -408,5 +406,3 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev) return sub_bus; } - -#endif /* CONFIG_PCI */ diff --git a/drivers/pci/pci_indirect.c b/drivers/pci/pci_indirect.c index 55517a8fed3..ab51f8d01e8 100644 --- a/drivers/pci/pci_indirect.c +++ b/drivers/pci/pci_indirect.c @@ -11,7 +11,6 @@ #include -#ifdef CONFIG_PCI #if (!defined(__I386__) && !defined(CONFIG_IXDP425)) #include @@ -135,4 +134,3 @@ void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) } #endif /* !__I386__ && !CONFIG_IXDP425 */ -#endif /* CONFIG_PCI */ diff --git a/drivers/pci/tsi108_pci.c b/drivers/pci/tsi108_pci.c index 4f02cb85e8c..edd614f236e 100644 --- a/drivers/pci/tsi108_pci.c +++ b/drivers/pci/tsi108_pci.c @@ -27,8 +27,6 @@ #include -#ifdef CONFIG_TSI108_PCI - #include #include #include @@ -182,5 +180,3 @@ void ft_pci_setup(void *blob, bd_t *bd) } } #endif /* CONFIG_OF_LIBFDT */ - -#endif /* CONFIG_TSI108_PCI */ diff --git a/drivers/pci/w83c553f.c b/drivers/pci/w83c553f.c index 9ea08a2565a..d7355a4084d 100644 --- a/drivers/pci/w83c553f.c +++ b/drivers/pci/w83c553f.c @@ -30,8 +30,6 @@ #include #include -#ifdef CFG_WINBOND_83C553 - #include #include @@ -222,5 +220,3 @@ void initialise_dma(void) out8(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00); out16(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000); } - -#endif /* CFG_WINBOND_83C553 */ diff --git a/include/configs/BAB7xx.h b/include/configs/BAB7xx.h index 799ce384726..26a1a2d3122 100644 --- a/include/configs/BAB7xx.h +++ b/include/configs/BAB7xx.h @@ -338,7 +338,7 @@ extern unsigned char scsi_sym53c8xx_ccf; /* * Winbond Configuration */ -#define CFG_WINBOND_83C553 1 /* has a winbond bridge */ +#define CONFIG_WINBOND_83C553 1 /* has a winbond bridge */ #define CFG_USE_WINBOND_IDE 0 /* use winbond 83c553 internal ide */ #define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /* pci-isa bridge config addr */ #define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /* ide config addr */ diff --git a/include/configs/HIDDEN_DRAGON.h b/include/configs/HIDDEN_DRAGON.h index fea1f6c46a8..5deb84de5a6 100644 --- a/include/configs/HIDDEN_DRAGON.h +++ b/include/configs/HIDDEN_DRAGON.h @@ -201,7 +201,7 @@ */ -#define CFG_WINBOND_83C553 1 /*has a winbond bridge */ +#define CONFIG_WINBOND_83C553 1 /*has a winbond bridge */ #define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal IDE ctrlr */ #define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */ #define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */ diff --git a/include/configs/Sandpoint8240.h b/include/configs/Sandpoint8240.h index c5a57d36c71..cfd16d31274 100644 --- a/include/configs/Sandpoint8240.h +++ b/include/configs/Sandpoint8240.h @@ -235,7 +235,7 @@ */ -#define CFG_WINBOND_83C553 1 /*has a winbond bridge */ +#define CONFIG_WINBOND_83C553 1 /*has a winbond bridge */ #define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal IDE ctrlr */ #define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */ #define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */ diff --git a/include/configs/Sandpoint8245.h b/include/configs/Sandpoint8245.h index 56853140c6e..c0f2c5796a6 100644 --- a/include/configs/Sandpoint8245.h +++ b/include/configs/Sandpoint8245.h @@ -203,7 +203,7 @@ */ -#define CFG_WINBOND_83C553 1 /*has a winbond bridge */ +#define CONFIG_WINBOND_83C553 1 /*has a winbond bridge */ #define CFG_USE_WINBOND_IDE 0 /*use winbond 83c553 internal IDE ctrlr */ #define CFG_WINBOND_ISA_CFG_ADDR 0x80005800 /*pci-isa bridge config addr */ #define CFG_WINBOND_IDE_CFG_ADDR 0x80005900 /*ide config addr */ -- cgit v1.3.1 From 7ba44a5521cdb7fa1c72864025cde1e21a6f6921 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:41 +0200 Subject: drivers/qe: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/qe/Makefile | 3 ++- drivers/qe/qe.c | 3 --- drivers/qe/uccf.c | 2 -- drivers/qe/uec.c | 5 ----- drivers/qe/uec_phy.c | 3 --- 5 files changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/qe/Makefile b/drivers/qe/Makefile index 45a2fff62ca..18fe9ce614a 100644 --- a/drivers/qe/Makefile +++ b/drivers/qe/Makefile @@ -25,8 +25,9 @@ include $(TOPDIR)/config.mk LIB := $(obj)qe.a COBJS-$(CONFIG_OF_LIBFDT) += fdt.o -COBJS := qe.o uccf.o uec.o uec_phy.o $(COBJS-y) +COBJS-$(CONFIG_QE) += qe.o uccf.o uec.o uec_phy.o +COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 7b6ecd753d2..e914d01d805 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -27,7 +27,6 @@ #include "asm/immap_qe.h" #include "qe.h" -#if defined(CONFIG_QE) qe_map_t *qe_immr = NULL; static qe_snum_t snums[QE_NUM_OF_SNUM]; @@ -466,5 +465,3 @@ U_BOOT_CMD( "fw [] - Upload firmware binary at address to " "the QE,\n\twith optional length verification.\n" ); - -#endif /* CONFIG_QE */ diff --git a/drivers/qe/uccf.c b/drivers/qe/uccf.c index 4a327ab48f6..7f6337bac8e 100644 --- a/drivers/qe/uccf.c +++ b/drivers/qe/uccf.c @@ -28,7 +28,6 @@ #include "qe.h" #include "uccf.h" -#if defined(CONFIG_QE) void ucc_fast_transmit_on_demand(ucc_fast_private_t *uccf) { out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD); @@ -401,4 +400,3 @@ int ucc_fast_init(ucc_fast_info_t *uf_info, ucc_fast_private_t **uccf_ret) *uccf_ret = uccf; return 0; } -#endif /* CONFIG_QE */ diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index ba89247e4fc..344c6499999 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -31,8 +31,6 @@ #include "uec_phy.h" #include "miiphy.h" -#if defined(CONFIG_QE) - #ifdef CONFIG_UEC_ETH1 static uec_info_t eth1_uec_info = { .uf_info = { @@ -1406,6 +1404,3 @@ int uec_initialize(int index) return 1; } - - -#endif /* CONFIG_QE */ diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index 423ba789e9e..186922e0c51 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -26,8 +26,6 @@ #include "uec_phy.h" #include "miiphy.h" -#if defined(CONFIG_QE) - #define ugphy_printk(format, arg...) \ printf(format "\n", ## arg) @@ -677,4 +675,3 @@ void change_phy_interface_mode (struct eth_device *dev, enet_interface_e mode) marvell_phy_interface_mode (dev, mode); #endif } -#endif /* CONFIG_QE */ -- cgit v1.3.1 From 00b1883a4cac59d97cd297b1a3a398db85982865 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:42 +0200 Subject: drivers/mtd: Move conditional compilation to Makefile rename CFG_FLASH_CFI_DRIVER to CONFIG_FLASH_CFI_DRIVER Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- README | 2 +- board/icecube/flash.c | 4 ++-- board/prodrive/pdnb3/flash.c | 4 ++-- board/tqc/tqm8xx/flash.c | 4 ++-- drivers/mtd/Makefile | 6 +++--- drivers/mtd/at45.c | 3 --- drivers/mtd/cfi_flash.c | 3 --- drivers/mtd/mw_eeprom.c | 5 ----- include/configs/APC405.h | 2 +- include/configs/ATUM8548.h | 2 +- include/configs/Adder.h | 2 +- include/configs/BC3450.h | 2 +- include/configs/CPCI750.h | 2 +- include/configs/DU440.h | 2 +- include/configs/EP88x.h | 2 +- include/configs/FPS850L.h | 2 +- include/configs/FPS860L.h | 2 +- include/configs/HMI10.h | 2 +- include/configs/IDS8247.h | 2 +- include/configs/ISPAN.h | 2 +- include/configs/IceCube.h | 2 +- include/configs/M52277EVB.h | 2 +- include/configs/M5235EVB.h | 2 +- include/configs/M5249EVB.h | 2 +- include/configs/M5253EVBE.h | 2 +- include/configs/M5271EVB.h | 2 +- include/configs/M5275EVB.h | 2 +- include/configs/M5282EVB.h | 2 +- include/configs/M5329EVB.h | 2 +- include/configs/M5373EVB.h | 2 +- include/configs/M54455EVB.h | 2 +- include/configs/M5475EVB.h | 2 +- include/configs/M5485EVB.h | 2 +- include/configs/MPC8313ERDB.h | 2 +- include/configs/MPC8315ERDB.h | 2 +- include/configs/MPC8323ERDB.h | 2 +- include/configs/MPC832XEMDS.h | 2 +- include/configs/MPC8349EMDS.h | 2 +- include/configs/MPC8349ITX.h | 4 ++-- include/configs/MPC8360EMDS.h | 2 +- include/configs/MPC8360ERDK.h | 2 +- include/configs/MPC837XEMDS.h | 2 +- include/configs/MPC837XERDB.h | 2 +- include/configs/MPC8540ADS.h | 2 +- include/configs/MPC8541CDS.h | 2 +- include/configs/MPC8544DS.h | 2 +- include/configs/MPC8548CDS.h | 2 +- include/configs/MPC8555CDS.h | 2 +- include/configs/MPC8560ADS.h | 2 +- include/configs/MPC8568MDS.h | 2 +- include/configs/MPC8610HPCD.h | 2 +- include/configs/MPC8641HPCN.h | 2 +- include/configs/MVBC_P.h | 2 +- include/configs/MVBLM7.h | 2 +- include/configs/MigoR.h | 2 +- include/configs/NSCU.h | 2 +- include/configs/PM854.h | 2 +- include/configs/PM856.h | 2 +- include/configs/PMC405.h | 2 +- include/configs/PMC440.h | 2 +- include/configs/Rattler.h | 2 +- include/configs/SBC8540.h | 2 +- include/configs/SX1.h | 2 +- include/configs/TB5200.h | 2 +- include/configs/TK885D.h | 2 +- include/configs/TQM5200.h | 2 +- include/configs/TQM823L.h | 2 +- include/configs/TQM823M.h | 2 +- include/configs/TQM8272.h | 2 +- include/configs/TQM834x.h | 2 +- include/configs/TQM850L.h | 2 +- include/configs/TQM850M.h | 2 +- include/configs/TQM855L.h | 2 +- include/configs/TQM855M.h | 2 +- include/configs/TQM85xx.h | 2 +- include/configs/TQM860L.h | 2 +- include/configs/TQM860M.h | 2 +- include/configs/TQM862L.h | 2 +- include/configs/TQM862M.h | 2 +- include/configs/TQM866M.h | 2 +- include/configs/TQM885D.h | 2 +- include/configs/Total5200.h | 2 +- include/configs/ZPC1900.h | 2 +- include/configs/acadia.h | 2 +- include/configs/actux1.h | 2 +- include/configs/actux2.h | 2 +- include/configs/actux3.h | 2 +- include/configs/actux4.h | 2 +- include/configs/ads5121.h | 2 +- include/configs/aev.h | 2 +- include/configs/alpr.h | 2 +- include/configs/apollon.h | 2 +- include/configs/assabet.h | 2 +- include/configs/at91cap9adk.h | 2 +- include/configs/at91sam9263ek.h | 2 +- include/configs/atngw100.h | 2 +- include/configs/atstk1002.h | 2 +- include/configs/atstk1003.h | 2 +- include/configs/atstk1004.h | 2 +- include/configs/atstk1006.h | 2 +- include/configs/bf533-stamp.h | 2 +- include/configs/bf537-stamp.h | 2 +- include/configs/bf561-ezkit.h | 2 +- include/configs/canmb.h | 2 +- include/configs/canyonlands.h | 2 +- include/configs/cm5200.h | 2 +- include/configs/csb272.h | 2 +- include/configs/csb472.h | 2 +- include/configs/csb637.h | 2 +- include/configs/davinci_dvevm.h | 2 +- include/configs/davinci_sonata.h | 2 +- include/configs/dbau1x00.h | 2 +- include/configs/eXalion.h | 2 +- include/configs/ep8248.h | 2 +- include/configs/ep82xxm.h | 2 +- include/configs/gcplus.h | 2 +- include/configs/gr_cpci_ax2000.h | 2 +- include/configs/gr_ep2s60.h | 2 +- include/configs/gr_xc3s_1500.h | 2 +- include/configs/grsim.h | 2 +- include/configs/grsim_leon2.h | 2 +- include/configs/hcu4.h | 2 +- include/configs/hcu5.h | 2 +- include/configs/hmi1001.h | 2 +- include/configs/imx31_litekit.h | 2 +- include/configs/imx31_phycore.h | 2 +- include/configs/inka4x0.h | 2 +- include/configs/ixdp425.h | 2 +- include/configs/ixdpg425.h | 2 +- include/configs/jupiter.h | 2 +- include/configs/katmai.h | 2 +- include/configs/kb9202.h | 2 +- include/configs/kilauea.h | 2 +- include/configs/korat.h | 2 +- include/configs/kvme080.h | 2 +- include/configs/linkstation.h | 2 +- include/configs/lwmon5.h | 2 +- include/configs/m501sk.h | 2 +- include/configs/makalu.h | 2 +- include/configs/mcc200.h | 2 +- include/configs/mcu25.h | 2 +- include/configs/mecp5200.h | 2 +- include/configs/mgcoge.h | 2 +- include/configs/mgsuvd.h | 2 +- include/configs/ml401.h | 2 +- include/configs/motionpro.h | 2 +- include/configs/mpc7448hpc2.h | 2 +- include/configs/mpr2.h | 2 +- include/configs/ms7720se.h | 2 +- include/configs/ms7722se.h | 2 +- include/configs/ms7750se.h | 2 +- include/configs/munices.h | 2 +- include/configs/mx31ads.h | 2 +- include/configs/omap1510inn.h | 2 +- include/configs/omap2420h4.h | 2 +- include/configs/omap5912osk.h | 2 +- include/configs/p3mx.h | 2 +- include/configs/p3p440.h | 2 +- include/configs/pdnb3.h | 2 +- include/configs/ppmc8260.h | 2 +- include/configs/pxa255_idp.h | 2 +- include/configs/qemu-mips.h | 2 +- include/configs/quad100hd.h | 2 +- include/configs/quantum.h | 6 +++--- include/configs/r2dplus.h | 2 +- include/configs/r7780mp.h | 2 +- include/configs/sbc8349.h | 2 +- include/configs/sbc8548.h | 2 +- include/configs/sbc8560.h | 2 +- include/configs/sbc8641d.h | 2 +- include/configs/sc3.h | 2 +- include/configs/sequoia.h | 2 +- include/configs/sh7763rdp.h | 2 +- include/configs/smmaco4.h | 2 +- include/configs/socrates.h | 2 +- include/configs/sorcery.h | 2 +- include/configs/spc1920.h | 2 +- include/configs/spieval.h | 2 +- include/configs/stxssa.h | 2 +- include/configs/stxxtc.h | 2 +- include/configs/taishan.h | 2 +- include/configs/trizepsiv.h | 2 +- include/configs/uc100.h | 2 +- include/configs/uc101.h | 2 +- include/configs/v38b.h | 2 +- include/configs/virtlab2.h | 2 +- include/configs/voiceblue.h | 2 +- include/configs/yosemite.h | 2 +- include/configs/zeus.h | 2 +- 189 files changed, 194 insertions(+), 205 deletions(-) (limited to 'drivers') diff --git a/README b/README index d4456e576b9..37449d16101 100644 --- a/README +++ b/README @@ -2064,7 +2064,7 @@ Configuration Settings: Define if the flash driver uses extra elements in the common flash structure for storing flash geometry. -- CFG_FLASH_CFI_DRIVER +- CONFIG_FLASH_CFI_DRIVER This option also enables the building of the cfi_flash driver in the drivers directory diff --git a/board/icecube/flash.c b/board/icecube/flash.c index 15e86d34f39..2d4026a9de7 100644 --- a/board/icecube/flash.c +++ b/board/icecube/flash.c @@ -23,7 +23,7 @@ #include -#ifndef CFG_FLASH_CFI_DRIVER +#ifndef CONFIG_FLASH_CFI_DRIVER flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ /* NOTE - CONFIG_FLASH_16BIT means the CPU interface is 16-bit, it @@ -490,4 +490,4 @@ static int write_word_amd (flash_info_t *info, FPWV *dest, FPW data) return (res); } -#endif /*CFG_FLASH_CFI_DRIVER*/ +#endif /*CONFIG_FLASH_CFI_DRIVER*/ diff --git a/board/prodrive/pdnb3/flash.c b/board/prodrive/pdnb3/flash.c index 518ea9c0314..0786324fba6 100644 --- a/board/prodrive/pdnb3/flash.c +++ b/board/prodrive/pdnb3/flash.c @@ -24,7 +24,7 @@ #include #include -#if !defined(CFG_FLASH_CFI_DRIVER) +#if !defined(CONFIG_FLASH_CFI_DRIVER) /* * include common flash code (for esd boards) @@ -86,4 +86,4 @@ unsigned long flash_init(void) return size; } -#endif /* CFG_FLASH_CFI_DRIVER */ +#endif /* CONFIG_FLASH_CFI_DRIVER */ diff --git a/board/tqc/tqm8xx/flash.c b/board/tqc/tqm8xx/flash.c index 4342ebc8419..1231c7c6f93 100644 --- a/board/tqc/tqm8xx/flash.c +++ b/board/tqc/tqm8xx/flash.c @@ -33,7 +33,7 @@ DECLARE_GLOBAL_DATA_PTR; -#if !defined(CFG_FLASH_CFI_DRIVER) /* do not use if CFI driver is configured */ +#if !defined(CONFIG_FLASH_CFI_DRIVER) /* do not use if CFI driver is configured */ #if defined(CONFIG_TQM8xxL) && !defined(CONFIG_TQM866M) \ && !defined(CONFIG_TQM885D) @@ -831,4 +831,4 @@ static int write_word (flash_info_t *info, ulong dest, ulong data) /*----------------------------------------------------------------------- */ -#endif /* !defined(CFG_FLASH_CFI_DRIVER) */ +#endif /* !defined(CONFIG_FLASH_CFI_DRIVER) */ diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index ff932a1b6bf..6538f7a1586 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -25,11 +25,11 @@ include $(TOPDIR)/config.mk LIB := $(obj)libmtd.a -COBJS-y += at45.o -COBJS-y += cfi_flash.o +COBJS-$(CONFIG_HAS_DATAFLASH) += at45.o +COBJS-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o COBJS-$(CONFIG_HAS_DATAFLASH) += dataflash.o -COBJS-y += mw_eeprom.o COBJS-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o +COBJS-$(CONFIG_MW_EEPROM) += mw_eeprom.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/mtd/at45.c b/drivers/mtd/at45.c index a9d13ff90ef..d1a60aac90b 100644 --- a/drivers/mtd/at45.c +++ b/drivers/mtd/at45.c @@ -20,8 +20,6 @@ #include #include - -#ifdef CONFIG_HAS_DATAFLASH #include /* @@ -559,4 +557,3 @@ int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc) AT91F_DataFlashGetStatus(pDesc); return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C); } -#endif diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 479075ccb19..402d835bf98 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -39,7 +39,6 @@ #include #include #include -#ifdef CFG_FLASH_CFI_DRIVER /* * This file implements a Common Flash Interface (CFI) driver for @@ -2015,5 +2014,3 @@ unsigned long flash_init (void) #endif return (size); } - -#endif /* CFG_FLASH_CFI */ diff --git a/drivers/mtd/mw_eeprom.c b/drivers/mtd/mw_eeprom.c index 2b3348810d2..f32ced4c2e0 100644 --- a/drivers/mtd/mw_eeprom.c +++ b/drivers/mtd/mw_eeprom.c @@ -1,9 +1,6 @@ /* Three-wire (MicroWire) serial eeprom driver (for 93C46 and compatibles) */ #include - -#ifdef CONFIG_MW_EEPROM - #include /* @@ -237,5 +234,3 @@ int mw_eeprom_probe(int dev) } return 0; } - -#endif diff --git a/include/configs/APC405.h b/include/configs/APC405.h index 2f266a242ff..6ee0a3631fb 100644 --- a/include/configs/APC405.h +++ b/include/configs/APC405.h @@ -269,7 +269,7 @@ extern int flash_banks; #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_MAX_FLASH_SECT 256 /* max num of sects on one chip */ #define CFG_MAX_FLASH_BANKS flash_banks /* max num of flash banks */ /* updated in board_early_init_r */ diff --git a/include/configs/ATUM8548.h b/include/configs/ATUM8548.h index f05c1d592b0..6aa881caca4 100644 --- a/include/configs/ATUM8548.h +++ b/include/configs/ATUM8548.h @@ -182,7 +182,7 @@ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_CFI 1 #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/Adder.h b/include/configs/Adder.h index cefdd29602d..07a9f4e9345 100644 --- a/include/configs/Adder.h +++ b/include/configs/Adder.h @@ -143,7 +143,7 @@ */ #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */ #define CFG_MAX_FLASH_SECT 128 /* Max num of sects on one chip */ diff --git a/include/configs/BC3450.h b/include/configs/BC3450.h index b7574bf1494..3c5d03812eb 100644 --- a/include/configs/BC3450.h +++ b/include/configs/BC3450.h @@ -328,7 +328,7 @@ /* use CFI flash driver if no module variant is spezified */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */ diff --git a/include/configs/CPCI750.h b/include/configs/CPCI750.h index 89edbde1de6..03756c3b242 100644 --- a/include/configs/CPCI750.h +++ b/include/configs/CPCI750.h @@ -294,7 +294,7 @@ * FLASH related *----------------------------------------------------------------------*/ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ #define CFG_FLASH_PROTECTION 1 /* use hardware protection */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ diff --git a/include/configs/DU440.h b/include/configs/DU440.h index 64c9ac076da..c757523aec2 100644 --- a/include/configs/DU440.h +++ b/include/configs/DU440.h @@ -119,7 +119,7 @@ * FLASH related */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/EP88x.h b/include/configs/EP88x.h index 7824b900ad4..5f1743b2ff3 100644 --- a/include/configs/EP88x.h +++ b/include/configs/EP88x.h @@ -138,7 +138,7 @@ */ #define CFG_FLASH_BASE 0xFC000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */ #define CFG_MAX_FLASH_SECT 512 /* Max num of sects on one chip */ diff --git a/include/configs/FPS850L.h b/include/configs/FPS850L.h index 79b71db75a6..e694a0218fc 100644 --- a/include/configs/FPS850L.h +++ b/include/configs/FPS850L.h @@ -194,7 +194,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/FPS860L.h b/include/configs/FPS860L.h index ec757e2ff65..84b682415d4 100644 --- a/include/configs/FPS860L.h +++ b/include/configs/FPS860L.h @@ -194,7 +194,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/HMI10.h b/include/configs/HMI10.h index 081ca6cc5ea..a7e7c5744ec 100644 --- a/include/configs/HMI10.h +++ b/include/configs/HMI10.h @@ -227,7 +227,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/IDS8247.h b/include/configs/IDS8247.h index f7d4499f4f7..29dc6234ba7 100644 --- a/include/configs/IDS8247.h +++ b/include/configs/IDS8247.h @@ -227,7 +227,7 @@ #define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { 0xFF800000 } #define CFG_MAX_FLASH_BANKS_DETECT 1 /* What should the base address of the main FLASH be and how big is diff --git a/include/configs/ISPAN.h b/include/configs/ISPAN.h index 760f7cca6e9..27e46a432bb 100644 --- a/include/configs/ISPAN.h +++ b/include/configs/ISPAN.h @@ -180,7 +180,7 @@ */ #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* Max num of memory banks */ #define CFG_MAX_FLASH_SECT 142 /* Max num of sects on one chip */ diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index 3a347eac55e..0b90946a364 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -246,7 +246,7 @@ #undef CONFIG_FLASH_16BIT /* Flash is 8-bit */ #if defined(CONFIG_LITE5200B) -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_BANKS_LIST {CFG_CS1_START,CFG_CS0_START} #endif diff --git a/include/configs/M52277EVB.h b/include/configs/M52277EVB.h index 3d2891354f8..8713b02aaf9 100644 --- a/include/configs/M52277EVB.h +++ b/include/configs/M52277EVB.h @@ -207,7 +207,7 @@ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x1000000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/M5235EVB.h b/include/configs/M5235EVB.h index 8af1c52abf9..e8361321f17 100644 --- a/include/configs/M5235EVB.h +++ b/include/configs/M5235EVB.h @@ -200,7 +200,7 @@ */ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x800000 /* Max size that the board might have */ #ifdef NORFLASH_PS32BIT # define CFG_FLASH_CFI_WIDTH FLASH_CFI_32BIT diff --git a/include/configs/M5249EVB.h b/include/configs/M5249EVB.h index de7ea42930f..c2f5dd9fa47 100644 --- a/include/configs/M5249EVB.h +++ b/include/configs/M5249EVB.h @@ -150,7 +150,7 @@ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x1000000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/M5253EVBE.h b/include/configs/M5253EVBE.h index f5e1b646ca2..9dbd1297633 100644 --- a/include/configs/M5253EVBE.h +++ b/include/configs/M5253EVBE.h @@ -172,7 +172,7 @@ #define CFG_FLASH_ERASE_TOUT 1000 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_SIZE 0x200000 #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT diff --git a/include/configs/M5271EVB.h b/include/configs/M5271EVB.h index a6fac4cbf63..12f9783abe8 100644 --- a/include/configs/M5271EVB.h +++ b/include/configs/M5271EVB.h @@ -210,7 +210,7 @@ #define CFG_FLASH_ERASE_TOUT 1000 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_SIZE 0x200000 /* Cache Configuration */ diff --git a/include/configs/M5275EVB.h b/include/configs/M5275EVB.h index 283c873d834..30c70e5796f 100644 --- a/include/configs/M5275EVB.h +++ b/include/configs/M5275EVB.h @@ -197,7 +197,7 @@ #define CFG_FLASH_ERASE_TOUT 1000 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_SIZE 0x200000 /*----------------------------------------------------------------------- diff --git a/include/configs/M5282EVB.h b/include/configs/M5282EVB.h index df46ee44385..c2c7fab732c 100644 --- a/include/configs/M5282EVB.h +++ b/include/configs/M5282EVB.h @@ -194,7 +194,7 @@ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x1000000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/M5329EVB.h b/include/configs/M5329EVB.h index b30d99c92e9..58948a20a9c 100644 --- a/include/configs/M5329EVB.h +++ b/include/configs/M5329EVB.h @@ -202,7 +202,7 @@ */ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x800000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/M5373EVB.h b/include/configs/M5373EVB.h index a710c6d9f8a..814c3a610d1 100644 --- a/include/configs/M5373EVB.h +++ b/include/configs/M5373EVB.h @@ -202,7 +202,7 @@ */ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x800000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/M54455EVB.h b/include/configs/M54455EVB.h index 3a022afafd2..6620f03d3d6 100644 --- a/include/configs/M54455EVB.h +++ b/include/configs/M54455EVB.h @@ -302,7 +302,7 @@ #undef CFG_FLASH_CFI #ifdef CFG_FLASH_CFI -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_SIZE 0x1000000 /* Max size that the board might have */ # define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT # define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ diff --git a/include/configs/M5475EVB.h b/include/configs/M5475EVB.h index e8804b56609..4037efb733e 100644 --- a/include/configs/M5475EVB.h +++ b/include/configs/M5475EVB.h @@ -259,7 +259,7 @@ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI # define CFG_FLASH_BASE (CFG_CS0_BASE) -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_SECT 137 /* max number of sectors on one chip */ # define CFG_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ diff --git a/include/configs/M5485EVB.h b/include/configs/M5485EVB.h index 0f957fff584..a14c55bc336 100644 --- a/include/configs/M5485EVB.h +++ b/include/configs/M5485EVB.h @@ -245,7 +245,7 @@ #define CFG_FLASH_CFI #ifdef CFG_FLASH_CFI # define CFG_FLASH_BASE (CFG_CS0_BASE) -# define CFG_FLASH_CFI_DRIVER 1 +# define CONFIG_FLASH_CFI_DRIVER 1 # define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT # define CFG_MAX_FLASH_SECT 137 /* max number of sectors on one chip */ # define CFG_FLASH_PROTECTION /* "Real" (hardware) sectors protection */ diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h index 37f8cffd3d7..a4c4240b651 100644 --- a/include/configs/MPC8313ERDB.h +++ b/include/configs/MPC8313ERDB.h @@ -171,7 +171,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* start of FLASH */ #define CFG_FLASH_SIZE 8 /* flash size in MB */ #define CFG_FLASH_EMPTY_INFO /* display empty sectors */ diff --git a/include/configs/MPC8315ERDB.h b/include/configs/MPC8315ERDB.h index 095f6658c1f..b0cc36dce39 100644 --- a/include/configs/MPC8315ERDB.h +++ b/include/configs/MPC8315ERDB.h @@ -188,7 +188,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h index 977c041dca6..94b3d5a337d 100644 --- a/include/configs/MPC8323ERDB.h +++ b/include/configs/MPC8323ERDB.h @@ -178,7 +178,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 16 /* FLASH size is 16M */ diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h index 9ca2a2be04e..401d0afc4d0 100644 --- a/include/configs/MPC832XEMDS.h +++ b/include/configs/MPC832XEMDS.h @@ -166,7 +166,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 16 /* FLASH size is 16M */ diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index 870583845d9..a53f5cd2612 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -148,7 +148,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* start of FLASH */ #define CFG_FLASH_SIZE 32 /* max flash size in MB */ /* #define CFG_FLASH_USE_BUFFER_WRITE */ diff --git a/include/configs/MPC8349ITX.h b/include/configs/MPC8349ITX.h index 82d06867be7..45ddd5c4515 100644 --- a/include/configs/MPC8349ITX.h +++ b/include/configs/MPC8349ITX.h @@ -175,7 +175,7 @@ */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* start of FLASH */ #define CFG_FLASH_EMPTY_INFO #define CFG_MAX_FLASH_SECT 135 /* 127 64KB sectors + 8 8KB sectors per device */ @@ -419,7 +419,7 @@ boards, we say we have two, but don't display a message if we find only one. */ #define CFG_ENV_SIZE 0x2000 #else #define CFG_NO_FLASH /* Flash is not usable now */ - #undef CFG_FLASH_CFI_DRIVER + #undef CONFIG_FLASH_CFI_DRIVER #define CFG_ENV_IS_NOWHERE /* Store ENV in memory only */ #define CFG_ENV_ADDR (CFG_MONITOR_BASE - 0x1000) #define CFG_ENV_SIZE 0x2000 diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h index b4bff9a2be3..43d4118b662 100644 --- a/include/configs/MPC8360EMDS.h +++ b/include/configs/MPC8360EMDS.h @@ -191,7 +191,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 32 /* max FLASH size is 32M */ #define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h index ca8d53cf253..6898495b8db 100644 --- a/include/configs/MPC8360ERDK.h +++ b/include/configs/MPC8360ERDK.h @@ -184,7 +184,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_SIZE 8 /* max FLASH size is 32M */ #define CFG_FLASH_PROTECTION 1 /* Use intel Flash protection. */ diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index 0dd02795a62..f9c1b170d1d 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -226,7 +226,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 32 /* max FLASH size is 32M */ diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h index 29c2490e6b1..82b33530d90 100644 --- a/include/configs/MPC837XERDB.h +++ b/include/configs/MPC837XERDB.h @@ -249,7 +249,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFE000000 /* FLASH base address */ #define CFG_FLASH_SIZE 8 /* max FLASH size is 32M */ diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index d1d3cc36069..6351925d7bb 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -152,7 +152,7 @@ #undef CFG_RAMBOOT #endif -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index a64565db931..d948d76a797 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -154,7 +154,7 @@ extern unsigned long get_clock_freq(void); #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index 091fd2e870d..9a77b7bcbc7 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -168,7 +168,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index acf6f0dce6a..33c5c933e0f 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -172,7 +172,7 @@ extern unsigned long get_clock_freq(void); #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index 1948c0d276f..85c235c4eb0 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -154,7 +154,7 @@ extern unsigned long get_clock_freq(void); #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index 27212162723..3567d1ce357 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -148,7 +148,7 @@ #undef CFG_RAMBOOT #endif -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index 9e6bb44ff92..a82d528dc06 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -167,7 +167,7 @@ extern unsigned long get_clock_freq(void); #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h index 06899b1aff6..e9371a2f364 100644 --- a/include/configs/MPC8610HPCD.h +++ b/include/configs/MPC8610HPCD.h @@ -192,7 +192,7 @@ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index cd354948a11..468fd08b9db 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -214,7 +214,7 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MVBC_P.h b/include/configs/MVBC_P.h index 2c27b978e0f..0ce88d6be6f 100644 --- a/include/configs/MVBC_P.h +++ b/include/configs/MVBC_P.h @@ -198,7 +198,7 @@ */ #undef CONFIG_FLASH_16BIT #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI_AMD_RESET 1 #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/MVBLM7.h b/include/configs/MVBLM7.h index b412655b6dd..0dce9b46d62 100644 --- a/include/configs/MVBLM7.h +++ b/include/configs/MVBLM7.h @@ -104,7 +104,7 @@ /* Flash */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT #define CFG_FLASH_BASE 0xFF800000 diff --git a/include/configs/MigoR.h b/include/configs/MigoR.h index ffa9b54e135..40cf275786b 100644 --- a/include/configs/MigoR.h +++ b/include/configs/MigoR.h @@ -103,7 +103,7 @@ /* FLASH */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_QUIET_TEST /* print 'E' for empty sector on flinfo */ #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/NSCU.h b/include/configs/NSCU.h index 21d90c303a9..31762b9a368 100644 --- a/include/configs/NSCU.h +++ b/include/configs/NSCU.h @@ -200,7 +200,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/PM854.h b/include/configs/PM854.h index bd058fc1551..f2c11b0bb08 100644 --- a/include/configs/PM854.h +++ b/include/configs/PM854.h @@ -148,7 +148,7 @@ #undef CFG_RAMBOOT #endif -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/PM856.h b/include/configs/PM856.h index 9355aafa61b..b2cf06000fd 100644 --- a/include/configs/PM856.h +++ b/include/configs/PM856.h @@ -149,7 +149,7 @@ #undef CFG_RAMBOOT #endif -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/PMC405.h b/include/configs/PMC405.h index adbe8a9fba6..966bbf9a318 100644 --- a/include/configs/PMC405.h +++ b/include/configs/PMC405.h @@ -214,7 +214,7 @@ #define CFG_FLASH_INCREMENT 0x01000000 #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_PROTECTION 1 /* don't use hardware protection */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks */ diff --git a/include/configs/PMC440.h b/include/configs/PMC440.h index 42f1d8d0062..9140287c873 100644 --- a/include/configs/PMC440.h +++ b/include/configs/PMC440.h @@ -120,7 +120,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/Rattler.h b/include/configs/Rattler.h index 01ebc8f6e07..e8ed0951c8b 100644 --- a/include/configs/Rattler.h +++ b/include/configs/Rattler.h @@ -187,7 +187,7 @@ #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 256 /* max num of sects on one chip */ diff --git a/include/configs/SBC8540.h b/include/configs/SBC8540.h index 8a53fdd0cb8..6033d93dd54 100644 --- a/include/configs/SBC8540.h +++ b/include/configs/SBC8540.h @@ -291,7 +291,7 @@ */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #if 0 #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_FLASH_PROTECTION /* use hardware protection */ diff --git a/include/configs/SX1.h b/include/configs/SX1.h index 50ad7dd598d..d23367979fb 100644 --- a/include/configs/SX1.h +++ b/include/configs/SX1.h @@ -181,7 +181,7 @@ * FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/TB5200.h b/include/configs/TB5200.h index d21783b838f..3b6816675a2 100644 --- a/include/configs/TB5200.h +++ b/include/configs/TB5200.h @@ -255,7 +255,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */ diff --git a/include/configs/TK885D.h b/include/configs/TK885D.h index 7310abfa600..8073b7ec6e5 100644 --- a/include/configs/TK885D.h +++ b/include/configs/TK885D.h @@ -247,7 +247,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM5200.h b/include/configs/TQM5200.h index bfb478a8688..992439f3b33 100644 --- a/include/configs/TQM5200.h +++ b/include/configs/TQM5200.h @@ -386,7 +386,7 @@ #else /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks (= chip selects) */ diff --git a/include/configs/TQM823L.h b/include/configs/TQM823L.h index 9cc196410c3..839b6be91b9 100644 --- a/include/configs/TQM823L.h +++ b/include/configs/TQM823L.h @@ -208,7 +208,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM823M.h b/include/configs/TQM823M.h index 5edd37935d5..b9a7a59c258 100644 --- a/include/configs/TQM823M.h +++ b/include/configs/TQM823M.h @@ -203,7 +203,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM8272.h b/include/configs/TQM8272.h index ba0402d2978..039ecf17bb8 100644 --- a/include/configs/TQM8272.h +++ b/include/configs/TQM8272.h @@ -372,7 +372,7 @@ #define CFG_MAX_FLASH_SECT 128 /* max num of sects on one chip */ #define CFG_FLASH_CFI /* flash is CFI compat. */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver*/ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver*/ #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector */ #define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash*/ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 0d2ca7225b1..e8f69f6dc86 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -78,7 +78,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #undef CFG_FLASH_CHECKSUM #define CFG_FLASH_BASE 0x80000000 /* start of FLASH */ #define CFG_FLASH_SIZE 8 /* FLASH size in MB */ diff --git a/include/configs/TQM850L.h b/include/configs/TQM850L.h index 9edf0d8072f..388fafc5554 100644 --- a/include/configs/TQM850L.h +++ b/include/configs/TQM850L.h @@ -193,7 +193,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM850M.h b/include/configs/TQM850M.h index e2c1ce80fad..6f0864f47ab 100644 --- a/include/configs/TQM850M.h +++ b/include/configs/TQM850M.h @@ -192,7 +192,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM855L.h b/include/configs/TQM855L.h index dd19d4e5785..093d6599ea1 100644 --- a/include/configs/TQM855L.h +++ b/include/configs/TQM855L.h @@ -198,7 +198,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM855M.h b/include/configs/TQM855M.h index 8a1c350cce3..64bbc39cf82 100644 --- a/include/configs/TQM855M.h +++ b/include/configs/TQM855M.h @@ -232,7 +232,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index d18f2346c64..964193fc065 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -204,7 +204,7 @@ #endif /* CONFIG_TQM_BIGFLASH */ #define CFG_FLASH_CFI /* flash is CFI compat. */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector */ #define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash*/ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* speed up output to Flash */ diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h index 803cdb854c4..dacc3406bb8 100644 --- a/include/configs/TQM860L.h +++ b/include/configs/TQM860L.h @@ -197,7 +197,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM860M.h b/include/configs/TQM860M.h index 071da1e607d..3ec849c8bc8 100644 --- a/include/configs/TQM860M.h +++ b/include/configs/TQM860M.h @@ -197,7 +197,7 @@ */ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h index d34f6bea649..6c610ee5904 100644 --- a/include/configs/TQM862L.h +++ b/include/configs/TQM862L.h @@ -201,7 +201,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM862M.h b/include/configs/TQM862M.h index 9270e449834..2eca59b99dd 100644 --- a/include/configs/TQM862M.h +++ b/include/configs/TQM862M.h @@ -201,7 +201,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h index d916d533728..4683286d7a0 100644 --- a/include/configs/TQM866M.h +++ b/include/configs/TQM866M.h @@ -241,7 +241,7 @@ */ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/TQM885D.h b/include/configs/TQM885D.h index f075442f381..5daaf04be84 100644 --- a/include/configs/TQM885D.h +++ b/include/configs/TQM885D.h @@ -244,7 +244,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/Total5200.h b/include/configs/Total5200.h index 598fe7bf278..25e98e249e5 100644 --- a/include/configs/Total5200.h +++ b/include/configs/Total5200.h @@ -204,7 +204,7 @@ * Flash configuration */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #if CONFIG_TOTAL5200_REV==2 # define CFG_MAX_FLASH_BANKS 3 /* max num of flash banks */ # define CFG_FLASH_BANKS_LIST { CFG_CS5_START, CFG_CS4_START, CFG_BOOTCS_START } diff --git a/include/configs/ZPC1900.h b/include/configs/ZPC1900.h index b04be766f57..388c7476811 100644 --- a/include/configs/ZPC1900.h +++ b/include/configs/ZPC1900.h @@ -179,7 +179,7 @@ #define CFG_FLSIMM_BASE 0xFF000000 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 32 /* max num of sects on one chip */ diff --git a/include/configs/acadia.h b/include/configs/acadia.h index 9092a7c0962..ed2754d66a8 100644 --- a/include/configs/acadia.h +++ b/include/configs/acadia.h @@ -107,7 +107,7 @@ *----------------------------------------------------------------------*/ #if !defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/actux1.h b/include/configs/actux1.h index 4c4b1d145d2..33a74949a54 100644 --- a/include/configs/actux1.h +++ b/include/configs/actux1.h @@ -162,7 +162,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* no byte writes on IXP4xx */ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT /* print 'E' for empty sector on flinfo */ diff --git a/include/configs/actux2.h b/include/configs/actux2.h index 873fced0079..75aaa118421 100644 --- a/include/configs/actux2.h +++ b/include/configs/actux2.h @@ -136,7 +136,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* no byte writes on IXP4xx */ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT diff --git a/include/configs/actux3.h b/include/configs/actux3.h index 5e468e6101a..693c2847fdb 100644 --- a/include/configs/actux3.h +++ b/include/configs/actux3.h @@ -135,7 +135,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* no byte writes on IXP4xx */ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT diff --git a/include/configs/actux4.h b/include/configs/actux4.h index e4dca2afac2..7f8e0f4d0f9 100644 --- a/include/configs/actux4.h +++ b/include/configs/actux4.h @@ -134,7 +134,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* board provides its own flash_init code */ #define CONFIG_FLASH_CFI_LEGACY 1 /* no byte writes on IXP4xx */ diff --git a/include/configs/ads5121.h b/include/configs/ads5121.h index 091da803a78..d129ea317dc 100644 --- a/include/configs/ads5121.h +++ b/include/configs/ads5121.h @@ -183,7 +183,7 @@ */ #undef CONFIG_BKUP_FLASH #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #ifdef CONFIG_BKUP_FLASH #define CFG_FLASH_BASE 0xFF800000 /* start of FLASH */ #define CFG_FLASH_SIZE 0x00800000 /* max flash size in bytes */ diff --git a/include/configs/aev.h b/include/configs/aev.h index c5e475921c4..f27cc4a1500 100644 --- a/include/configs/aev.h +++ b/include/configs/aev.h @@ -225,7 +225,7 @@ /* use CFI flash driver if no module variant is spezified */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */ diff --git a/include/configs/alpr.h b/include/configs/alpr.h index fb6feb52749..f342c7a6db6 100644 --- a/include/configs/alpr.h +++ b/include/configs/alpr.h @@ -86,7 +86,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI 1 /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ diff --git a/include/configs/apollon.h b/include/configs/apollon.h index 5884611b9ad..c93e77a2e22 100644 --- a/include/configs/apollon.h +++ b/include/configs/apollon.h @@ -215,7 +215,7 @@ * CFI FLASH driver setup */ # define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -# define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ +# define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ /* #define CFG_FLASH_USE_BUFFER_WRITE 1 */ /* Use buffered writes (~10x faster) */ # define CFG_FLASH_PROTECTION 1 /* Use h/w sector protection*/ diff --git a/include/configs/assabet.h b/include/configs/assabet.h index d10f092f985..ed7b5ef8ffd 100644 --- a/include/configs/assabet.h +++ b/include/configs/assabet.h @@ -152,7 +152,7 @@ #define CFG_FLASH_BASE PHYS_FLASH_1 #define CFG_FLASH_SIZE PHYS_FLASH_SIZE #define CFG_FLASH_CFI 1 /* flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 1 /* max # of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/at91cap9adk.h b/include/configs/at91cap9adk.h index 342ce2a649d..520c67685db 100644 --- a/include/configs/at91cap9adk.h +++ b/include/configs/at91cap9adk.h @@ -109,7 +109,7 @@ /* NOR flash */ #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define PHYS_FLASH_1 0x10000000 #define CFG_FLASH_BASE PHYS_FLASH_1 #define CFG_MAX_FLASH_SECT 256 diff --git a/include/configs/at91sam9263ek.h b/include/configs/at91sam9263ek.h index a8194b564d9..5f90d39d5ca 100644 --- a/include/configs/at91sam9263ek.h +++ b/include/configs/at91sam9263ek.h @@ -113,7 +113,7 @@ #define CFG_NO_FLASH 1 #else #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define PHYS_FLASH_1 0x10000000 #define CFG_FLASH_BASE PHYS_FLASH_1 #define CFG_MAX_FLASH_SECT 256 diff --git a/include/configs/atngw100.h b/include/configs/atngw100.h index f040b863c77..6d8c1b22a38 100644 --- a/include/configs/atngw100.h +++ b/include/configs/atngw100.h @@ -140,7 +140,7 @@ #define CONFIG_NR_DRAM_BANKS 1 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_BASE 0x00000000 #define CFG_FLASH_SIZE 0x800000 diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h index 68f0cecf39e..3a7d27354f8 100644 --- a/include/configs/atstk1002.h +++ b/include/configs/atstk1002.h @@ -163,7 +163,7 @@ /* External flash on STK1000 */ #if 0 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #endif #define CFG_FLASH_BASE 0x00000000 diff --git a/include/configs/atstk1003.h b/include/configs/atstk1003.h index d3a2f69edea..55ea7f290f3 100644 --- a/include/configs/atstk1003.h +++ b/include/configs/atstk1003.h @@ -146,7 +146,7 @@ /* External flash on STK1000 */ #if 0 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #endif #define CFG_FLASH_BASE 0x00000000 diff --git a/include/configs/atstk1004.h b/include/configs/atstk1004.h index a37ba92416b..369c6196490 100644 --- a/include/configs/atstk1004.h +++ b/include/configs/atstk1004.h @@ -146,7 +146,7 @@ /* External flash on STK1000 */ #if 0 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #endif #define CFG_FLASH_BASE 0x00000000 diff --git a/include/configs/atstk1006.h b/include/configs/atstk1006.h index a6c5b6e24ed..902f822e45f 100644 --- a/include/configs/atstk1006.h +++ b/include/configs/atstk1006.h @@ -163,7 +163,7 @@ /* External flash on STK1000 */ #if 0 #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #endif #define CFG_FLASH_BASE 0x00000000 diff --git a/include/configs/bf533-stamp.h b/include/configs/bf533-stamp.h index d70aa1087cb..9f5667bcb52 100644 --- a/include/configs/bf533-stamp.h +++ b/include/configs/bf533-stamp.h @@ -94,7 +94,7 @@ */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_AMD_RESET #define CFG_FLASH_BASE 0x20000000 diff --git a/include/configs/bf537-stamp.h b/include/configs/bf537-stamp.h index a881d53289b..a06c1dccfb4 100644 --- a/include/configs/bf537-stamp.h +++ b/include/configs/bf537-stamp.h @@ -221,7 +221,7 @@ #define CFG_FLASH_BASE 0x20000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_PROTECTION #define CFG_MAX_FLASH_BANKS 1 #define CFG_MAX_FLASH_SECT 71 /* some have 67 sectors (M29W320DB), but newer have 71 (M29W320EB) */ diff --git a/include/configs/bf561-ezkit.h b/include/configs/bf561-ezkit.h index e99e97924cd..e4a7f9dbce3 100644 --- a/include/configs/bf561-ezkit.h +++ b/include/configs/bf561-ezkit.h @@ -77,7 +77,7 @@ */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_AMD_RESET #define CFG_ENV_IS_IN_FLASH 1 #define CFG_FLASH_BASE 0x20000000 diff --git a/include/configs/canmb.h b/include/configs/canmb.h index f097e2c2f09..38714cc3069 100644 --- a/include/configs/canmb.h +++ b/include/configs/canmb.h @@ -130,7 +130,7 @@ #define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h index ac2e5d99e01..3b5b2809359 100644 --- a/include/configs/canyonlands.h +++ b/include/configs/canyonlands.h @@ -188,7 +188,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_AMD_RESET 1 /* Use AMD (Spansion) reset cmd */ #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} diff --git a/include/configs/cm5200.h b/include/configs/cm5200.h index ef50c7cabb7..0221dfeb8c1 100644 --- a/include/configs/cm5200.h +++ b/include/configs/cm5200.h @@ -177,7 +177,7 @@ * Flash configuration */ #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_BASE 0xfc000000 /* we need these despite using CFI */ #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ diff --git a/include/configs/csb272.h b/include/configs/csb272.h index 15bf1772b94..5145c004235 100644 --- a/include/configs/csb272.h +++ b/include/configs/csb272.h @@ -264,7 +264,7 @@ * */ #define CFG_FLASH_CFI 1 /* flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 1 /* max # of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/csb472.h b/include/configs/csb472.h index b06c0a269da..d3e5ea86b1b 100644 --- a/include/configs/csb472.h +++ b/include/configs/csb472.h @@ -263,7 +263,7 @@ * */ #define CFG_FLASH_CFI 1 /* flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 1 /* max # of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/csb637.h b/include/configs/csb637.h index 735a211e07e..88c8fdbf7fd 100644 --- a/include/configs/csb637.h +++ b/include/configs/csb637.h @@ -179,7 +179,7 @@ #define PHYS_FLASH_SIZE 0x800000 /* 8 megs main flash */ #define CFG_FLASH_BASE PHYS_FLASH_1 #define CFG_FLASH_CFI 1 /* flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 1 /* max # of memory banks */ diff --git a/include/configs/davinci_dvevm.h b/include/configs/davinci_dvevm.h index 632c4c2bf9d..c27ce18ff2b 100644 --- a/include/configs/davinci_dvevm.h +++ b/include/configs/davinci_dvevm.h @@ -140,7 +140,7 @@ #endif #define CFG_ENV_IS_IN_FLASH #undef CFG_NO_FLASH -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_MAX_FLASH_BANKS 1 /* max number of flash banks */ #define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD Flash */ diff --git a/include/configs/davinci_sonata.h b/include/configs/davinci_sonata.h index ba68605a055..c55766ce34f 100644 --- a/include/configs/davinci_sonata.h +++ b/include/configs/davinci_sonata.h @@ -135,7 +135,7 @@ #endif #define CFG_ENV_IS_IN_FLASH #undef CFG_NO_FLASH -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_MAX_FLASH_BANKS 1 /* max number of flash banks */ #define CFG_FLASH_SECT_SZ 0x20000 /* 128KB sect size AMD Flash */ diff --git a/include/configs/dbau1x00.h b/include/configs/dbau1x00.h index 0e10396dfa9..8941c5eb12a 100644 --- a/include/configs/dbau1x00.h +++ b/include/configs/dbau1x00.h @@ -183,7 +183,7 @@ #define CFG_FLASH_BANKS_LIST {PHYS_FLASH_1, PHYS_FLASH_2} #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 /* The following #defines are needed to get flash environment right */ #define CFG_MONITOR_BASE TEXT_BASE diff --git a/include/configs/eXalion.h b/include/configs/eXalion.h index f8e2c885b06..6ba0d3fe57d 100644 --- a/include/configs/eXalion.h +++ b/include/configs/eXalion.h @@ -170,7 +170,7 @@ */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/ep8248.h b/include/configs/ep8248.h index 8a220b68163..ccc0d5d225b 100644 --- a/include/configs/ep8248.h +++ b/include/configs/ep8248.h @@ -186,7 +186,7 @@ #define CFG_FLASH_BASE 0xFF800000 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 256 /* max num of sects on one chip */ diff --git a/include/configs/ep82xxm.h b/include/configs/ep82xxm.h index ac5847ce12c..ac68c869a73 100644 --- a/include/configs/ep82xxm.h +++ b/include/configs/ep82xxm.h @@ -202,7 +202,7 @@ *----------------------------------------------------------------------*/ #define CFG_FLASH_BASE 0xFC000000 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 512 /* max num of sects on one chip */ #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector in flinfo */ diff --git a/include/configs/gcplus.h b/include/configs/gcplus.h index 3b1b4ab9506..1d9c05b729b 100644 --- a/include/configs/gcplus.h +++ b/include/configs/gcplus.h @@ -169,7 +169,7 @@ #else /* REVISIT: This doesn't work on ADS GCPlus just yet: */ #define CFG_FLASH_CFI 1 /* flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* use common cfi driver */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_BANKS 1 /* max # of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index ffe7671ec03..942609f8caf 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -208,7 +208,7 @@ /*** CFI CONFIG ***/ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI /* Bypass cache when reading regs from flash memory */ #define CFG_FLASH_CFI_BYPASS_READ diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 7b1d582202e..ae25fb291e0 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -196,7 +196,7 @@ /*** CFI CONFIG ***/ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI /* Bypass cache when reading regs from flash memory */ #define CFG_FLASH_CFI_BYPASS_READ diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 6fe2b7cc3bc..f019bb44eab 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -172,7 +172,7 @@ /*** CFI CONFIG ***/ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI /* Bypass cache when reading regs from flash memory */ #define CFG_FLASH_CFI_BYPASS_READ diff --git a/include/configs/grsim.h b/include/configs/grsim.h index 3fb8eb3a618..f880a7b5198 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -202,7 +202,7 @@ /*** CFI CONFIG ***/ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #endif diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h index 406ce3df373..e5af9a6e97f 100644 --- a/include/configs/grsim_leon2.h +++ b/include/configs/grsim_leon2.h @@ -199,7 +199,7 @@ /*** CFI CONFIG ***/ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #endif diff --git a/include/configs/hcu4.h b/include/configs/hcu4.h index 13b0358cb69..d99ac5355e6 100644 --- a/include/configs/hcu4.h +++ b/include/configs/hcu4.h @@ -105,7 +105,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* board provides its own flash_init code */ #define CONFIG_FLASH_CFI_LEGACY 1 #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT diff --git a/include/configs/hcu5.h b/include/configs/hcu5.h index 20808681f31..54d6721145d 100644 --- a/include/configs/hcu5.h +++ b/include/configs/hcu5.h @@ -351,7 +351,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* board provides its own flash_init code */ #define CONFIG_FLASH_CFI_LEGACY 1 #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT diff --git a/include/configs/hmi1001.h b/include/configs/hmi1001.h index ad7cf76869a..205f5ccb03a 100644 --- a/include/configs/hmi1001.h +++ b/include/configs/hmi1001.h @@ -155,7 +155,7 @@ #define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_CFI_AMD_RESET diff --git a/include/configs/imx31_litekit.h b/include/configs/imx31_litekit.h index ec4ed1eeb67..c4763335b6e 100644 --- a/include/configs/imx31_litekit.h +++ b/include/configs/imx31_litekit.h @@ -158,7 +158,7 @@ * CFI FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h index 7d6aaa1b54b..237f3616af4 100644 --- a/include/configs/imx31_phycore.h +++ b/include/configs/imx31_phycore.h @@ -164,7 +164,7 @@ * CFI FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/inka4x0.h b/include/configs/inka4x0.h index 6ec92c38c57..efa2802fee2 100644 --- a/include/configs/inka4x0.h +++ b/include/configs/inka4x0.h @@ -160,7 +160,7 @@ * Flash configuration */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_BASE 0xffe00000 #define CFG_FLASH_SIZE 0x00200000 #define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ diff --git a/include/configs/ixdp425.h b/include/configs/ixdp425.h index b7c43fedf32..6b73abe1f6f 100644 --- a/include/configs/ixdp425.h +++ b/include/configs/ixdp425.h @@ -181,7 +181,7 @@ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_ENV_IS_IN_FLASH 1 #define CFG_FLASH_BANKS_LIST { PHYS_FLASH_1 } diff --git a/include/configs/ixdpg425.h b/include/configs/ixdpg425.h index 05dc841e35c..d4e487124b1 100644 --- a/include/configs/ixdpg425.h +++ b/include/configs/ixdpg425.h @@ -210,7 +210,7 @@ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_ENV_IS_IN_FLASH 1 #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ diff --git a/include/configs/jupiter.h b/include/configs/jupiter.h index c9859270c00..af88a3fa2d1 100644 --- a/include/configs/jupiter.h +++ b/include/configs/jupiter.h @@ -191,7 +191,7 @@ #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT diff --git a/include/configs/katmai.h b/include/configs/katmai.h index f07e470683a..e056b011f2d 100644 --- a/include/configs/katmai.h +++ b/include/configs/katmai.h @@ -208,7 +208,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ diff --git a/include/configs/kb9202.h b/include/configs/kb9202.h index 7dcce836eb7..e775e60949b 100644 --- a/include/configs/kb9202.h +++ b/include/configs/kb9202.h @@ -153,7 +153,7 @@ #define CFG_MAXARGS 16 /* max number of command args */ #define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #ifndef __ASSEMBLY__ diff --git a/include/configs/kilauea.h b/include/configs/kilauea.h index 9c1a3a4c1e5..d94f967ba25 100644 --- a/include/configs/kilauea.h +++ b/include/configs/kilauea.h @@ -131,7 +131,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/korat.h b/include/configs/korat.h index 4ca4ed00667..a887446f262 100644 --- a/include/configs/korat.h +++ b/include/configs/korat.h @@ -110,7 +110,7 @@ * FLASH related */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CONFIG_FLASH_CFI_LEGACY /* Allow hard-coded config for FLASH0 */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH1_ADDR, CFG_FLASH0_ADDR } diff --git a/include/configs/kvme080.h b/include/configs/kvme080.h index 569800aa231..819e456e459 100644 --- a/include/configs/kvme080.h +++ b/include/configs/kvme080.h @@ -142,7 +142,7 @@ #define CFG_BOOTMAPSZ (8 << 20) #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_USE_BUFFER_WRITE #define CFG_FLASH_PROTECTION #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/linkstation.h b/include/configs/linkstation.h index bc642941162..e5a0fb97153 100644 --- a/include/configs/linkstation.h +++ b/include/configs/linkstation.h @@ -434,7 +434,7 @@ * FLASH organization */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #undef CFG_FLASH_PROTECTION #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index 2f3a0660628..3d135c4eaa6 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -124,7 +124,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH0 0xFC000000 #define CFG_FLASH1 0xF8000000 diff --git a/include/configs/m501sk.h b/include/configs/m501sk.h index e4be1ed33fe..bc94cf4a332 100644 --- a/include/configs/m501sk.h +++ b/include/configs/m501sk.h @@ -57,7 +57,7 @@ * Hardware drivers */ #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_ENV_SECT_SIZE 0x20000 #define CFG_FLASH_USE_BUFFER_WRITE #define CFG_FLASH_PROTECTION /*for Intel P30 Flash*/ diff --git a/include/configs/makalu.h b/include/configs/makalu.h index 65b240e0f18..ddfc5e39e36 100644 --- a/include/configs/makalu.h +++ b/include/configs/makalu.h @@ -125,7 +125,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/mcc200.h b/include/configs/mcc200.h index e4c3f7239be..f5128474479 100644 --- a/include/configs/mcc200.h +++ b/include/configs/mcc200.h @@ -211,7 +211,7 @@ #define CFG_FLASH_SIZE 0x04000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/mcu25.h b/include/configs/mcu25.h index 4e9645e5851..6adba9616fc 100644 --- a/include/configs/mcu25.h +++ b/include/configs/mcu25.h @@ -105,7 +105,7 @@ /* Use common CFI driver */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER /* board provides its own flash_init code */ #define CONFIG_FLASH_CFI_LEGACY 1 #define CFG_FLASH_CFI_WIDTH FLASH_CFI_8BIT diff --git a/include/configs/mecp5200.h b/include/configs/mecp5200.h index 8dfb9aa8a96..75040fece6e 100644 --- a/include/configs/mecp5200.h +++ b/include/configs/mecp5200.h @@ -203,7 +203,7 @@ #define CONFIG_ENV_OVERWRITE 1 #endif -#define CFG_FLASH_CFI_DRIVER 1 /* Flash is CFI conformant */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Flash is CFI conformant */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ #define CFG_FLASH_PROTECTION 1 /* use hardware protection */ #if 0 diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h index 59ff96b5c54..5fe3075efc4 100644 --- a/include/configs/mgcoge.h +++ b/include/configs/mgcoge.h @@ -153,7 +153,7 @@ #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_SIZE 32 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 512 /* max num of sects on one chip */ diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h index 9cbc9ccf93f..6f1c640b1a3 100644 --- a/include/configs/mgsuvd.h +++ b/include/configs/mgsuvd.h @@ -189,7 +189,7 @@ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_FLASH_SIZE 32 #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_MAX_FLASH_SECT 256 /* max num of sects on one chip */ diff --git a/include/configs/ml401.h b/include/configs/ml401.h index 7e0df870191..36a42ba6fc2 100644 --- a/include/configs/ml401.h +++ b/include/configs/ml401.h @@ -154,7 +154,7 @@ #define CFG_FLASH_BASE XILINX_FLASH_START #define CFG_FLASH_SIZE XILINX_FLASH_SIZE #define CFG_FLASH_CFI 1 - #define CFG_FLASH_CFI_DRIVER 1 + #define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_EMPTY_INFO 1 /* ?empty sector */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ diff --git a/include/configs/motionpro.h b/include/configs/motionpro.h index 3d1eafee696..f2a35ee2b39 100644 --- a/include/configs/motionpro.h +++ b/include/configs/motionpro.h @@ -263,7 +263,7 @@ * Flash configuration */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_BASE 0xff000000 #define CFG_FLASH_SIZE 0x01000000 #define CFG_MAX_FLASH_BANKS 1 /* max num of memory banks */ diff --git a/include/configs/mpc7448hpc2.h b/include/configs/mpc7448hpc2.h index 2f249674050..d379b1fb053 100644 --- a/include/configs/mpc7448hpc2.h +++ b/include/configs/mpc7448hpc2.h @@ -374,7 +374,7 @@ #define FLASH_BANK_SIZE 0x01000000 /* 16 MB Total */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, /* CFG_FLASH_BASE2 */ } -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_WRITE_SWAPPED_DATA diff --git a/include/configs/mpr2.h b/include/configs/mpr2.h index 2598b342f41..3df6e39f49d 100644 --- a/include/configs/mpr2.h +++ b/include/configs/mpr2.h @@ -67,7 +67,7 @@ /* Flash */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_BASE 0xA0000000 #define CFG_MAX_FLASH_SECT 256 diff --git a/include/configs/ms7720se.h b/include/configs/ms7720se.h index dc0af1594ee..1c3d2771b08 100644 --- a/include/configs/ms7720se.h +++ b/include/configs/ms7720se.h @@ -82,7 +82,7 @@ /* FLASH */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_QUIET_TEST #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ diff --git a/include/configs/ms7722se.h b/include/configs/ms7722se.h index 910a44eb4a5..3809e7120cd 100644 --- a/include/configs/ms7722se.h +++ b/include/configs/ms7722se.h @@ -90,7 +90,7 @@ /* FLASH */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_QUIET_TEST #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ diff --git a/include/configs/ms7750se.h b/include/configs/ms7750se.h index bee0aab1334..4356a671e83 100644 --- a/include/configs/ms7750se.h +++ b/include/configs/ms7750se.h @@ -86,7 +86,7 @@ #define CFG_RX_ETH_BUFFER (8) #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_CFI_BROKEN_TABLE #undef CFG_FLASH_QUIET_TEST #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ diff --git a/include/configs/munices.h b/include/configs/munices.h index e0046ec2d38..cea2834305d 100644 --- a/include/configs/munices.h +++ b/include/configs/munices.h @@ -133,7 +133,7 @@ */ #define CFG_FLASH_BASE 0xFF000000 #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x01000000 /* 16 MByte */ diff --git a/include/configs/mx31ads.h b/include/configs/mx31ads.h index 37ba872a439..9ede7645d9e 100644 --- a/include/configs/mx31ads.h +++ b/include/configs/mx31ads.h @@ -185,7 +185,7 @@ * CFI FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/cfi_flash.c */ #define CONFIG_FLASH_SPANSION_S29WS_N 1 /* A non-standard buffered write algorithm */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/omap1510inn.h b/include/configs/omap1510inn.h index 0be46eacec7..46b30e025a4 100644 --- a/include/configs/omap1510inn.h +++ b/include/configs/omap1510inn.h @@ -179,7 +179,7 @@ * FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/omap2420h4.h b/include/configs/omap2420h4.h index 88a3f6eb95b..aac5d0fc7e5 100644 --- a/include/configs/omap2420h4.h +++ b/include/configs/omap2420h4.h @@ -283,7 +283,7 @@ * CFI FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* Use buffered writes (~10x faster) */ #define CFG_FLASH_PROTECTION 1 /* Use hardware sector protection */ diff --git a/include/configs/omap5912osk.h b/include/configs/omap5912osk.h index e3bde4ff81d..1c44ce032fe 100644 --- a/include/configs/omap5912osk.h +++ b/include/configs/omap5912osk.h @@ -174,7 +174,7 @@ * FLASH driver setup */ #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use drivers/mtd/cfi_flash.c */ #define CFG_FLASH_BANKS_LIST { PHYS_FLASH_1, PHYS_FLASH_2 } diff --git a/include/configs/p3mx.h b/include/configs/p3mx.h index 0913b14a4ca..33a94bc2ca7 100644 --- a/include/configs/p3mx.h +++ b/include/configs/p3mx.h @@ -128,7 +128,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_MAX_FLASH_SECT 512 /* max number of sectors on one chip */ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ diff --git a/include/configs/p3p440.h b/include/configs/p3p440.h index 82f239117e3..ac0d83ac1c5 100644 --- a/include/configs/p3p440.h +++ b/include/configs/p3p440.h @@ -279,7 +279,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH3, CFG_FLASH2, CFG_FLASH1, CFG_FLASH0 } diff --git a/include/configs/pdnb3.h b/include/configs/pdnb3.h index aca70dce69b..889207a94e6 100644 --- a/include/configs/pdnb3.h +++ b/include/configs/pdnb3.h @@ -218,7 +218,7 @@ */ #if defined(CONFIG_SCPU) #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_WIDTH FLASH_CFI_16BIT /* no byte writes on IXP4xx */ #endif diff --git a/include/configs/ppmc8260.h b/include/configs/ppmc8260.h index dee664361f9..6f1195b1e50 100644 --- a/include/configs/ppmc8260.h +++ b/include/configs/ppmc8260.h @@ -452,7 +452,7 @@ */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ #define CFG_FLASH_INCREMENT 0 /* there is only one bank */ diff --git a/include/configs/pxa255_idp.h b/include/configs/pxa255_idp.h index a2f365042c9..179ff7ad50a 100644 --- a/include/configs/pxa255_idp.h +++ b/include/configs/pxa255_idp.h @@ -333,7 +333,7 @@ * FLASH and environment organization */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_MONITOR_BASE 0 #define CFG_MONITOR_LEN PHYS_FLASH_SECT_SIZE diff --git a/include/configs/qemu-mips.h b/include/configs/qemu-mips.h index 3dfd2181f48..19e627b61ca 100644 --- a/include/configs/qemu-mips.h +++ b/include/configs/qemu-mips.h @@ -146,7 +146,7 @@ #define CFG_MAX_FLASH_BANKS 1 #define CFG_MAX_FLASH_SECT 128 #define CFG_FLASH_CFI 1 /* Flash memory is CFI compliant */ -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_FLASH_USE_BUFFER_WRITE 1 #define CFG_ENV_IS_IN_FLASH 1 diff --git a/include/configs/quad100hd.h b/include/configs/quad100hd.h index 622a5d4cccd..d464734dadc 100644 --- a/include/configs/quad100hd.h +++ b/include/configs/quad100hd.h @@ -182,7 +182,7 @@ * FLASH organization */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/quantum.h b/include/configs/quantum.h index cc261c33e10..34a1ea6e2c6 100644 --- a/include/configs/quantum.h +++ b/include/configs/quantum.h @@ -170,13 +170,13 @@ #define CFG_FLASH_BASE 0xFF000000 #if 1 - #define CFG_FLASH_CFI_DRIVER + #define CONFIG_FLASH_CFI_DRIVER #else - #undef CFG_FLASH_CFI_DRIVER + #undef CONFIG_FLASH_CFI_DRIVER #endif -#ifdef CFG_FLASH_CFI_DRIVER +#ifdef CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI 1 #undef CFG_FLASH_USE_BUFFER_WRITE #define CFG_FLASH_BANKS_LIST {CFG_FLASH_BASE} diff --git a/include/configs/r2dplus.h b/include/configs/r2dplus.h index 414e8dca571..06ede3e039a 100644 --- a/include/configs/r2dplus.h +++ b/include/configs/r2dplus.h @@ -65,7 +65,7 @@ * NOR Flash ( Spantion S29GL256P ) */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_BASE (0xA0000000) #define CFG_MAX_FLASH_BANKS (1) #define CFG_MAX_FLASH_SECT 256 diff --git a/include/configs/r7780mp.h b/include/configs/r7780mp.h index 0b08f18be17..77881e7a28d 100644 --- a/include/configs/r7780mp.h +++ b/include/configs/r7780mp.h @@ -106,7 +106,7 @@ #define CFG_RX_ETH_BUFFER (8) #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_CFI_BROKEN_TABLE #undef CFG_FLASH_QUIET_TEST /* print 'E' for empty sector on flinfo */ diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 74815567ff9..261229c489c 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -133,7 +133,7 @@ * FLASH on the Local Bus */ #define CFG_FLASH_CFI /* use the Common Flash Interface */ -#define CFG_FLASH_CFI_DRIVER /* use the CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* use the CFI driver */ #define CFG_FLASH_BASE 0xFF800000 /* start of FLASH */ #define CFG_FLASH_SIZE 8 /* flash size in MB */ /* #define CFG_FLASH_USE_BUFFER_WRITE */ diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 358fc0208e9..b4238e566f3 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -178,7 +178,7 @@ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/sbc8560.h b/include/configs/sbc8560.h index 6345cce635e..b244eef950c 100644 --- a/include/configs/sbc8560.h +++ b/include/configs/sbc8560.h @@ -290,7 +290,7 @@ */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #if 0 #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ #define CFG_FLASH_PROTECTION /* use hardware protection */ diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index ebfcb463247..efc787e9993 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -223,7 +223,7 @@ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ #define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_WRITE_SWAPPED_DATA #define CFG_FLASH_EMPTY_INFO diff --git a/include/configs/sc3.h b/include/configs/sc3.h index 87311ea6c7a..659f74ed954 100644 --- a/include/configs/sc3.h +++ b/include/configs/sc3.h @@ -397,7 +397,7 @@ extern unsigned long offsetOfEnvironment; #define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ #define CFG_FLASH_CFI /* flash is CFI compat. */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver*/ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver*/ #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector */ #define CFG_FLASH_QUIET_TEST 1 /* don't warn upon unknown flash*/ #define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ diff --git a/include/configs/sequoia.h b/include/configs/sequoia.h index 730037e6f30..18675c2d536 100644 --- a/include/configs/sequoia.h +++ b/include/configs/sequoia.h @@ -123,7 +123,7 @@ * FLASH related */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } diff --git a/include/configs/sh7763rdp.h b/include/configs/sh7763rdp.h index 47236341bdf..1306702fcbb 100644 --- a/include/configs/sh7763rdp.h +++ b/include/configs/sh7763rdp.h @@ -89,7 +89,7 @@ #define CFG_BOOTMAPSZ (8 * 1024 * 1024) #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #undef CFG_FLASH_QUIET_TEST #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ /* Timeout for Flash erase operations (in ms) */ diff --git a/include/configs/smmaco4.h b/include/configs/smmaco4.h index 3e47eb88a7c..1d202d4b2f8 100644 --- a/include/configs/smmaco4.h +++ b/include/configs/smmaco4.h @@ -196,7 +196,7 @@ /* use CFI flash driver if no module variant is spezified */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */ diff --git a/include/configs/socrates.h b/include/configs/socrates.h index 16274137dc6..8a649425b4a 100644 --- a/include/configs/socrates.h +++ b/include/configs/socrates.h @@ -139,7 +139,7 @@ #define CFG_OR1_PRELIM 0xfe000ff7 /* 32MB Flash */ #define CFG_FLASH_CFI /* flash is CFI compat. */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver*/ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver*/ #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector */ #define CFG_MAX_FLASH_BANKS 2 /* number of banks */ diff --git a/include/configs/sorcery.h b/include/configs/sorcery.h index 18f55337370..f4e460800cf 100644 --- a/include/configs/sorcery.h +++ b/include/configs/sorcery.h @@ -189,7 +189,7 @@ #define CFG_MAX_FLASH_BANKS 2 /* max num of flash banks */ #define CFG_MAX_FLASH_SECT 512 /* max num of sects on one chip */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, \ CFG_FLASH_BASE+0x04000000 } /* two banks */ diff --git a/include/configs/spc1920.h b/include/configs/spc1920.h index f46c464cbc0..daaa23f48e7 100644 --- a/include/configs/spc1920.h +++ b/include/configs/spc1920.h @@ -180,7 +180,7 @@ */ #define CFG_FLASH_BASE 0xFE000000 #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_MAX_FLASH_BANKS 1 /* Max number of flash banks */ #define CFG_MAX_FLASH_SECT 128 /* Max num of sects on one chip */ diff --git a/include/configs/spieval.h b/include/configs/spieval.h index 69d2d67ab1c..93798a46f96 100644 --- a/include/configs/spieval.h +++ b/include/configs/spieval.h @@ -287,7 +287,7 @@ /* use CFI flash driver if no module variant is spezified */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_BOOTCS_START } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_SIZE 0x04000000 /* 64 MByte */ diff --git a/include/configs/stxssa.h b/include/configs/stxssa.h index a1e9789ea01..4f1c1563553 100644 --- a/include/configs/stxssa.h +++ b/include/configs/stxssa.h @@ -98,7 +98,7 @@ #define CFG_OR0_PRELIM (CFG_FLASH_BASE | 0x0FF7) #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #undef CFG_FLASH_USE_BUFFER_WRITE /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/stxxtc.h b/include/configs/stxxtc.h index fcafba59379..2bdce303cf7 100644 --- a/include/configs/stxxtc.h +++ b/include/configs/stxxtc.h @@ -213,7 +213,7 @@ #define CFG_ENV_SIZE_REDUND CFG_ENV_SIZE #define CFG_FLASH_CFI 1 -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #undef CFG_FLASH_USE_BUFFER_WRITE /* use buffered writes (20x faster) */ #define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */ #define CFG_MAX_FLASH_BANKS 2 /* max number of memory banks */ diff --git a/include/configs/taishan.h b/include/configs/taishan.h index ba421925edc..81133bb5c86 100644 --- a/include/configs/taishan.h +++ b/include/configs/taishan.h @@ -89,7 +89,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_EMPTY_INFO /* print 'E' for empty sector on flinfo */ #define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes (20x faster) */ diff --git a/include/configs/trizepsiv.h b/include/configs/trizepsiv.h index f77dd14f1a8..6367f873ef9 100644 --- a/include/configs/trizepsiv.h +++ b/include/configs/trizepsiv.h @@ -293,7 +293,7 @@ */ #define CFG_FLASH_CFI -#define CFG_FLASH_CFI_DRIVER 1 +#define CONFIG_FLASH_CFI_DRIVER 1 #define CFG_MONITOR_BASE 0 #define CFG_MONITOR_LEN 0x40000 diff --git a/include/configs/uc100.h b/include/configs/uc100.h index e74b1bb85ba..106e6f27591 100644 --- a/include/configs/uc100.h +++ b/include/configs/uc100.h @@ -230,7 +230,7 @@ * FLASH organization */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_AMD_RESET 1 /* AMD RESET for STM 29W320DB! */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/uc101.h b/include/configs/uc101.h index 042750e2fe9..a18618893cd 100644 --- a/include/configs/uc101.h +++ b/include/configs/uc101.h @@ -168,7 +168,7 @@ #define CFG_FLASH_ERASE_TOUT 240000 /* Flash Erase Timeout (in ms) */ #define CFG_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (in ms) */ -#define CFG_FLASH_CFI_DRIVER +#define CONFIG_FLASH_CFI_DRIVER #define CFG_FLASH_CFI #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_CFI_AMD_RESET diff --git a/include/configs/v38b.h b/include/configs/v38b.h index c2035225526..35745484d44 100644 --- a/include/configs/v38b.h +++ b/include/configs/v38b.h @@ -201,7 +201,7 @@ * Flash configuration - use CFI driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_CFI_AMD_RESET 1 #define CFG_FLASH_BASE 0xFF000000 #define CFG_MAX_FLASH_BANKS 1 /* max num of flash banks */ diff --git a/include/configs/virtlab2.h b/include/configs/virtlab2.h index f1048861d86..1a125f16ce8 100644 --- a/include/configs/virtlab2.h +++ b/include/configs/virtlab2.h @@ -202,7 +202,7 @@ /* use CFI flash driver */ #define CFG_FLASH_CFI 1 /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER 1 /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER 1 /* Use the common driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE, CFG_FLASH_BASE+flash_info[0].size } #define CFG_FLASH_EMPTY_INFO #define CFG_FLASH_USE_BUFFER_WRITE 1 diff --git a/include/configs/voiceblue.h b/include/configs/voiceblue.h index 8c827af315e..20917ee9a5c 100644 --- a/include/configs/voiceblue.h +++ b/include/configs/voiceblue.h @@ -60,7 +60,7 @@ * FLASH organization */ #define CFG_FLASH_CFI /* Flash is CFI conformant */ -#define CFG_FLASH_CFI_DRIVER /* Use the common driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use the common driver */ #define CFG_MAX_FLASH_BANKS 1 #define CFG_FLASH_BASE PHYS_FLASH_1 diff --git a/include/configs/yosemite.h b/include/configs/yosemite.h index 891b515d4ec..cb2042ce6ce 100644 --- a/include/configs/yosemite.h +++ b/include/configs/yosemite.h @@ -105,7 +105,7 @@ * FLASH related *----------------------------------------------------------------------*/ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_CFI_AMD_RESET 1 /* AMD RESET for STM 29W320DB! */ #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ diff --git a/include/configs/zeus.h b/include/configs/zeus.h index cd120dfbf13..b50cba556cf 100644 --- a/include/configs/zeus.h +++ b/include/configs/zeus.h @@ -210,7 +210,7 @@ * FLASH organization */ #define CFG_FLASH_CFI /* The flash is CFI compatible */ -#define CFG_FLASH_CFI_DRIVER /* Use common CFI driver */ +#define CONFIG_FLASH_CFI_DRIVER /* Use common CFI driver */ #define CFG_FLASH_BANKS_LIST { CFG_FLASH_BASE } -- cgit v1.3.1 From 4fb09b81920e5dfdfc4576883186733f0bd6059c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:42 +0200 Subject: drivers/mtd/onenand: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/mtd/onenand/Makefile | 3 ++- drivers/mtd/onenand/onenand_base.c | 5 ----- drivers/mtd/onenand/onenand_bbt.c | 5 ----- drivers/mtd/onenand/onenand_uboot.c | 5 ----- 4 files changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile index 92074b25528..1d35a57d84f 100644 --- a/drivers/mtd/onenand/Makefile +++ b/drivers/mtd/onenand/Makefile @@ -25,8 +25,9 @@ include $(TOPDIR)/config.mk LIB := $(obj)libonenand.a -COBJS := onenand_uboot.o onenand_base.o onenand_bbt.o +COBJS-$(CONFIG_CMD_ONENAND) := onenand_uboot.o onenand_base.o onenand_bbt.o +COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index ded1706abbe..7c9438be316 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -10,9 +10,6 @@ */ #include - -#ifdef CONFIG_CMD_ONENAND - #include #include #include @@ -1304,5 +1301,3 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) void onenand_release(struct mtd_info *mtd) { } - -#endif /* CONFIG_CMD_ONENAND */ diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 87344ab65f1..0abaa1ab38c 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -15,9 +15,6 @@ */ #include - -#ifdef CONFIG_CMD_ONENAND - #include #include #include @@ -261,5 +258,3 @@ int onenand_default_bbt(struct mtd_info *mtd) return onenand_scan_bbt(mtd, bbm->badblock_pattern); } - -#endif /* CFG_CMD_ONENAND */ diff --git a/drivers/mtd/onenand/onenand_uboot.c b/drivers/mtd/onenand/onenand_uboot.c index bd7466ac9d9..d614450616f 100644 --- a/drivers/mtd/onenand/onenand_uboot.c +++ b/drivers/mtd/onenand/onenand_uboot.c @@ -14,9 +14,6 @@ */ #include - -#ifdef CONFIG_CMD_ONENAND - #include #include #include @@ -37,5 +34,3 @@ void onenand_init(void) puts("OneNAND: "); print_size(onenand_mtd.size, "\n"); } - -#endif /* CONFIG_CMD_ONENAND */ -- cgit v1.3.1 From cc4a0ceeac5462106172d0cc9d9d542233aa3ab2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:43 +0200 Subject: drivers/mtd/nand: Move conditional compilation to Makefile rename CFG_NAND_LEGACY to CONFIG_NAND_LEGACY Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- board/delta/nand.c | 2 +- board/esd/common/auto_update.c | 12 ++++++------ board/netta/netta.c | 2 +- common/cmd_jffs2.c | 12 ++++++------ common/cmd_nand.c | 6 +++--- cpu/arm920t/s3c24x0/nand.c | 2 +- cpu/arm926ejs/davinci/nand.c | 2 +- cpu/ppc4xx/ndfc.c | 2 +- doc/README.nand | 2 +- drivers/mtd/nand/Makefile | 10 +++++++--- drivers/mtd/nand/diskonchip.c | 2 +- drivers/mtd/nand/fsl_upm.c | 3 --- drivers/mtd/nand/nand.c | 5 ----- drivers/mtd/nand/nand_base.c | 5 ----- drivers/mtd/nand/nand_bbt.c | 5 ----- drivers/mtd/nand/nand_ecc.c | 4 ---- drivers/mtd/nand/nand_ids.c | 4 ---- drivers/mtd/nand/nand_util.c | 5 ----- drivers/mtd/nand_legacy/nand_legacy.c | 2 +- fs/jffs2/jffs2_1pass.c | 6 +++--- fs/jffs2/jffs2_nand_1pass.c | 2 +- include/configs/BMW.h | 2 +- include/configs/CPU87.h | 2 +- include/configs/GEN860T.h | 2 +- include/configs/IDS8247.h | 2 +- include/configs/MIP405.h | 2 +- include/configs/NETPHONE.h | 2 +- include/configs/NETTA.h | 2 +- include/configs/NETTA2.h | 2 +- include/configs/NETVIA.h | 2 +- include/configs/PCIPPC2.h | 2 +- include/configs/PCIPPC6.h | 2 +- include/configs/PIP405.h | 2 +- include/configs/PM520.h | 2 +- include/configs/PM826.h | 2 +- include/configs/PM828.h | 2 +- include/configs/SXNI855T.h | 2 +- include/configs/TQM85xx.h | 2 +- include/configs/VCMA9.h | 2 +- include/configs/at91rm9200dk.h | 2 +- include/configs/delta.h | 2 +- include/configs/omap2420h4.h | 2 +- include/configs/stxxtc.h | 2 +- include/configs/svm_sc8xx.h | 2 +- include/linux/mtd/nand_ids.h | 2 +- include/linux/mtd/nand_legacy.h | 2 +- include/nand.h | 4 ++-- lib_generic/crc32.c | 2 +- 48 files changed, 62 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/board/delta/nand.c b/board/delta/nand.c index b007b090d05..4ce78a1e1da 100644 --- a/board/delta/nand.c +++ b/board/delta/nand.c @@ -23,7 +23,7 @@ #include #if defined(CONFIG_CMD_NAND) -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include #include diff --git a/board/esd/common/auto_update.c b/board/esd/common/auto_update.c index 7e6eea0f1c8..a1e0ce5a271 100644 --- a/board/esd/common/auto_update.c +++ b/board/esd/common/auto_update.c @@ -27,7 +27,7 @@ #include #include #include -#if defined(CFG_NAND_LEGACY) +#if defined(CONFIG_NAND_LEGACY) #include #endif #include @@ -58,7 +58,7 @@ extern int flash_sect_erase(ulong, ulong); extern int flash_sect_protect (int, ulong, ulong); extern int flash_write (char *, ulong, ulong); -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) /* references to names in cmd_nand.c */ #define NANDRW_READ 0x01 #define NANDRW_WRITE 0x00 @@ -158,7 +158,7 @@ int au_do_update(int i, long sz) int off, rc; uint nbytes; int k; -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) int total; #endif @@ -241,7 +241,7 @@ int au_do_update(int i, long sz) debug ("flash_sect_erase(%lx, %lx);\n", start, end); flash_sect_erase (start, end); } else { -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) printf ("Updating NAND FLASH with image %s\n", au_image[i].name); debug ("nand_legacy_erase(%lx, %lx);\n", start, end); @@ -273,7 +273,7 @@ int au_do_update(int i, long sz) rc = flash_write ((char *)addr, start, (nbytes + 1) & ~1); } else { -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) debug ("nand_legacy_rw(%p, %lx, %x)\n", addr, start, nbytes); rc = nand_legacy_rw (nand_dev_desc, @@ -298,7 +298,7 @@ int au_do_update(int i, long sz) rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)); } else { -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) rc = nand_legacy_rw (nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP, diff --git a/board/netta/netta.c b/board/netta/netta.c index 1183f33ef8c..bc31386ec7e 100644 --- a/board/netta/netta.c +++ b/board/netta/netta.c @@ -555,7 +555,7 @@ int board_early_init_f(void) return 0; } -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) #include diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index b4698bee478..c031d803491 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -96,12 +96,12 @@ #include #if defined(CONFIG_CMD_NAND) -#ifdef CFG_NAND_LEGACY +#ifdef CONFIG_NAND_LEGACY #include -#else /* !CFG_NAND_LEGACY */ +#else /* !CONFIG_NAND_LEGACY */ #include #include -#endif /* !CFG_NAND_LEGACY */ +#endif /* !CONFIG_NAND_LEGACY */ #endif /* enable/disable debugging messages */ #define DEBUG_JFFS @@ -476,7 +476,7 @@ static int part_del(struct mtd_device *dev, struct part_info *part) } } -#ifdef CFG_NAND_LEGACY +#ifdef CONFIG_NAND_LEGACY jffs2_free_cache(part); #endif list_del(&part->link); @@ -505,7 +505,7 @@ static void part_delall(struct list_head *head) list_for_each_safe(entry, n, head) { part_tmp = list_entry(entry, struct part_info, link); -#ifdef CFG_NAND_LEGACY +#ifdef CONFIG_NAND_LEGACY jffs2_free_cache(part_tmp); #endif list_del(entry); @@ -741,7 +741,7 @@ static int device_validate(u8 type, u8 num, u32 *size) } else if (type == MTD_DEV_TYPE_NAND) { #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) if (num < CFG_MAX_NAND_DEVICE) { -#ifndef CFG_NAND_LEGACY +#ifndef CONFIG_NAND_LEGACY *size = nand_info[num].size; #else extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE]; diff --git a/common/cmd_nand.c b/common/cmd_nand.c index 520c15217c2..fa7a438b5ff 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -11,7 +11,7 @@ #include -#ifndef CFG_NAND_LEGACY +#ifndef CONFIG_NAND_LEGACY /* * * New NAND support @@ -667,7 +667,7 @@ U_BOOT_CMD(nboot, 4, 1, do_nandboot, #endif -#else /* CFG_NAND_LEGACY */ +#else /* CONFIG_NAND_LEGACY */ /* * * Legacy NAND support - to be phased out @@ -1077,4 +1077,4 @@ U_BOOT_CMD( #endif -#endif /* CFG_NAND_LEGACY */ +#endif /* CONFIG_NAND_LEGACY */ diff --git a/cpu/arm920t/s3c24x0/nand.c b/cpu/arm920t/s3c24x0/nand.c index e1bf128157b..14882cb2438 100644 --- a/cpu/arm920t/s3c24x0/nand.c +++ b/cpu/arm920t/s3c24x0/nand.c @@ -27,7 +27,7 @@ #endif #if defined(CONFIG_CMD_NAND) -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include #include diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c index 8fd784e7906..2aa01d6f78e 100644 --- a/cpu/arm926ejs/davinci/nand.c +++ b/cpu/arm926ejs/davinci/nand.c @@ -45,7 +45,7 @@ #include #ifdef CFG_USE_NAND -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include #include diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c index 4f083d95bc1..72acfd01b5e 100644 --- a/cpu/ppc4xx/ndfc.c +++ b/cpu/ppc4xx/ndfc.c @@ -31,7 +31,7 @@ #include -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) && \ +#if defined(CONFIG_CMD_NAND) && !defined(CONFIG_NAND_LEGACY) && \ (defined(CONFIG_440EP) || defined(CONFIG_440GR) || \ defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ defined(CONFIG_405EZ) || defined(CONFIG_405EX) || \ diff --git a/doc/README.nand b/doc/README.nand index 0ad5e18dd39..171380e274f 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -184,7 +184,7 @@ We now use a complete rewrite of the NAND code based on what is in The old NAND handling code has been re-factored and is now confined to only board-specific files and - unfortunately - to the DoC code (see below). A new configuration variable has been introduced: -CFG_NAND_LEGACY, which has to be defined in the board config file if +CONFIG_NAND_LEGACY, which has to be defined in the board config file if that board uses legacy code. The necessary changes have been made to all affected boards, and no diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index ffb31695945..19233105a20 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -25,15 +25,19 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnand.a +ifdef CONFIG_CMD_NAND +ifndef CONFIG_NAND_LEGACY COBJS-y += nand.o COBJS-y += nand_base.o -COBJS-y += nand_ids.o -COBJS-y += nand_ecc.o COBJS-y += nand_bbt.o +COBJS-y += nand_ecc.o +COBJS-y += nand_ids.o COBJS-y += nand_util.o +endif COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o -COBJS-y += fsl_upm.o +COBJS-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o +endif COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index ce197f5ad16..4cba8100a5f 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c @@ -21,7 +21,7 @@ #include -#if !defined(CFG_NAND_LEGACY) +#if !defined(CONFIG_NAND_LEGACY) #include #include diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index e651903040b..1a1d8c4e612 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c @@ -11,8 +11,6 @@ */ #include - -#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_FSL_UPM) #include #include #include @@ -150,4 +148,3 @@ int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun) return 0; } -#endif /* CONFIG_CMD_NAND */ diff --git a/drivers/mtd/nand/nand.c b/drivers/mtd/nand/nand.c index e44470eb6cc..ebd2acd02bf 100644 --- a/drivers/mtd/nand/nand.c +++ b/drivers/mtd/nand/nand.c @@ -22,9 +22,6 @@ */ #include - -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - #include #ifndef CFG_NAND_BASE_LIST @@ -79,5 +76,3 @@ void nand_init(void) board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device); #endif } - -#endif diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a29ff1146f2..0913bb87418 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -59,8 +59,6 @@ #define ENOTSUPP 524 /* Operation is not supported */ -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - #include #include #include @@ -2822,6 +2820,3 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Steven J. Hill , Thomas Gleixner "); MODULE_DESCRIPTION("Generic NAND flash driver code"); #endif - -#endif - diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 84479473b6d..b3b740da641 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -53,9 +53,6 @@ */ #include - -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - #include #include #include @@ -1237,5 +1234,3 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) EXPORT_SYMBOL(nand_scan_bbt); EXPORT_SYMBOL(nand_default_bbt); #endif - -#endif diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index e1d5154db22..ee1f6cc8a85 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c @@ -39,8 +39,6 @@ #include -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - /* XXX U-BOOT XXX */ #if 0 #include @@ -215,5 +213,3 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, #if 0 EXPORT_SYMBOL(nand_correct_data); #endif - -#endif diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index f8b96cf025d..2ff75c94e91 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -12,9 +12,6 @@ */ #include - -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - #include /* * Chip ID list @@ -147,4 +144,3 @@ struct nand_manufacturers nand_manuf_ids[] = { {NAND_MFR_MICRON, "Micron"}, {0x0, "Unknown"} }; -#endif diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 02fe914db8b..22820d55d02 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -31,9 +31,6 @@ */ #include - -#if defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) - #include #include #include @@ -606,5 +603,3 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length, return 0; } - -#endif /* defined(CONFIG_CMD_NAND) && !defined(CFG_NAND_LEGACY) */ diff --git a/drivers/mtd/nand_legacy/nand_legacy.c b/drivers/mtd/nand_legacy/nand_legacy.c index fafefad60fe..8f7dc3901af 100644 --- a/drivers/mtd/nand_legacy/nand_legacy.c +++ b/drivers/mtd/nand_legacy/nand_legacy.c @@ -15,7 +15,7 @@ #include #include -#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY) +#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) #include #include diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 8a06777ae2a..b5e7ab8b19e 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -146,7 +146,7 @@ static struct part_info *current_part; #if (defined(CONFIG_JFFS2_NAND) && \ defined(CONFIG_CMD_NAND) ) -#if defined(CFG_NAND_LEGACY) +#if defined(CONFIG_NAND_LEGACY) #include #else #include @@ -161,7 +161,7 @@ static struct part_info *current_part; * */ -#if defined(CFG_NAND_LEGACY) +#if defined(CONFIG_NAND_LEGACY) /* this one defined in nand_legacy.c */ int read_jffs2_nand(size_t start, size_t len, size_t * retlen, u_char * buf, int nanddev); @@ -201,7 +201,7 @@ static int read_nand_cached(u32 off, u32 size, u_char *buf) } } -#if defined(CFG_NAND_LEGACY) +#if defined(CONFIG_NAND_LEGACY) if (read_jffs2_nand(nand_cache_off, NAND_CACHE_SIZE, &retlen, nand_cache, id->num) < 0 || retlen != NAND_CACHE_SIZE) { diff --git a/fs/jffs2/jffs2_nand_1pass.c b/fs/jffs2/jffs2_nand_1pass.c index 3ce9c982552..9f6de7d32a5 100644 --- a/fs/jffs2/jffs2_nand_1pass.c +++ b/fs/jffs2/jffs2_nand_1pass.c @@ -1,6 +1,6 @@ #include -#if !defined(CFG_NAND_LEGACY) && defined(CONFIG_CMD_JFFS2) +#if !defined(CONFIG_NAND_LEGACY) && defined(CONFIG_CMD_JFFS2) #include #include diff --git a/include/configs/BMW.h b/include/configs/BMW.h index bb7856f675d..11d19c6f7f5 100644 --- a/include/configs/BMW.h +++ b/include/configs/BMW.h @@ -86,7 +86,7 @@ /* CONFIG_CMD_DOC required legacy NAND support */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #if 0 #define CONFIG_PCI 1 diff --git a/include/configs/CPU87.h b/include/configs/CPU87.h index 3879d9b27a5..d325c4d076a 100644 --- a/include/configs/CPU87.h +++ b/include/configs/CPU87.h @@ -191,7 +191,7 @@ #endif -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/configs/GEN860T.h b/include/configs/GEN860T.h index 037b115c136..422ed32aaaa 100644 --- a/include/configs/GEN860T.h +++ b/include/configs/GEN860T.h @@ -280,7 +280,7 @@ #define CFG_FPGA_PROG_FEEDBACK -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Verbose help from command monitor. diff --git a/include/configs/IDS8247.h b/include/configs/IDS8247.h index 29dc6234ba7..029bb9914b7 100644 --- a/include/configs/IDS8247.h +++ b/include/configs/IDS8247.h @@ -262,7 +262,7 @@ */ #if defined(CONFIG_CMD_NAND) -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND0_BASE 0xE1000000 #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h index d683b87ae00..66235e37b41 100644 --- a/include/configs/MIP405.h +++ b/include/configs/MIP405.h @@ -88,7 +88,7 @@ #endif -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " diff --git a/include/configs/NETPHONE.h b/include/configs/NETPHONE.h index 27e7ab9bcec..6c18b816914 100644 --- a/include/configs/NETPHONE.h +++ b/include/configs/NETPHONE.h @@ -502,7 +502,7 @@ /****************************************************************/ /* NAND */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_ECC_JFFS2 #define CONFIG_MTD_NAND_VERIFY_WRITE diff --git a/include/configs/NETTA.h b/include/configs/NETTA.h index 56c76d3258c..1f1bc540bb4 100644 --- a/include/configs/NETTA.h +++ b/include/configs/NETTA.h @@ -621,7 +621,7 @@ /****************************************************************/ /* NAND */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_VERIFY_WRITE #define CONFIG_MTD_NAND_UNSAFE diff --git a/include/configs/NETTA2.h b/include/configs/NETTA2.h index b8c48482acb..9a1f1d6da5c 100644 --- a/include/configs/NETTA2.h +++ b/include/configs/NETTA2.h @@ -503,7 +503,7 @@ /****************************************************************/ /* NAND */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_ECC_JFFS2 #define CONFIG_MTD_NAND_VERIFY_WRITE diff --git a/include/configs/NETVIA.h b/include/configs/NETVIA.h index 1293fb0e2bc..c0295941870 100644 --- a/include/configs/NETVIA.h +++ b/include/configs/NETVIA.h @@ -397,7 +397,7 @@ /*****************************************************************************/ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2 diff --git a/include/configs/PCIPPC2.h b/include/configs/PCIPPC2.h index 268b0343a36..6ebaa85e8c0 100644 --- a/include/configs/PCIPPC2.h +++ b/include/configs/PCIPPC2.h @@ -84,7 +84,7 @@ #define CONFIG_PCI 1 #define CONFIG_PCI_PNP 1 /* PCI plug-and-play */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/configs/PCIPPC6.h b/include/configs/PCIPPC6.h index 250b5860481..9202794ab21 100644 --- a/include/configs/PCIPPC6.h +++ b/include/configs/PCIPPC6.h @@ -86,7 +86,7 @@ #define CONFIG_PCI 1 #define CONFIG_PCI_PNP 1 /* PCI plug-and-play */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h index 5890012b4ee..2ceda001cab 100644 --- a/include/configs/PIP405.h +++ b/include/configs/PIP405.h @@ -77,7 +77,7 @@ #define CONFIG_CMD_BSP -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_HUSH_PARSER #define CFG_PROMPT_HUSH_PS2 "> " diff --git a/include/configs/PM520.h b/include/configs/PM520.h index 259178f857b..5e0bb056d80 100644 --- a/include/configs/PM520.h +++ b/include/configs/PM520.h @@ -88,7 +88,7 @@ #if !defined(CONFIG_BOOT_ROM) /* DoC requires legacy NAND for now */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #endif diff --git a/include/configs/PM826.h b/include/configs/PM826.h index 36e9aa56ea3..190e2a44247 100644 --- a/include/configs/PM826.h +++ b/include/configs/PM826.h @@ -180,7 +180,7 @@ #endif -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Disk-On-Chip configuration diff --git a/include/configs/PM828.h b/include/configs/PM828.h index abf593cf712..96c0edf9397 100644 --- a/include/configs/PM828.h +++ b/include/configs/PM828.h @@ -183,7 +183,7 @@ /* * Disk-On-Chip configuration */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_DOC_SHORT_TIMEOUT #define CFG_MAX_DOC_DEVICE 1 /* Max number of DOC devices */ diff --git a/include/configs/SXNI855T.h b/include/configs/SXNI855T.h index aefc7eecbd1..c5d53868602 100644 --- a/include/configs/SXNI855T.h +++ b/include/configs/SXNI855T.h @@ -195,7 +195,7 @@ */ /* NAND flash support */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CONFIG_MTD_NAND_ECC_JFFS2 #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h index 964193fc065..d84554e37dc 100644 --- a/include/configs/TQM85xx.h +++ b/include/configs/TQM85xx.h @@ -345,7 +345,7 @@ /* NAND FLASH */ #ifdef CONFIG_NAND -#undef CFG_NAND_LEGACY +#undef CONFIG_NAND_LEGACY #define CONFIG_NAND_FSL_UPM 1 diff --git a/include/configs/VCMA9.h b/include/configs/VCMA9.h index ad8db613ec1..02cabb2fb81 100644 --- a/include/configs/VCMA9.h +++ b/include/configs/VCMA9.h @@ -254,7 +254,7 @@ */ #if defined(CONFIG_CMD_NAND) -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h index cd2eae20634..fca431e3baf 100644 --- a/include/configs/at91rm9200dk.h +++ b/include/configs/at91rm9200dk.h @@ -116,7 +116,7 @@ #define CONFIG_CMD_MII #define CONFIG_CMD_NAND -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 diff --git a/include/configs/delta.h b/include/configs/delta.h index 14fde1a9579..1db962aaf50 100644 --- a/include/configs/delta.h +++ b/include/configs/delta.h @@ -217,7 +217,7 @@ /* * NAND Flash */ -#undef CFG_NAND_LEGACY +#undef CONFIG_NAND_LEGACY #define CFG_NAND0_BASE 0x0 /* 0x43100040 */ /* 0x10000000 */ #undef CFG_NAND1_BASE diff --git a/include/configs/omap2420h4.h b/include/configs/omap2420h4.h index aac5d0fc7e5..afdcba41150 100644 --- a/include/configs/omap2420h4.h +++ b/include/configs/omap2420h4.h @@ -151,7 +151,7 @@ /* * Board NAND Info. */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND_ADDR 0x04000000 /* physical address to access nand at CS0*/ #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ diff --git a/include/configs/stxxtc.h b/include/configs/stxxtc.h index 2bdce303cf7..37a52cf7edb 100644 --- a/include/configs/stxxtc.h +++ b/include/configs/stxxtc.h @@ -449,7 +449,7 @@ /****************************************************************/ /* NAND */ -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY #define CFG_NAND_BASE NAND_BASE #define CONFIG_MTD_NAND_ECC_JFFS2 #define CONFIG_MTD_NAND_VERIFY_WRITE diff --git a/include/configs/svm_sc8xx.h b/include/configs/svm_sc8xx.h index 70336b5ebd0..bbbfa15db1d 100644 --- a/include/configs/svm_sc8xx.h +++ b/include/configs/svm_sc8xx.h @@ -151,7 +151,7 @@ #define CONFIG_CMD_DATE -#define CFG_NAND_LEGACY +#define CONFIG_NAND_LEGACY /* * Miscellaneous configurable options diff --git a/include/linux/mtd/nand_ids.h b/include/linux/mtd/nand_ids.h index d9eb9118280..e7aa26df048 100644 --- a/include/linux/mtd/nand_ids.h +++ b/include/linux/mtd/nand_ids.h @@ -28,7 +28,7 @@ #ifndef __LINUX_MTD_NAND_IDS_H #define __LINUX_MTD_NAND_IDS_H -#ifndef CFG_NAND_LEGACY +#ifndef CONFIG_NAND_LEGACY #error This module is for the legacy NAND support #endif diff --git a/include/linux/mtd/nand_legacy.h b/include/linux/mtd/nand_legacy.h index b05e7267e49..4494bc569d9 100644 --- a/include/linux/mtd/nand_legacy.h +++ b/include/linux/mtd/nand_legacy.h @@ -36,7 +36,7 @@ #ifndef __LINUX_MTD_NAND_LEGACY_H #define __LINUX_MTD_NAND_LEGACY_H -#ifndef CFG_NAND_LEGACY +#ifndef CONFIG_NAND_LEGACY #error This module is for the legacy NAND support #endif diff --git a/include/nand.h b/include/nand.h index 764e9f97229..4c2b76dd4b3 100644 --- a/include/nand.h +++ b/include/nand.h @@ -26,7 +26,7 @@ extern void nand_init(void); -#ifndef CFG_NAND_LEGACY +#ifndef CONFIG_NAND_LEGACY #include #include #include @@ -128,5 +128,5 @@ void board_nand_select_device(struct nand_chip *nand, int chip); __attribute__((noreturn)) void nand_boot(void); -#endif /* !CFG_NAND_LEGACY */ +#endif /* !CONFIG_NAND_LEGACY */ #endif diff --git a/lib_generic/crc32.c b/lib_generic/crc32.c index 83d1d1d3a0d..b6a7a91620f 100644 --- a/lib_generic/crc32.c +++ b/lib_generic/crc32.c @@ -174,7 +174,7 @@ uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *buf, uInt len) #if defined(CONFIG_CMD_JFFS2) || \ (defined(CONFIG_CMD_NAND) \ - && !defined(CFG_NAND_LEGACY)) + && !defined(CONFIG_NAND_LEGACY)) /* No ones complement version. JFFS2 (and other things ?) * don't use ones compliment in their CRC calculations. -- cgit v1.3.1 From 9483df6408c25f16060432de3868901e352e23bc Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Wed, 13 Aug 2008 01:40:43 +0200 Subject: drivers/mtd/nand_legacy: Move conditional compilation to Makefile Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/mtd/nand_legacy/Makefile | 5 ++++- drivers/mtd/nand_legacy/nand_legacy.c | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand_legacy/Makefile b/drivers/mtd/nand_legacy/Makefile index 4e29c36e704..a1a9cc92b59 100644 --- a/drivers/mtd/nand_legacy/Makefile +++ b/drivers/mtd/nand_legacy/Makefile @@ -25,8 +25,11 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnand_legacy.a -COBJS := nand_legacy.o +ifdef CONFIG_CMD_NAND +COBJS-$(CONFIG_NAND_LEGACY) := nand_legacy.o +endif +COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/mtd/nand_legacy/nand_legacy.c b/drivers/mtd/nand_legacy/nand_legacy.c index 8f7dc3901af..bf5565a8fbe 100644 --- a/drivers/mtd/nand_legacy/nand_legacy.c +++ b/drivers/mtd/nand_legacy/nand_legacy.c @@ -14,9 +14,6 @@ #include #include #include - -#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_LEGACY) - #include #include #include @@ -1608,5 +1605,3 @@ int read_jffs2_nand(size_t start, size_t len, start, len, retlen, buf); } #endif /* CONFIG_JFFS2_NAND */ - -#endif -- cgit v1.3.1