From e393bc090088f731299def1cf466d45707cd9a6d Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Wed, 2 Jul 2014 07:53:06 +0900 Subject: mtd: onenand: remove s5pc100 related onenand codes This patch removes s5pc100 related onenand codes because of no more support for S5PC100 SoC in mainline. Cc: Kyungmin Park Cc: David Woodhouse Cc: Brian Norris Signed-off-by: Kukjin Kim --- drivers/mtd/onenand/Kconfig | 4 ++-- drivers/mtd/onenand/samsung.c | 25 +------------------------ 2 files changed, 3 insertions(+), 26 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig index ab2607273e80..dcae2f6a2b11 100644 --- a/drivers/mtd/onenand/Kconfig +++ b/drivers/mtd/onenand/Kconfig @@ -32,10 +32,10 @@ config MTD_ONENAND_OMAP2 config MTD_ONENAND_SAMSUNG tristate "OneNAND on Samsung SOC controller support" - depends on ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4 + depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS4 help Support for a OneNAND flash device connected to an Samsung SOC. - S3C64XX/S5PC100 use command mapping method. + S3C64XX uses command mapping method. S5PC110/S5PC210 use generic OneNAND method. config MTD_ONENAND_OTP diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index efb819c3df2f..19cfb97adbc0 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -10,7 +10,7 @@ * published by the Free Software Foundation. * * Implementation: - * S3C64XX and S5PC100: emulate the pseudo BufferRAM + * S3C64XX: emulate the pseudo BufferRAM * S5PC110: use DMA */ @@ -32,7 +32,6 @@ enum soc_type { TYPE_S3C6400, TYPE_S3C6410, - TYPE_S5PC100, TYPE_S5PC110, }; @@ -59,7 +58,6 @@ enum soc_type { #define MAP_11 (0x3) #define S3C64XX_CMD_MAP_SHIFT 24 -#define S5PC100_CMD_MAP_SHIFT 26 #define S3C6400_FBA_SHIFT 10 #define S3C6400_FPA_SHIFT 4 @@ -69,10 +67,6 @@ enum soc_type { #define S3C6410_FPA_SHIFT 6 #define S3C6410_FSA_SHIFT 4 -#define S5PC100_FBA_SHIFT 13 -#define S5PC100_FPA_SHIFT 7 -#define S5PC100_FSA_SHIFT 5 - /* S5PC110 specific definitions */ #define S5PC110_DMA_SRC_ADDR 0x400 #define S5PC110_DMA_SRC_CFG 0x404 @@ -195,11 +189,6 @@ static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val) return (type << S3C64XX_CMD_MAP_SHIFT) | val; } -static unsigned int s5pc1xx_cmd_map(unsigned type, unsigned val) -{ - return (type << S5PC100_CMD_MAP_SHIFT) | val; -} - static unsigned int s3c6400_mem_addr(int fba, int fpa, int fsa) { return (fba << S3C6400_FBA_SHIFT) | (fpa << S3C6400_FPA_SHIFT) | @@ -212,12 +201,6 @@ static unsigned int s3c6410_mem_addr(int fba, int fpa, int fsa) (fsa << S3C6410_FSA_SHIFT); } -static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa) -{ - return (fba << S5PC100_FBA_SHIFT) | (fpa << S5PC100_FPA_SHIFT) | - (fsa << S5PC100_FSA_SHIFT); -} - static void s3c_onenand_reset(void) { unsigned long timeout = 0x10000; @@ -835,9 +818,6 @@ static void s3c_onenand_setup(struct mtd_info *mtd) } else if (onenand->type == TYPE_S3C6410) { onenand->mem_addr = s3c6410_mem_addr; onenand->cmd_map = s3c64xx_cmd_map; - } else if (onenand->type == TYPE_S5PC100) { - onenand->mem_addr = s5pc100_mem_addr; - onenand->cmd_map = s5pc1xx_cmd_map; } else if (onenand->type == TYPE_S5PC110) { /* Use generic onenand functions */ this->read_bufferram = s5pc110_read_bufferram; @@ -1110,9 +1090,6 @@ static struct platform_device_id s3c_onenand_driver_ids[] = { }, { .name = "s3c6410-onenand", .driver_data = TYPE_S3C6410, - }, { - .name = "s5pc100-onenand", - .driver_data = TYPE_S5PC100, }, { .name = "s5pc110-onenand", .driver_data = TYPE_S5PC110, -- cgit v1.2.3 From e8c235b065ec07cd1c63c0e0bfbfc718d438baba Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Tue, 8 Jul 2014 16:04:44 +0200 Subject: UBI: init_volumes: Ignore volumes with no LEBs UBI assumes that ubi_attach_info will only contain ubi_ainf_volume structures for volumes with at least one LEB. In scanning mode this is true because UBI can nicely create a ubi_ainf_volume on demand while creating the EBA table. For fastmap this is not true, the fastmap on-flash structure has a list of all volumes, the ubi_ainf_volume structures are created from this list. So it can happen that an empty volume ends up in init_volumes(). We can easely deal with that by looking into ->leb_count too. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/vtbl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index d77b1c1d7c72..07cac5f9ffb8 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -591,7 +591,7 @@ static int init_volumes(struct ubi_device *ubi, /* Static volumes only */ av = ubi_find_av(ai, i); - if (!av) { + if (!av || !av->leb_count) { /* * No eraseblocks belonging to this volume found. We * don't actually know whether this static volume is -- cgit v1.2.3 From 495f2bf6c4ed2da5dcadac96312f71da2a5af949 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 5 May 2014 07:11:52 -0300 Subject: UBI: block: Make ubiblock_resize return something Currently, ubiblock_resize() can fail if the device is not found in the list. This commit changes the return type, so the function can return something meaningful on error paths. Reported-by: kbuild test robot Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/block.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 8457df7ec5af..52cefae01887 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -498,7 +498,7 @@ int ubiblock_remove(struct ubi_volume_info *vi) return 0; } -static void ubiblock_resize(struct ubi_volume_info *vi) +static int ubiblock_resize(struct ubi_volume_info *vi) { struct ubiblock *dev; int disk_capacity; @@ -512,7 +512,7 @@ static void ubiblock_resize(struct ubi_volume_info *vi) dev = find_dev_nolock(vi->ubi_num, vi->vol_id); if (!dev) { mutex_unlock(&devices_mutex); - return; + return -ENODEV; } mutex_lock(&dev->dev_mutex); @@ -521,6 +521,7 @@ static void ubiblock_resize(struct ubi_volume_info *vi) ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size); mutex_unlock(&dev->dev_mutex); mutex_unlock(&devices_mutex); + return 0; } static int ubiblock_notify(struct notifier_block *nb, -- cgit v1.2.3 From 0a3d571bb8940a189322cc5f51466bdab044a48b Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 5 May 2014 07:11:53 -0300 Subject: UBI: block: Set disk_capacity out of the mutex There's no need to set the disk capacity with the mutex held, so this commit takes the variable setting out of the mutex. This simplifies the disk capacity fix for very large volumes in a follow up commit. Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/block.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 52cefae01887..043919ad35e4 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -378,7 +378,7 @@ int ubiblock_create(struct ubi_volume_info *vi) { struct ubiblock *dev; struct gendisk *gd; - int disk_capacity; + int disk_capacity = (vi->size * vi->usable_leb_size) >> 9; int ret; /* Check that the volume isn't already handled */ @@ -412,7 +412,6 @@ int ubiblock_create(struct ubi_volume_info *vi) gd->first_minor = dev->ubi_num * UBI_MAX_VOLUMES + dev->vol_id; gd->private_data = dev; sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); - disk_capacity = (vi->size * vi->usable_leb_size) >> 9; set_capacity(gd, disk_capacity); dev->gd = gd; @@ -501,7 +500,7 @@ int ubiblock_remove(struct ubi_volume_info *vi) static int ubiblock_resize(struct ubi_volume_info *vi) { struct ubiblock *dev; - int disk_capacity; + int disk_capacity = (vi->size * vi->usable_leb_size) >> 9; /* * Need to lock the device list until we stop using the device, @@ -516,7 +515,6 @@ static int ubiblock_resize(struct ubi_volume_info *vi) } mutex_lock(&dev->dev_mutex); - disk_capacity = (vi->size * vi->usable_leb_size) >> 9; set_capacity(dev->gd, disk_capacity); ubi_msg("%s resized to %d LEBs", dev->gd->disk_name, vi->size); mutex_unlock(&dev->dev_mutex); -- cgit v1.2.3 From 4df38926f337ff4de49a8fb512aa4a55df0c502d Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 5 May 2014 07:11:54 -0300 Subject: UBI: block: Avoid disk size integer overflow This patch fixes the issue that on very large UBI volumes UBI block does not work correctly. Signed-off-by: Richard Weinberger Signed-off-by: Ezequiel Garcia Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/block.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 043919ad35e4..33c64955d4d7 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -378,9 +378,11 @@ int ubiblock_create(struct ubi_volume_info *vi) { struct ubiblock *dev; struct gendisk *gd; - int disk_capacity = (vi->size * vi->usable_leb_size) >> 9; + u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; int ret; + if ((sector_t)disk_capacity != disk_capacity) + return -EFBIG; /* Check that the volume isn't already handled */ mutex_lock(&devices_mutex); if (find_dev_nolock(vi->ubi_num, vi->vol_id)) { @@ -500,8 +502,13 @@ int ubiblock_remove(struct ubi_volume_info *vi) static int ubiblock_resize(struct ubi_volume_info *vi) { struct ubiblock *dev; - int disk_capacity = (vi->size * vi->usable_leb_size) >> 9; + u64 disk_capacity = ((u64)vi->size * vi->usable_leb_size) >> 9; + if ((sector_t)disk_capacity != disk_capacity) { + ubi_warn("%s: the volume is too big, cannot resize (%d LEBs)", + dev->gd->disk_name, vi->size); + return -EFBIG; + } /* * Need to lock the device list until we stop using the device, * otherwise the device struct might get released in -- cgit v1.2.3 From 49e236bc4a2639af0e77b3a05460e8367e3187a4 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sun, 27 Jul 2014 09:35:48 +0200 Subject: UBI: bugfix in ubi_wl_flush() Use the _safe variant because we're iterating over a list where items get deleted and freed. Signed-off-by: Richard Weinberger Signed-off-by: Artem Bityutskiy --- drivers/mtd/ubi/wl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 0f3425dac910..20f491713145 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1718,12 +1718,12 @@ int ubi_wl_flush(struct ubi_device *ubi, int vol_id, int lnum) vol_id, lnum, ubi->works_count); while (found) { - struct ubi_work *wrk; + struct ubi_work *wrk, *tmp; found = 0; down_read(&ubi->work_sem); spin_lock(&ubi->wl_lock); - list_for_each_entry(wrk, &ubi->works, list) { + list_for_each_entry_safe(wrk, tmp, &ubi->works, list) { if ((vol_id == UBI_ALL || wrk->vol_id == vol_id) && (lnum == UBI_ALL || wrk->lnum == lnum)) { list_del(&wrk->list); -- cgit v1.2.3 From 9cf12167e909a86fbc4b39cf4cffef4cba40f1b3 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 23 Jul 2014 16:36:25 +0200 Subject: MIPS: Alchemy: add helpers to access static memory ctrl registers. This patch changes the static memory controller registers to offsets from base, prefixes them with AU1000_ to avoid silent failures due to changed addresses and introduces helpers to access them. No functional changes, comparing assembly of a few select functions shows no differences. Signed-off-by: Manuel Lauss Cc: Linux-MIPS Patchwork: https://patchwork.linux-mips.org/patch/7463/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/power.c | 48 ++++++++++++++-------------- arch/mips/alchemy/devboards/db1200.c | 2 +- arch/mips/alchemy/devboards/db1300.c | 2 +- arch/mips/alchemy/devboards/db1550.c | 4 +-- arch/mips/include/asm/mach-au1x00/au1000.h | 50 ++++++++++++++++++------------ drivers/mtd/nand/au1550nd.c | 8 ++--- 6 files changed, 62 insertions(+), 52 deletions(-) (limited to 'drivers/mtd') diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 2d3831b02091..921ed30b440c 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -64,18 +64,18 @@ static void save_core_regs(void) sleep_sys_pinfunc = alchemy_rdsys(AU1000_SYS_PINFUNC); /* Save the static memory controller configuration. */ - sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); - sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); - sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); - sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); - sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); - sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); - sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); - sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); - sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); - sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); - sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); - sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); + sleep_static_memctlr[0][0] = alchemy_rdsmem(AU1000_MEM_STCFG0); + sleep_static_memctlr[0][1] = alchemy_rdsmem(AU1000_MEM_STTIME0); + sleep_static_memctlr[0][2] = alchemy_rdsmem(AU1000_MEM_STADDR0); + sleep_static_memctlr[1][0] = alchemy_rdsmem(AU1000_MEM_STCFG1); + sleep_static_memctlr[1][1] = alchemy_rdsmem(AU1000_MEM_STTIME1); + sleep_static_memctlr[1][2] = alchemy_rdsmem(AU1000_MEM_STADDR1); + sleep_static_memctlr[2][0] = alchemy_rdsmem(AU1000_MEM_STCFG2); + sleep_static_memctlr[2][1] = alchemy_rdsmem(AU1000_MEM_STTIME2); + sleep_static_memctlr[2][2] = alchemy_rdsmem(AU1000_MEM_STADDR2); + sleep_static_memctlr[3][0] = alchemy_rdsmem(AU1000_MEM_STCFG3); + sleep_static_memctlr[3][1] = alchemy_rdsmem(AU1000_MEM_STTIME3); + sleep_static_memctlr[3][2] = alchemy_rdsmem(AU1000_MEM_STADDR3); } static void restore_core_regs(void) @@ -95,18 +95,18 @@ static void restore_core_regs(void) alchemy_wrsys(sleep_sys_pinfunc, AU1000_SYS_PINFUNC); /* Restore the static memory controller configuration. */ - au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); - au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); - au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); - au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); - au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); - au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); - au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); - au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); - au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); - au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); - au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); - au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); + alchemy_wrsmem(sleep_static_memctlr[0][0], AU1000_MEM_STCFG0); + alchemy_wrsmem(sleep_static_memctlr[0][1], AU1000_MEM_STTIME0); + alchemy_wrsmem(sleep_static_memctlr[0][2], AU1000_MEM_STADDR0); + alchemy_wrsmem(sleep_static_memctlr[1][0], AU1000_MEM_STCFG1); + alchemy_wrsmem(sleep_static_memctlr[1][1], AU1000_MEM_STTIME1); + alchemy_wrsmem(sleep_static_memctlr[1][2], AU1000_MEM_STADDR1); + alchemy_wrsmem(sleep_static_memctlr[2][0], AU1000_MEM_STCFG2); + alchemy_wrsmem(sleep_static_memctlr[2][1], AU1000_MEM_STTIME2); + alchemy_wrsmem(sleep_static_memctlr[2][2], AU1000_MEM_STADDR2); + alchemy_wrsmem(sleep_static_memctlr[3][0], AU1000_MEM_STCFG3); + alchemy_wrsmem(sleep_static_memctlr[3][1], AU1000_MEM_STTIME3); + alchemy_wrsmem(sleep_static_memctlr[3][2], AU1000_MEM_STADDR3); } void au_sleep(void) diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 408c36f37699..5ccfd8393cd5 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c @@ -246,7 +246,7 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int au1200_nand_device_ready(struct mtd_info *mtd) { - return __raw_readl((void __iomem *)MEM_STSTAT) & 1; + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; } static struct mtd_partition db1200_nand_parts[] = { diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index 1aed6be4de10..c80e5b94064e 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -169,7 +169,7 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int au1300_nand_device_ready(struct mtd_info *mtd) { - return __raw_readl((void __iomem *)MEM_STSTAT) & 1; + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; } static struct mtd_partition db1300_nand_parts[] = { diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 392fb89270d6..d1320665e7e3 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c @@ -151,7 +151,7 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, static int au1550_nand_device_ready(struct mtd_info *mtd) { - return __raw_readl((void __iomem *)MEM_STSTAT) & 1; + return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; } static struct mtd_partition db1550_nand_parts[] = { @@ -217,7 +217,7 @@ static struct platform_device pb1550_nand_dev = { static void __init pb1550_nand_setup(void) { - int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | + int boot_swapboot = (alchemy_rdsmem(AU1000_MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); gpio_direction_input(206); /* de-assert NAND CS# */ diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index c8cfca9c3167..d664b11e0baf 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h @@ -309,25 +309,21 @@ #define AU1550_MEM_SDSREF 0x08D0 #define AU1550_MEM_SDSLEEP MEM_SDSREF -/* Static Bus Controller */ -#define MEM_STCFG0 0xB4001000 -#define MEM_STTIME0 0xB4001004 -#define MEM_STADDR0 0xB4001008 - -#define MEM_STCFG1 0xB4001010 -#define MEM_STTIME1 0xB4001014 -#define MEM_STADDR1 0xB4001018 - -#define MEM_STCFG2 0xB4001020 -#define MEM_STTIME2 0xB4001024 -#define MEM_STADDR2 0xB4001028 - -#define MEM_STCFG3 0xB4001030 -#define MEM_STTIME3 0xB4001034 -#define MEM_STADDR3 0xB4001038 - -#define MEM_STNDCTL 0xB4001100 -#define MEM_STSTAT 0xB4001104 +/* Static Bus Controller register offsets */ +#define AU1000_MEM_STCFG0 0x000 +#define AU1000_MEM_STTIME0 0x004 +#define AU1000_MEM_STADDR0 0x008 +#define AU1000_MEM_STCFG1 0x010 +#define AU1000_MEM_STTIME1 0x014 +#define AU1000_MEM_STADDR1 0x018 +#define AU1000_MEM_STCFG2 0x020 +#define AU1000_MEM_STTIME2 0x024 +#define AU1000_MEM_STADDR2 0x028 +#define AU1000_MEM_STCFG3 0x030 +#define AU1000_MEM_STTIME3 0x034 +#define AU1000_MEM_STADDR3 0x038 +#define AU1000_MEM_STNDCTL 0x100 +#define AU1000_MEM_STSTAT 0x104 #define MEM_STNAND_CMD 0x0 #define MEM_STNAND_ADDR 0x4 @@ -713,6 +709,22 @@ static inline void alchemy_wrsys(unsigned long v, int regofs) wmb(); /* drain writebuffer */ } +/* helpers to access static memctrl registers */ +static inline unsigned long alchemy_rdsmem(int regofs) +{ + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); + + return __raw_readl(b + regofs); +} + +static inline void alchemy_wrsmem(unsigned long v, int regofs) +{ + void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); + + __raw_writel(v, b + regofs); + wmb(); /* drain writebuffer */ +} + /* Early Au1000 have a write-only SYS_CPUPLL register. */ static inline int au1xxx_cpu_has_pll_wo(void) { diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index bc5c518828d2..6cece6e7ee6b 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -223,12 +223,12 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) case NAND_CTL_SETNCE: /* assert (force assert) chip enable */ - au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL); + alchemy_wrsmem((1 << (4 + ctx->cs)), AU1000_MEM_STNDCTL); break; case NAND_CTL_CLRNCE: /* deassert chip enable */ - au_writel(0, MEM_STNDCTL); + alchemy_wrsmem(0, AU1000_MEM_STNDCTL); break; } @@ -240,9 +240,7 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) int au1550_device_ready(struct mtd_info *mtd) { - int ret = (au_readl(MEM_STSTAT) & 0x1) ? 1 : 0; - au_sync(); - return ret; + return (alchemy_rdsmem(AU1000_MEM_STSTAT) & 0x1) ? 1 : 0; } /** -- cgit v1.2.3 From 2f73bfbe0873452f4cd388ec2f67f8226fe93f79 Mon Sep 17 00:00:00 2001 From: Manuel Lauss Date: Wed, 23 Jul 2014 16:36:26 +0200 Subject: MIPS: Alchemy: remove au_read/write/sync replace au_read/write/sync with __raw_read/write and wmb. Signed-off-by: Manuel Lauss Cc: Linux-MIPS Patchwork: https://patchwork.linux-mips.org/patch/7465/ Signed-off-by: Ralf Baechle --- arch/mips/alchemy/common/dbdma.c | 22 ++-- arch/mips/alchemy/common/dma.c | 15 +-- arch/mips/include/asm/mach-au1x00/au1000.h | 48 ------- arch/mips/include/asm/mach-au1x00/au1000_dma.h | 50 ++++---- drivers/mmc/host/au1xmmc.c | 167 +++++++++++++------------ drivers/mtd/nand/au1550nd.c | 21 ++-- drivers/net/ethernet/amd/au1000_eth.c | 31 +++-- drivers/spi/spi-au1550.c | 66 +++++----- drivers/video/fbdev/au1100fb.c | 4 +- drivers/video/fbdev/au1200fb.c | 31 +++-- sound/soc/au1x/psc-ac97.c | 140 ++++++++++----------- sound/soc/au1x/psc-i2s.c | 100 +++++++-------- sound/soc/au1x/psc.h | 22 ++-- 13 files changed, 340 insertions(+), 377 deletions(-) (limited to 'drivers/mtd') diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 19d5642c16d9..745695db5ba0 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -341,7 +341,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, (dtp->dev_flags & DEV_FLAGS_SYNC)) i |= DDMA_CFG_SYNC; cp->ddma_cfg = i; - au_sync(); + wmb(); /* drain writebuffer */ /* * Return a non-zero value that can be used to find the channel @@ -631,7 +631,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) */ dma_cache_wback_inv((unsigned long)buf, nbytes); dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ - au_sync(); + wmb(); /* drain writebuffer */ dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); ctp->chan_ptr->ddma_dbell = 0; @@ -693,7 +693,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) */ dma_cache_inv((unsigned long)buf, nbytes); dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ - au_sync(); + wmb(); /* drain writebuffer */ dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); ctp->chan_ptr->ddma_dbell = 0; @@ -760,7 +760,7 @@ void au1xxx_dbdma_stop(u32 chanid) cp = ctp->chan_ptr; cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */ - au_sync(); + wmb(); /* drain writebuffer */ while (!(cp->ddma_stat & DDMA_STAT_H)) { udelay(1); halt_timeout++; @@ -771,7 +771,7 @@ void au1xxx_dbdma_stop(u32 chanid) } /* clear current desc valid and doorbell */ cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); - au_sync(); + wmb(); /* drain writebuffer */ } EXPORT_SYMBOL(au1xxx_dbdma_stop); @@ -789,9 +789,9 @@ void au1xxx_dbdma_start(u32 chanid) cp = ctp->chan_ptr; cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ - au_sync(); + wmb(); /* drain writebuffer */ cp->ddma_dbell = 0; - au_sync(); + wmb(); /* drain writebuffer */ } EXPORT_SYMBOL(au1xxx_dbdma_start); @@ -832,7 +832,7 @@ u32 au1xxx_get_dma_residue(u32 chanid) /* This is only valid if the channel is stopped. */ rv = cp->ddma_bytecnt; - au_sync(); + wmb(); /* drain writebuffer */ return rv; } @@ -868,7 +868,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) au1x_dma_chan_t *cp; intstat = dbdma_gptr->ddma_intstat; - au_sync(); + wmb(); /* drain writebuffer */ chan_index = __ffs(intstat); ctp = chan_tab_ptr[chan_index]; @@ -877,7 +877,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) /* Reset interrupt. */ cp->ddma_irq = 0; - au_sync(); + wmb(); /* drain writebuffer */ if (ctp->chan_callback) ctp->chan_callback(irq, ctp->chan_callparam); @@ -1061,7 +1061,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) dbdma_gptr->ddma_config = 0; dbdma_gptr->ddma_throttle = 0; dbdma_gptr->ddma_inten = 0xffff; - au_sync(); + wmb(); /* drain writebuffer */ ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); if (ret) diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index 9b624e2c0fcf..4fb6207b883b 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c @@ -141,17 +141,17 @@ void dump_au1000_dma_channel(unsigned int dmanr) printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr); printk(KERN_INFO " mode = 0x%08x\n", - au_readl(chan->io + DMA_MODE_SET)); + __raw_readl(chan->io + DMA_MODE_SET)); printk(KERN_INFO " addr = 0x%08x\n", - au_readl(chan->io + DMA_PERIPHERAL_ADDR)); + __raw_readl(chan->io + DMA_PERIPHERAL_ADDR)); printk(KERN_INFO " start0 = 0x%08x\n", - au_readl(chan->io + DMA_BUFFER0_START)); + __raw_readl(chan->io + DMA_BUFFER0_START)); printk(KERN_INFO " start1 = 0x%08x\n", - au_readl(chan->io + DMA_BUFFER1_START)); + __raw_readl(chan->io + DMA_BUFFER1_START)); printk(KERN_INFO " count0 = 0x%08x\n", - au_readl(chan->io + DMA_BUFFER0_COUNT)); + __raw_readl(chan->io + DMA_BUFFER0_COUNT)); printk(KERN_INFO " count1 = 0x%08x\n", - au_readl(chan->io + DMA_BUFFER1_COUNT)); + __raw_readl(chan->io + DMA_BUFFER1_COUNT)); } /* @@ -204,7 +204,8 @@ int request_au1000_dma(int dev_id, const char *dev_str, } /* fill it in */ - chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN; + chan->io = (void __iomem *)(KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + + i * DMA_CHANNEL_LEN); chan->dev_id = dev_id; chan->dev_str = dev_str; chan->fifo_addr = dev->fifo_addr; diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index d664b11e0baf..754207071b58 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h @@ -645,54 +645,6 @@ #include -/* cpu pipeline flush */ -void static inline au_sync(void) -{ - __asm__ volatile ("sync"); -} - -void static inline au_sync_udelay(int us) -{ - __asm__ volatile ("sync"); - udelay(us); -} - -void static inline au_sync_delay(int ms) -{ - __asm__ volatile ("sync"); - mdelay(ms); -} - -void static inline au_writeb(u8 val, unsigned long reg) -{ - *(volatile u8 *)reg = val; -} - -void static inline au_writew(u16 val, unsigned long reg) -{ - *(volatile u16 *)reg = val; -} - -void static inline au_writel(u32 val, unsigned long reg) -{ - *(volatile u32 *)reg = val; -} - -static inline u8 au_readb(unsigned long reg) -{ - return *(volatile u8 *)reg; -} - -static inline u16 au_readw(unsigned long reg) -{ - return *(volatile u16 *)reg; -} - -static inline u32 au_readl(unsigned long reg) -{ - return *(volatile u32 *)reg; -} - /* helpers to access the SYS_* registers */ static inline unsigned long alchemy_rdsys(int regofs) { diff --git a/arch/mips/include/asm/mach-au1x00/au1000_dma.h b/arch/mips/include/asm/mach-au1x00/au1000_dma.h index 7cedca5a305c..0a0cd4270c6f 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000_dma.h +++ b/arch/mips/include/asm/mach-au1x00/au1000_dma.h @@ -106,7 +106,7 @@ enum { struct dma_chan { int dev_id; /* this channel is allocated if >= 0, */ /* free otherwise */ - unsigned int io; + void __iomem *io; const char *dev_str; int irq; void *irq_dev; @@ -157,7 +157,7 @@ static inline void enable_dma_buffer0(unsigned int dmanr) if (!chan) return; - au_writel(DMA_BE0, chan->io + DMA_MODE_SET); + __raw_writel(DMA_BE0, chan->io + DMA_MODE_SET); } static inline void enable_dma_buffer1(unsigned int dmanr) @@ -166,7 +166,7 @@ static inline void enable_dma_buffer1(unsigned int dmanr) if (!chan) return; - au_writel(DMA_BE1, chan->io + DMA_MODE_SET); + __raw_writel(DMA_BE1, chan->io + DMA_MODE_SET); } static inline void enable_dma_buffers(unsigned int dmanr) { @@ -174,7 +174,7 @@ static inline void enable_dma_buffers(unsigned int dmanr) if (!chan) return; - au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); + __raw_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); } static inline void start_dma(unsigned int dmanr) @@ -183,7 +183,7 @@ static inline void start_dma(unsigned int dmanr) if (!chan) return; - au_writel(DMA_GO, chan->io + DMA_MODE_SET); + __raw_writel(DMA_GO, chan->io + DMA_MODE_SET); } #define DMA_HALT_POLL 0x5000 @@ -195,11 +195,11 @@ static inline void halt_dma(unsigned int dmanr) if (!chan) return; - au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); + __raw_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); /* Poll the halt bit */ for (i = 0; i < DMA_HALT_POLL; i++) - if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) + if (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) break; if (i == DMA_HALT_POLL) printk(KERN_INFO "halt_dma: HALT poll expired!\n"); @@ -215,7 +215,7 @@ static inline void disable_dma(unsigned int dmanr) halt_dma(dmanr); /* Now we can disable the buffers */ - au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); + __raw_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); } static inline int dma_halted(unsigned int dmanr) @@ -224,7 +224,7 @@ static inline int dma_halted(unsigned int dmanr) if (!chan) return 1; - return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; + return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; } /* Initialize a DMA channel. */ @@ -239,14 +239,14 @@ static inline void init_dma(unsigned int dmanr) disable_dma(dmanr); /* Set device FIFO address */ - au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); + __raw_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); mode = chan->mode | (chan->dev_id << DMA_DID_BIT); if (chan->irq) mode |= DMA_IE; - au_writel(~mode, chan->io + DMA_MODE_CLEAR); - au_writel(mode, chan->io + DMA_MODE_SET); + __raw_writel(~mode, chan->io + DMA_MODE_CLEAR); + __raw_writel(mode, chan->io + DMA_MODE_SET); } /* @@ -283,7 +283,7 @@ static inline int get_dma_active_buffer(unsigned int dmanr) if (!chan) return -1; - return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; + return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; } /* @@ -304,7 +304,7 @@ static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a) if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) return; - au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); + __raw_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); } /* @@ -316,7 +316,7 @@ static inline void clear_dma_done0(unsigned int dmanr) if (!chan) return; - au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); + __raw_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); } static inline void clear_dma_done1(unsigned int dmanr) @@ -325,7 +325,7 @@ static inline void clear_dma_done1(unsigned int dmanr) if (!chan) return; - au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); + __raw_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); } /* @@ -344,7 +344,7 @@ static inline void set_dma_addr0(unsigned int dmanr, unsigned int a) if (!chan) return; - au_writel(a, chan->io + DMA_BUFFER0_START); + __raw_writel(a, chan->io + DMA_BUFFER0_START); } /* @@ -356,7 +356,7 @@ static inline void set_dma_addr1(unsigned int dmanr, unsigned int a) if (!chan) return; - au_writel(a, chan->io + DMA_BUFFER1_START); + __raw_writel(a, chan->io + DMA_BUFFER1_START); } @@ -370,7 +370,7 @@ static inline void set_dma_count0(unsigned int dmanr, unsigned int count) if (!chan) return; count &= DMA_COUNT_MASK; - au_writel(count, chan->io + DMA_BUFFER0_COUNT); + __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); } /* @@ -383,7 +383,7 @@ static inline void set_dma_count1(unsigned int dmanr, unsigned int count) if (!chan) return; count &= DMA_COUNT_MASK; - au_writel(count, chan->io + DMA_BUFFER1_COUNT); + __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); } /* @@ -396,8 +396,8 @@ static inline void set_dma_count(unsigned int dmanr, unsigned int count) if (!chan) return; count &= DMA_COUNT_MASK; - au_writel(count, chan->io + DMA_BUFFER0_COUNT); - au_writel(count, chan->io + DMA_BUFFER1_COUNT); + __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); + __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); } /* @@ -410,7 +410,7 @@ static inline unsigned int get_dma_buffer_done(unsigned int dmanr) if (!chan) return 0; - return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); + return __raw_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); } @@ -437,10 +437,10 @@ static inline int get_dma_residue(unsigned int dmanr) if (!chan) return 0; - curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? + curBufCntReg = (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; - count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; + count = __raw_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; if ((chan->mode & DMA_DW_MASK) == DMA_DW16) count <<= 1; diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 0ea43c09803c..2988e9df85e3 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -90,7 +90,7 @@ struct au1xmmc_host { struct mmc_request *mrq; u32 flags; - u32 iobase; + void __iomem *iobase; u32 clock; u32 bus_width; u32 power_mode; @@ -162,32 +162,33 @@ static inline int has_dbdma(void) static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) { - u32 val = au_readl(HOST_CONFIG(host)); + u32 val = __raw_readl(HOST_CONFIG(host)); val |= mask; - au_writel(val, HOST_CONFIG(host)); - au_sync(); + __raw_writel(val, HOST_CONFIG(host)); + wmb(); /* drain writebuffer */ } static inline void FLUSH_FIFO(struct au1xmmc_host *host) { - u32 val = au_readl(HOST_CONFIG2(host)); + u32 val = __raw_readl(HOST_CONFIG2(host)); - au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); - au_sync_delay(1); + __raw_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ + mdelay(1); /* SEND_STOP will turn off clock control - this re-enables it */ val &= ~SD_CONFIG2_DF; - au_writel(val, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(val, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ } static inline void IRQ_OFF(struct au1xmmc_host *host, u32 mask) { - u32 val = au_readl(HOST_CONFIG(host)); + u32 val = __raw_readl(HOST_CONFIG(host)); val &= ~mask; - au_writel(val, HOST_CONFIG(host)); - au_sync(); + __raw_writel(val, HOST_CONFIG(host)); + wmb(); /* drain writebuffer */ } static inline void SEND_STOP(struct au1xmmc_host *host) @@ -197,12 +198,13 @@ static inline void SEND_STOP(struct au1xmmc_host *host) WARN_ON(host->status != HOST_S_DATA); host->status = HOST_S_STOP; - config2 = au_readl(HOST_CONFIG2(host)); - au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); - au_sync(); + config2 = __raw_readl(HOST_CONFIG2(host)); + __raw_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ /* Send the stop command */ - au_writel(STOP_CMD, HOST_CMD(host)); + __raw_writel(STOP_CMD, HOST_CMD(host)); + wmb(); /* drain writebuffer */ } static void au1xmmc_set_power(struct au1xmmc_host *host, int state) @@ -296,28 +298,28 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, } } - au_writel(cmd->arg, HOST_CMDARG(host)); - au_sync(); + __raw_writel(cmd->arg, HOST_CMDARG(host)); + wmb(); /* drain writebuffer */ if (wait) IRQ_OFF(host, SD_CONFIG_CR); - au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); - au_sync(); + __raw_writel((mmccmd | SD_CMD_GO), HOST_CMD(host)); + wmb(); /* drain writebuffer */ /* Wait for the command to go on the line */ - while (au_readl(HOST_CMD(host)) & SD_CMD_GO) + while (__raw_readl(HOST_CMD(host)) & SD_CMD_GO) /* nop */; /* Wait for the command to come back */ if (wait) { - u32 status = au_readl(HOST_STATUS(host)); + u32 status = __raw_readl(HOST_STATUS(host)); while (!(status & SD_STATUS_CR)) - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); /* Clear the CR status */ - au_writel(SD_STATUS_CR, HOST_STATUS(host)); + __raw_writel(SD_STATUS_CR, HOST_STATUS(host)); IRQ_ON(host, SD_CONFIG_CR); } @@ -339,11 +341,11 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) data = mrq->cmd->data; if (status == 0) - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); /* The transaction is really over when the SD_STATUS_DB bit is clear */ while ((host->flags & HOST_F_XMIT) && (status & SD_STATUS_DB)) - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); data->error = 0; dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma.dir); @@ -357,7 +359,7 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status) data->error = -EILSEQ; /* Clear the CRC bits */ - au_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); + __raw_writel(SD_STATUS_WC | SD_STATUS_RC, HOST_STATUS(host)); data->bytes_xfered = 0; @@ -380,7 +382,7 @@ static void au1xmmc_tasklet_data(unsigned long param) { struct au1xmmc_host *host = (struct au1xmmc_host *)param; - u32 status = au_readl(HOST_STATUS(host)); + u32 status = __raw_readl(HOST_STATUS(host)); au1xmmc_data_complete(host, status); } @@ -412,15 +414,15 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host) max = AU1XMMC_MAX_TRANSFER; for (count = 0; count < max; count++) { - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_TH)) break; val = *sg_ptr++; - au_writel((unsigned long)val, HOST_TXPORT(host)); - au_sync(); + __raw_writel((unsigned long)val, HOST_TXPORT(host)); + wmb(); /* drain writebuffer */ } host->pio.len -= count; @@ -472,7 +474,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) max = AU1XMMC_MAX_TRANSFER; for (count = 0; count < max; count++) { - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_NE)) break; @@ -494,7 +496,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host) break; } - val = au_readl(HOST_RXPORT(host)); + val = __raw_readl(HOST_RXPORT(host)); if (sg_ptr) *sg_ptr++ = (unsigned char)(val & 0xFF); @@ -537,10 +539,10 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) if (cmd->flags & MMC_RSP_PRESENT) { if (cmd->flags & MMC_RSP_136) { - r[0] = au_readl(host->iobase + SD_RESP3); - r[1] = au_readl(host->iobase + SD_RESP2); - r[2] = au_readl(host->iobase + SD_RESP1); - r[3] = au_readl(host->iobase + SD_RESP0); + r[0] = __raw_readl(host->iobase + SD_RESP3); + r[1] = __raw_readl(host->iobase + SD_RESP2); + r[2] = __raw_readl(host->iobase + SD_RESP1); + r[3] = __raw_readl(host->iobase + SD_RESP0); /* The CRC is omitted from the response, so really * we only got 120 bytes, but the engine expects @@ -559,7 +561,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) * that means that the OSR data starts at bit 31, * so we can just read RESP0 and return that. */ - cmd->resp[0] = au_readl(host->iobase + SD_RESP0); + cmd->resp[0] = __raw_readl(host->iobase + SD_RESP0); } } @@ -586,7 +588,7 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) u32 mask = SD_STATUS_DB | SD_STATUS_NE; while((status & mask) != mask) - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); } au1xxx_dbdma_start(channel); @@ -606,13 +608,13 @@ static void au1xmmc_set_clock(struct au1xmmc_host *host, int rate) pbus /= 2; divisor = ((pbus / rate) / 2) - 1; - config = au_readl(HOST_CONFIG(host)); + config = __raw_readl(HOST_CONFIG(host)); config &= ~(SD_CONFIG_DIV); config |= (divisor & SD_CONFIG_DIV) | SD_CONFIG_DE; - au_writel(config, HOST_CONFIG(host)); - au_sync(); + __raw_writel(config, HOST_CONFIG(host)); + wmb(); /* drain writebuffer */ } static int au1xmmc_prepare_data(struct au1xmmc_host *host, @@ -636,7 +638,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host, if (host->dma.len == 0) return -ETIMEDOUT; - au_writel(data->blksz - 1, HOST_BLKSIZE(host)); + __raw_writel(data->blksz - 1, HOST_BLKSIZE(host)); if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) { int i; @@ -723,31 +725,34 @@ static void au1xmmc_request(struct mmc_host* mmc, struct mmc_request* mrq) static void au1xmmc_reset_controller(struct au1xmmc_host *host) { /* Apply the clock */ - au_writel(SD_ENABLE_CE, HOST_ENABLE(host)); - au_sync_delay(1); + __raw_writel(SD_ENABLE_CE, HOST_ENABLE(host)); + wmb(); /* drain writebuffer */ + mdelay(1); - au_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); - au_sync_delay(5); + __raw_writel(SD_ENABLE_R | SD_ENABLE_CE, HOST_ENABLE(host)); + wmb(); /* drain writebuffer */ + mdelay(5); - au_writel(~0, HOST_STATUS(host)); - au_sync(); + __raw_writel(~0, HOST_STATUS(host)); + wmb(); /* drain writebuffer */ - au_writel(0, HOST_BLKSIZE(host)); - au_writel(0x001fffff, HOST_TIMEOUT(host)); - au_sync(); + __raw_writel(0, HOST_BLKSIZE(host)); + __raw_writel(0x001fffff, HOST_TIMEOUT(host)); + wmb(); /* drain writebuffer */ - au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ - au_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); - au_sync_delay(1); + __raw_writel(SD_CONFIG2_EN | SD_CONFIG2_FF, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ + mdelay(1); - au_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(SD_CONFIG2_EN, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ /* Configure interrupts */ - au_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); - au_sync(); + __raw_writel(AU1XMMC_INTERRUPTS, HOST_CONFIG(host)); + wmb(); /* drain writebuffer */ } @@ -767,7 +772,7 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) host->clock = ios->clock; } - config2 = au_readl(HOST_CONFIG2(host)); + config2 = __raw_readl(HOST_CONFIG2(host)); switch (ios->bus_width) { case MMC_BUS_WIDTH_8: config2 |= SD_CONFIG2_BB; @@ -780,8 +785,8 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB); break; } - au_writel(config2, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(config2, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ } #define STATUS_TIMEOUT (SD_STATUS_RAT | SD_STATUS_DT) @@ -793,7 +798,7 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) struct au1xmmc_host *host = dev_id; u32 status; - status = au_readl(HOST_STATUS(host)); + status = __raw_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_I)) return IRQ_NONE; /* not ours */ @@ -839,8 +844,8 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id) status); } - au_writel(status, HOST_STATUS(host)); - au_sync(); + __raw_writel(status, HOST_STATUS(host)); + wmb(); /* drain writebuffer */ return IRQ_HANDLED; } @@ -976,7 +981,7 @@ static int au1xmmc_probe(struct platform_device *pdev) goto out1; } - host->iobase = (unsigned long)ioremap(r->start, 0x3c); + host->iobase = ioremap(r->start, 0x3c); if (!host->iobase) { dev_err(&pdev->dev, "cannot remap mmio\n"); goto out2; @@ -1075,7 +1080,7 @@ static int au1xmmc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); - pr_info(DRIVER_NAME ": MMC Controller %d set up at %8.8X" + pr_info(DRIVER_NAME ": MMC Controller %d set up at %p" " (mode=%s)\n", pdev->id, host->iobase, host->flags & HOST_F_DMA ? "dma" : "pio"); @@ -1087,10 +1092,10 @@ out6: led_classdev_unregister(host->platdata->led); out5: #endif - au_writel(0, HOST_ENABLE(host)); - au_writel(0, HOST_CONFIG(host)); - au_writel(0, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(0, HOST_ENABLE(host)); + __raw_writel(0, HOST_CONFIG(host)); + __raw_writel(0, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ if (host->flags & HOST_F_DBDMA) au1xmmc_dbdma_shutdown(host); @@ -1130,10 +1135,10 @@ static int au1xmmc_remove(struct platform_device *pdev) !(host->mmc->caps & MMC_CAP_NEEDS_POLL)) host->platdata->cd_setup(host->mmc, 0); - au_writel(0, HOST_ENABLE(host)); - au_writel(0, HOST_CONFIG(host)); - au_writel(0, HOST_CONFIG2(host)); - au_sync(); + __raw_writel(0, HOST_ENABLE(host)); + __raw_writel(0, HOST_CONFIG(host)); + __raw_writel(0, HOST_CONFIG2(host)); + wmb(); /* drain writebuffer */ tasklet_kill(&host->data_task); tasklet_kill(&host->finish_task); @@ -1158,11 +1163,11 @@ static int au1xmmc_suspend(struct platform_device *pdev, pm_message_t state) { struct au1xmmc_host *host = platform_get_drvdata(pdev); - au_writel(0, HOST_CONFIG2(host)); - au_writel(0, HOST_CONFIG(host)); - au_writel(0xffffffff, HOST_STATUS(host)); - au_writel(0, HOST_ENABLE(host)); - au_sync(); + __raw_writel(0, HOST_CONFIG2(host)); + __raw_writel(0, HOST_CONFIG(host)); + __raw_writel(0xffffffff, HOST_STATUS(host)); + __raw_writel(0, HOST_ENABLE(host)); + wmb(); /* drain writebuffer */ return 0; } diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 6cece6e7ee6b..77d6c17b38c2 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c @@ -41,7 +41,7 @@ static u_char au_read_byte(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; u_char ret = readb(this->IO_ADDR_R); - au_sync(); + wmb(); /* drain writebuffer */ return ret; } @@ -56,7 +56,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) { struct nand_chip *this = mtd->priv; writeb(byte, this->IO_ADDR_W); - au_sync(); + wmb(); /* drain writebuffer */ } /** @@ -69,7 +69,7 @@ static u_char au_read_byte16(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); - au_sync(); + wmb(); /* drain writebuffer */ return ret; } @@ -84,7 +84,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) { struct nand_chip *this = mtd->priv; writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); - au_sync(); + wmb(); /* drain writebuffer */ } /** @@ -97,7 +97,7 @@ static u16 au_read_word(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; u16 ret = readw(this->IO_ADDR_R); - au_sync(); + wmb(); /* drain writebuffer */ return ret; } @@ -116,7 +116,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) for (i = 0; i < len; i++) { writeb(buf[i], this->IO_ADDR_W); - au_sync(); + wmb(); /* drain writebuffer */ } } @@ -135,7 +135,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) for (i = 0; i < len; i++) { buf[i] = readb(this->IO_ADDR_R); - au_sync(); + wmb(); /* drain writebuffer */ } } @@ -156,7 +156,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) for (i = 0; i < len; i++) { writew(p[i], this->IO_ADDR_W); - au_sync(); + wmb(); /* drain writebuffer */ } } @@ -178,7 +178,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) for (i = 0; i < len; i++) { p[i] = readw(this->IO_ADDR_R); - au_sync(); + wmb(); /* drain writebuffer */ } } @@ -234,8 +234,7 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) this->IO_ADDR_R = this->IO_ADDR_W; - /* Drain the writebuffer */ - au_sync(); + wmb(); /* Drain the writebuffer */ } int au1550_device_ready(struct mtd_info *mtd) diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index ad8b058c8068..31c48a7ac2b6 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -270,10 +270,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) if (force_reset || (!aup->mac_enabled)) { writel(MAC_EN_CLOCK_ENABLE, aup->enable); - au_sync_delay(2); + wmb(); /* drain writebuffer */ + mdelay(2); writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE), aup->enable); - au_sync_delay(2); + wmb(); /* drain writebuffer */ + mdelay(2); aup->mac_enabled = 1; } @@ -391,7 +393,8 @@ static void au1000_hard_stop(struct net_device *dev) reg = readl(&aup->mac->control); reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); writel(reg, &aup->mac->control); - au_sync_delay(10); + wmb(); /* drain writebuffer */ + mdelay(10); } static void au1000_enable_rx_tx(struct net_device *dev) @@ -404,7 +407,8 @@ static void au1000_enable_rx_tx(struct net_device *dev) reg = readl(&aup->mac->control); reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); writel(reg, &aup->mac->control); - au_sync_delay(10); + wmb(); /* drain writebuffer */ + mdelay(10); } static void @@ -454,7 +458,8 @@ au1000_adjust_link(struct net_device *dev) reg |= MAC_DISABLE_RX_OWN; } writel(reg, &aup->mac->control); - au_sync_delay(1); + wmb(); /* drain writebuffer */ + mdelay(1); au1000_enable_rx_tx(dev); aup->old_duplex = phydev->duplex; @@ -618,9 +623,11 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) au1000_hard_stop(dev); writel(MAC_EN_CLOCK_ENABLE, aup->enable); - au_sync_delay(2); + wmb(); /* drain writebuffer */ + mdelay(2); writel(0, aup->enable); - au_sync_delay(2); + wmb(); /* drain writebuffer */ + mdelay(2); aup->tx_full = 0; for (i = 0; i < NUM_RX_DMA; i++) { @@ -770,7 +777,7 @@ static int au1000_init(struct net_device *dev) for (i = 0; i < NUM_RX_DMA; i++) aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ control = MAC_RX_ENABLE | MAC_TX_ENABLE; #ifndef CONFIG_CPU_LITTLE_ENDIAN @@ -787,7 +794,7 @@ static int au1000_init(struct net_device *dev) writel(control, &aup->mac->control); writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ - au_sync(); + wmb(); /* drain writebuffer */ spin_unlock_irqrestore(&aup->lock, flags); return 0; @@ -878,7 +885,7 @@ static int au1000_rx(struct net_device *dev) } prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1); - au_sync(); + wmb(); /* drain writebuffer */ /* next descriptor */ prxd = aup->rx_dma_ring[aup->rx_head]; @@ -926,7 +933,7 @@ static void au1000_tx_ack(struct net_device *dev) au1000_update_tx_stats(dev, ptxd->status); ptxd->buff_stat &= ~TX_T_DONE; ptxd->len = 0; - au_sync(); + wmb(); /* drain writebuffer */ aup->tx_tail = (aup->tx_tail + 1) & (NUM_TX_DMA - 1); ptxd = aup->tx_dma_ring[aup->tx_tail]; @@ -1057,7 +1064,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) ps->tx_bytes += ptxd->len; ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ dev_kfree_skb(skb); aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1); return NETDEV_TX_OK; diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index 67375a11d4bd..ffb42f12d5a1 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c @@ -141,13 +141,13 @@ static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_spievent = PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; - au_sync(); + wmb(); /* drain writebuffer */ } static void au1550_spi_reset_fifos(struct au1550_spi *hw) @@ -155,10 +155,10 @@ static void au1550_spi_reset_fifos(struct au1550_spi *hw) u32 pcr; hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; - au_sync(); + wmb(); /* drain writebuffer */ do { pcr = hw->regs->psc_spipcr; - au_sync(); + wmb(); /* drain writebuffer */ } while (pcr != 0); } @@ -188,9 +188,9 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) au1550_spi_bits_handlers_set(hw, spi->bits_per_word); cfg = hw->regs->psc_spicfg; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ if (spi->mode & SPI_CPOL) cfg |= PSC_SPICFG_BI; @@ -218,10 +218,10 @@ static void au1550_spi_chipsel(struct spi_device *spi, int value) cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ do { stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ } while ((stat & PSC_SPISTAT_DR) == 0); if (hw->pdata->activate_cs) @@ -252,9 +252,9 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) au1550_spi_bits_handlers_set(hw, spi->bits_per_word); cfg = hw->regs->psc_spicfg; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ if (hw->usedma && bpw <= 8) cfg &= ~PSC_SPICFG_DD_DISABLE; @@ -268,12 +268,12 @@ static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) cfg |= au1550_spi_baudcfg(hw, hz); hw->regs->psc_spicfg = cfg; - au_sync(); + wmb(); /* drain writebuffer */ if (cfg & PSC_SPICFG_DE_ENABLE) { do { stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ } while ((stat & PSC_SPISTAT_DR) == 0); } @@ -396,11 +396,11 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) /* by default enable nearly all events interrupt */ hw->regs->psc_spimsk = PSC_SPIMSK_SD; - au_sync(); + wmb(); /* drain writebuffer */ /* start the transfer */ hw->regs->psc_spipcr = PSC_SPIPCR_MS; - au_sync(); + wmb(); /* drain writebuffer */ wait_for_completion(&hw->master_done); @@ -429,7 +429,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) stat = hw->regs->psc_spistat; evnt = hw->regs->psc_spievent; - au_sync(); + wmb(); /* drain writebuffer */ if ((stat & PSC_SPISTAT_DI) == 0) { dev_err(hw->dev, "Unexpected IRQ!\n"); return IRQ_NONE; @@ -484,7 +484,7 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ { \ u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ - au_sync(); \ + wmb(); /* drain writebuffer */ \ if (hw->rx) { \ *(u##size *)hw->rx = (u##size)fifoword; \ hw->rx += (size) / 8; \ @@ -504,7 +504,7 @@ static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ if (hw->tx_count >= hw->len) \ fifoword |= PSC_SPITXRX_LC; \ hw->regs->psc_spitxrx = fifoword; \ - au_sync(); \ + wmb(); /* drain writebuffer */ \ } AU1550_SPI_RX_WORD(8,0xff) @@ -539,18 +539,18 @@ static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) } stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ if (stat & PSC_SPISTAT_TF) break; } /* enable event interrupts */ hw->regs->psc_spimsk = mask; - au_sync(); + wmb(); /* drain writebuffer */ /* start the transfer */ hw->regs->psc_spipcr = PSC_SPIPCR_MS; - au_sync(); + wmb(); /* drain writebuffer */ wait_for_completion(&hw->master_done); @@ -564,7 +564,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) stat = hw->regs->psc_spistat; evnt = hw->regs->psc_spievent; - au_sync(); + wmb(); /* drain writebuffer */ if ((stat & PSC_SPISTAT_DI) == 0) { dev_err(hw->dev, "Unexpected IRQ!\n"); return IRQ_NONE; @@ -594,7 +594,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) do { busy = 0; stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ /* * Take care to not let the Rx FIFO overflow. @@ -615,7 +615,7 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) } while (busy); hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR; - au_sync(); + wmb(); /* drain writebuffer */ /* * Restart the SPI transmission in case of a transmit underflow. @@ -634,9 +634,9 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) */ if (evnt & PSC_SPIEVNT_TU) { hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_spipcr = PSC_SPIPCR_MS; - au_sync(); + wmb(); /* drain writebuffer */ } if (hw->rx_count >= hw->len) { @@ -690,19 +690,19 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) /* set up the PSC for SPI mode */ hw->regs->psc_ctrl = PSC_CTRL_DISABLE; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_spicfg = 0; - au_sync(); + wmb(); /* drain writebuffer */ hw->regs->psc_ctrl = PSC_CTRL_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ do { stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ } while ((stat & PSC_SPISTAT_SR) == 0); @@ -717,16 +717,16 @@ static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) #endif hw->regs->psc_spicfg = cfg; - au_sync(); + wmb(); /* drain writebuffer */ au1550_spi_mask_ack_all(hw); hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; - au_sync(); + wmb(); /* drain writebuffer */ do { stat = hw->regs->psc_spistat; - au_sync(); + wmb(); /* drain writebuffer */ } while ((stat & PSC_SPISTAT_DR) == 0); au1550_spi_reset_fifos(hw); diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index c0832eaff4d1..c163424de223 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -113,7 +113,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) case VESA_NO_BLANKING: /* Turn on panel */ fbdev->regs->lcd_control |= LCD_CONTROL_GO; - au_sync(); + wmb(); /* drain writebuffer */ break; case VESA_VSYNC_SUSPEND: @@ -121,7 +121,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) case VESA_POWERDOWN: /* Turn off panel */ fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; - au_sync(); + wmb(); /* drain writebuffer */ break; default: break; diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 2d77334af41b..1c8e106dca00 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -764,7 +764,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, /* Disable the window while making changes, then restore WINEN */ winenable = lcd->winenable & (1 << plane); - au_sync(); + wmb(); /* drain writebuffer */ lcd->winenable &= ~(1 << plane); lcd->window[plane].winctrl0 = winctrl0; lcd->window[plane].winctrl1 = winctrl1; @@ -772,7 +772,7 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, lcd->window[plane].winbuf1 = fbdev->fb_phys; lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ lcd->winenable |= winenable; - au_sync(); + wmb(); /* drain writebuffer */ return 0; } @@ -788,22 +788,21 @@ static void au1200_setpanel(struct panel_settings *newpanel, /* Make sure all windows disabled */ winenable = lcd->winenable; lcd->winenable = 0; - au_sync(); + wmb(); /* drain writebuffer */ /* * Ensure everything is disabled before reconfiguring */ if (lcd->screen & LCD_SCREEN_SEN) { /* Wait for vertical sync period */ lcd->intstatus = LCD_INT_SS; - while ((lcd->intstatus & LCD_INT_SS) == 0) { - au_sync(); - } + while ((lcd->intstatus & LCD_INT_SS) == 0) + ; lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ do { lcd->intstatus = lcd->intstatus; /*clear interrupts*/ - au_sync(); + wmb(); /* drain writebuffer */ /*wait for controller to shut down*/ } while ((lcd->intstatus & LCD_INT_SD) == 0); @@ -847,7 +846,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, lcd->pwmhi = panel->mode_pwmhi; lcd->outmask = panel->mode_outmask; lcd->fifoctrl = panel->mode_fifoctrl; - au_sync(); + wmb(); /* drain writebuffer */ /* fixme: Check window settings to make sure still valid * for new geometry */ @@ -863,7 +862,7 @@ static void au1200_setpanel(struct panel_settings *newpanel, * Re-enable screen now that it is configured */ lcd->screen |= LCD_SCREEN_SEN; - au_sync(); + wmb(); /* drain writebuffer */ /* Call init of panel */ if (pd->panel_init) @@ -956,7 +955,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev) | LCD_WINCTRL2_SCY_1 ) ; lcd->winenable |= win->w[plane].mode_winenable; - au_sync(); + wmb(); /* drain writebuffer */ } @@ -1270,7 +1269,7 @@ static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) if (pdata->flags & SCREEN_MASK) lcd->colorkeymsk = pdata->mask; - au_sync(); + wmb(); /* drain writebuffer */ } static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) @@ -1288,7 +1287,7 @@ static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) hi1 = (lcd->pwmhi >> 16) + 1; divider = (lcd->pwmdiv & 0x3FFFF) + 1; pdata->brightness = ((hi1 << 8) / divider) - 1; - au_sync(); + wmb(); /* drain writebuffer */ } static void set_window(unsigned int plane, @@ -1387,7 +1386,7 @@ static void set_window(unsigned int plane, val |= (pdata->enable & 1) << plane; lcd->winenable = val; } - au_sync(); + wmb(); /* drain writebuffer */ } static void get_window(unsigned int plane, @@ -1414,7 +1413,7 @@ static void get_window(unsigned int plane, pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21; pdata->enable = (lcd->winenable >> plane) & 1; - au_sync(); + wmb(); /* drain writebuffer */ } static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd, @@ -1511,7 +1510,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id) { /* Nothing to do for now, just clear any pending interrupt */ lcd->intstatus = lcd->intstatus; - au_sync(); + wmb(); /* drain writebuffer */ return IRQ_HANDLED; } @@ -1809,7 +1808,7 @@ static int au1200fb_drv_suspend(struct device *dev) au1200_setpanel(NULL, pd); lcd->outmask = 0; - au_sync(); + wmb(); /* drain writebuffer */ return 0; } diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 986dcec79fa0..84f31e1f9d24 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -79,28 +79,28 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97, unsigned short retry, tmo; unsigned long data; - au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); - au_sync(); + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + wmb(); /* drain writebuffer */ retry = AC97_RW_RETRIES; do { mutex_lock(&pscdata->lock); - au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), + __raw_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), AC97_CDC(pscdata)); - au_sync(); + wmb(); /* drain writebuffer */ tmo = 20; do { udelay(21); - if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) + if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) break; } while (--tmo); - data = au_readl(AC97_CDC(pscdata)); + data = __raw_readl(AC97_CDC(pscdata)); - au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); - au_sync(); + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + wmb(); /* drain writebuffer */ mutex_unlock(&pscdata->lock); @@ -119,26 +119,26 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); unsigned int tmo, retry; - au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); - au_sync(); + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + wmb(); /* drain writebuffer */ retry = AC97_RW_RETRIES; do { mutex_lock(&pscdata->lock); - au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), + __raw_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), AC97_CDC(pscdata)); - au_sync(); + wmb(); /* drain writebuffer */ tmo = 20; do { udelay(21); - if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) + if (__raw_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD) break; } while (--tmo); - au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); - au_sync(); + __raw_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); + wmb(); /* drain writebuffer */ mutex_unlock(&pscdata->lock); } while (--retry && !tmo); @@ -149,11 +149,11 @@ static void au1xpsc_ac97_warm_reset(struct snd_ac97 *ac97) { struct au1xpsc_audio_data *pscdata = ac97_to_pscdata(ac97); - au_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); - au_sync(); + __raw_writel(PSC_AC97RST_SNC, AC97_RST(pscdata)); + wmb(); /* drain writebuffer */ msleep(10); - au_writel(0, AC97_RST(pscdata)); - au_sync(); + __raw_writel(0, AC97_RST(pscdata)); + wmb(); /* drain writebuffer */ } static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) @@ -162,25 +162,25 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) int i; /* disable PSC during cold reset */ - au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); - au_sync(); - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata)); - au_sync(); + __raw_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(pscdata)); + wmb(); /* drain writebuffer */ /* issue cold reset */ - au_writel(PSC_AC97RST_RST, AC97_RST(pscdata)); - au_sync(); + __raw_writel(PSC_AC97RST_RST, AC97_RST(pscdata)); + wmb(); /* drain writebuffer */ msleep(500); - au_writel(0, AC97_RST(pscdata)); - au_sync(); + __raw_writel(0, AC97_RST(pscdata)); + wmb(); /* drain writebuffer */ /* enable PSC */ - au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); - au_sync(); + __raw_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); + wmb(); /* drain writebuffer */ /* wait for PSC to indicate it's ready */ i = 1000; - while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) + while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) msleep(1); if (i == 0) { @@ -189,12 +189,12 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97) } /* enable the ac97 function */ - au_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); - au_sync(); + __raw_writel(pscdata->cfg | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + wmb(); /* drain writebuffer */ /* wait for AC97 core to become ready */ i = 1000; - while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) + while (!((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) msleep(1); if (i == 0) printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); @@ -218,8 +218,8 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, chans = params_channels(params); - r = ro = au_readl(AC97_CFG(pscdata)); - stat = au_readl(AC97_STAT(pscdata)); + r = ro = __raw_readl(AC97_CFG(pscdata)); + stat = __raw_readl(AC97_STAT(pscdata)); /* already active? */ if (stat & (PSC_AC97STAT_TB | PSC_AC97STAT_RB)) { @@ -252,28 +252,28 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, mutex_lock(&pscdata->lock); /* disable AC97 device controller first... */ - au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); - au_sync(); + __raw_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + wmb(); /* drain writebuffer */ /* ...wait for it... */ t = 100; - while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t) + while ((__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t) msleep(1); if (!t) printk(KERN_ERR "PSC-AC97: can't disable!\n"); /* ...write config... */ - au_writel(r, AC97_CFG(pscdata)); - au_sync(); + __raw_writel(r, AC97_CFG(pscdata)); + wmb(); /* drain writebuffer */ /* ...enable the AC97 controller again... */ - au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); - au_sync(); + __raw_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); + wmb(); /* drain writebuffer */ /* ...and wait for ready bit */ t = 100; - while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t) + while ((!(__raw_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t) msleep(1); if (!t) @@ -300,21 +300,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); - au_sync(); - au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); - au_sync(); + __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); + wmb(); /* drain writebuffer */ + __raw_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); + wmb(); /* drain writebuffer */ break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: - au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); - au_sync(); + __raw_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); + wmb(); /* drain writebuffer */ - while (au_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype)) + while (__raw_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype)) asm volatile ("nop"); - au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); - au_sync(); + __raw_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata)); + wmb(); /* drain writebuffer */ break; default: @@ -398,13 +398,13 @@ static int au1xpsc_ac97_drvprobe(struct platform_device *pdev) PSC_AC97CFG_DE_ENABLE; /* preserve PSC clock source set up by platform */ - sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); - au_writel(0, PSC_SEL(wd)); - au_sync(); - au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); - au_sync(); + sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(0, PSC_SEL(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd)); + wmb(); /* drain writebuffer */ /* name the DAI like this device instance ("au1xpsc-ac97.PSCINDEX") */ memcpy(&wd->dai_drv, &au1xpsc_ac97_dai_template, @@ -433,10 +433,10 @@ static int au1xpsc_ac97_drvremove(struct platform_device *pdev) snd_soc_unregister_component(&pdev->dev); /* disable PSC completely */ - au_writel(0, AC97_CFG(wd)); - au_sync(); - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); + __raw_writel(0, AC97_CFG(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ au1xpsc_ac97_workdata = NULL; /* MDEV */ @@ -449,12 +449,12 @@ static int au1xpsc_ac97_drvsuspend(struct device *dev) struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); /* save interesting registers and disable PSC */ - wd->pm[0] = au_readl(PSC_SEL(wd)); + wd->pm[0] = __raw_readl(PSC_SEL(wd)); - au_writel(0, AC97_CFG(wd)); - au_sync(); - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); + __raw_writel(0, AC97_CFG(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ return 0; } @@ -464,8 +464,8 @@ static int au1xpsc_ac97_drvresume(struct device *dev) struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); /* restore PSC clock config */ - au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd)); - au_sync(); + __raw_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd)); + wmb(); /* drain writebuffer */ /* after this point the ac97 core will cold-reset the codec. * During cold-reset the PSC is reinitialized and the last diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index fe923a7bdc39..814beffc56f2 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -120,10 +120,10 @@ static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, unsigned long stat; /* check if the PSC is already streaming data */ - stat = au_readl(I2S_STAT(pscdata)); + stat = __raw_readl(I2S_STAT(pscdata)); if (stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB)) { /* reject parameters not currently set up in hardware */ - cfgbits = au_readl(I2S_CFG(pscdata)); + cfgbits = __raw_readl(I2S_CFG(pscdata)); if ((PSC_I2SCFG_GET_LEN(cfgbits) != params->msbits) || (params_rate(params) != pscdata->rate)) return -EINVAL; @@ -149,33 +149,33 @@ static int au1xpsc_i2s_configure(struct au1xpsc_audio_data *pscdata) unsigned long tmo; /* bring PSC out of sleep, and configure I2S unit */ - au_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); - au_sync(); + __raw_writel(PSC_CTRL_ENABLE, PSC_CTRL(pscdata)); + wmb(); /* drain writebuffer */ tmo = 1000000; - while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo) + while (!(__raw_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_SR) && tmo) tmo--; if (!tmo) goto psc_err; - au_writel(0, I2S_CFG(pscdata)); - au_sync(); - au_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata)); - au_sync(); + __raw_writel(0, I2S_CFG(pscdata)); + wmb(); /* drain writebuffer */ + __raw_writel(pscdata->cfg | PSC_I2SCFG_DE_ENABLE, I2S_CFG(pscdata)); + wmb(); /* drain writebuffer */ /* wait for I2S controller to become ready */ tmo = 1000000; - while (!(au_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo) + while (!(__raw_readl(I2S_STAT(pscdata)) & PSC_I2SSTAT_DR) && tmo) tmo--; if (tmo) return 0; psc_err: - au_writel(0, I2S_CFG(pscdata)); - au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); - au_sync(); + __raw_writel(0, I2S_CFG(pscdata)); + __raw_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); + wmb(); /* drain writebuffer */ return -ETIMEDOUT; } @@ -187,26 +187,26 @@ static int au1xpsc_i2s_start(struct au1xpsc_audio_data *pscdata, int stype) ret = 0; /* if both TX and RX are idle, configure the PSC */ - stat = au_readl(I2S_STAT(pscdata)); + stat = __raw_readl(I2S_STAT(pscdata)); if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { ret = au1xpsc_i2s_configure(pscdata); if (ret) goto out; } - au_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata)); - au_sync(); - au_writel(I2SPCR_START(stype), I2S_PCR(pscdata)); - au_sync(); + __raw_writel(I2SPCR_CLRFIFO(stype), I2S_PCR(pscdata)); + wmb(); /* drain writebuffer */ + __raw_writel(I2SPCR_START(stype), I2S_PCR(pscdata)); + wmb(); /* drain writebuffer */ /* wait for start confirmation */ tmo = 1000000; - while (!(au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) + while (!(__raw_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) tmo--; if (!tmo) { - au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); - au_sync(); + __raw_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); + wmb(); /* drain writebuffer */ ret = -ETIMEDOUT; } out: @@ -217,21 +217,21 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype) { unsigned long tmo, stat; - au_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); - au_sync(); + __raw_writel(I2SPCR_STOP(stype), I2S_PCR(pscdata)); + wmb(); /* drain writebuffer */ /* wait for stop confirmation */ tmo = 1000000; - while ((au_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) + while ((__raw_readl(I2S_STAT(pscdata)) & I2SSTAT_BUSY(stype)) && tmo) tmo--; /* if both TX and RX are idle, disable PSC */ - stat = au_readl(I2S_STAT(pscdata)); + stat = __raw_readl(I2S_STAT(pscdata)); if (!(stat & (PSC_I2SSTAT_TB | PSC_I2SSTAT_RB))) { - au_writel(0, I2S_CFG(pscdata)); - au_sync(); - au_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); - au_sync(); + __raw_writel(0, I2S_CFG(pscdata)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_SUSPEND, PSC_CTRL(pscdata)); + wmb(); /* drain writebuffer */ } return 0; } @@ -332,12 +332,12 @@ static int au1xpsc_i2s_drvprobe(struct platform_device *pdev) /* preserve PSC clock source set up by platform (dev.platform_data * is already occupied by soc layer) */ - sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); - au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd)); - au_writel(0, I2S_CFG(wd)); - au_sync(); + sel = __raw_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK; + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd)); + __raw_writel(0, I2S_CFG(wd)); + wmb(); /* drain writebuffer */ /* preconfigure: set max rx/tx fifo depths */ wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8; @@ -364,10 +364,10 @@ static int au1xpsc_i2s_drvremove(struct platform_device *pdev) snd_soc_unregister_component(&pdev->dev); - au_writel(0, I2S_CFG(wd)); - au_sync(); - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); + __raw_writel(0, I2S_CFG(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ return 0; } @@ -378,12 +378,12 @@ static int au1xpsc_i2s_drvsuspend(struct device *dev) struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); /* save interesting register and disable PSC */ - wd->pm[0] = au_readl(PSC_SEL(wd)); + wd->pm[0] = __raw_readl(PSC_SEL(wd)); - au_writel(0, I2S_CFG(wd)); - au_sync(); - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); + __raw_writel(0, I2S_CFG(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ return 0; } @@ -393,12 +393,12 @@ static int au1xpsc_i2s_drvresume(struct device *dev) struct au1xpsc_audio_data *wd = dev_get_drvdata(dev); /* select I2S mode and PSC clock */ - au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); - au_sync(); - au_writel(0, PSC_SEL(wd)); - au_sync(); - au_writel(wd->pm[0], PSC_SEL(wd)); - au_sync(); + __raw_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(0, PSC_SEL(wd)); + wmb(); /* drain writebuffer */ + __raw_writel(wd->pm[0], PSC_SEL(wd)); + wmb(); /* drain writebuffer */ return 0; } diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h index b16b2e02e0c9..74dffeb641fa 100644 --- a/sound/soc/au1x/psc.h +++ b/sound/soc/au1x/psc.h @@ -27,16 +27,16 @@ struct au1xpsc_audio_data { }; /* easy access macros */ -#define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) -#define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) -#define I2S_STAT(x) ((unsigned long)((x)->mmio) + PSC_I2SSTAT_OFFSET) -#define I2S_CFG(x) ((unsigned long)((x)->mmio) + PSC_I2SCFG_OFFSET) -#define I2S_PCR(x) ((unsigned long)((x)->mmio) + PSC_I2SPCR_OFFSET) -#define AC97_CFG(x) ((unsigned long)((x)->mmio) + PSC_AC97CFG_OFFSET) -#define AC97_CDC(x) ((unsigned long)((x)->mmio) + PSC_AC97CDC_OFFSET) -#define AC97_EVNT(x) ((unsigned long)((x)->mmio) + PSC_AC97EVNT_OFFSET) -#define AC97_PCR(x) ((unsigned long)((x)->mmio) + PSC_AC97PCR_OFFSET) -#define AC97_RST(x) ((unsigned long)((x)->mmio) + PSC_AC97RST_OFFSET) -#define AC97_STAT(x) ((unsigned long)((x)->mmio) + PSC_AC97STAT_OFFSET) +#define PSC_CTRL(x) ((x)->mmio + PSC_CTRL_OFFSET) +#define PSC_SEL(x) ((x)->mmio + PSC_SEL_OFFSET) +#define I2S_STAT(x) ((x)->mmio + PSC_I2SSTAT_OFFSET) +#define I2S_CFG(x) ((x)->mmio + PSC_I2SCFG_OFFSET) +#define I2S_PCR(x) ((x)->mmio + PSC_I2SPCR_OFFSET) +#define AC97_CFG(x) ((x)->mmio + PSC_AC97CFG_OFFSET) +#define AC97_CDC(x) ((x)->mmio + PSC_AC97CDC_OFFSET) +#define AC97_EVNT(x) ((x)->mmio + PSC_AC97EVNT_OFFSET) +#define AC97_PCR(x) ((x)->mmio + PSC_AC97PCR_OFFSET) +#define AC97_RST(x) ((x)->mmio + PSC_AC97RST_OFFSET) +#define AC97_STAT(x) ((x)->mmio + PSC_AC97STAT_OFFSET) #endif -- cgit v1.2.3 From 5828c60826e9422169b3711aa58a583242864cc8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 31 Jul 2014 18:36:20 +0300 Subject: mtd: ndfc: silence an array underflow static checker warning We check "cs" for array overflows but we don't check for underflows and it upsets the static checkers. Signed-off-by: Dan Carpenter Signed-off-by: Brian Norris --- drivers/mtd/nand/ndfc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 69eaba690a99..253a644da76a 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -203,7 +203,8 @@ static int ndfc_probe(struct platform_device *ofdev) struct ndfc_controller *ndfc; const __be32 *reg; u32 ccr; - int err, len, cs; + u32 cs; + int err, len; /* Read the reg property to get the chip select */ reg = of_get_property(ofdev->dev.of_node, "reg", &len); -- cgit v1.2.3 From 9b6e5172e363b0c35a6be4d3197f3bcdc789292e Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 31 Jul 2014 16:31:16 +0200 Subject: mtd: use NULL instead of 0 for an address Use NULL instead of 0 when returning an address. This fixes a sparse warning. Signed-off-by: Martin Kepplinger Signed-off-by: Brian Norris --- drivers/mtd/maps/pcmciamtd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index a3cfad392ed6..af747af5eee9 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -89,7 +89,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) if (!pcmcia_dev_present(dev->p_dev)) { pr_debug("device removed\n"); - return 0; + return NULL; } offset = to & ~(dev->win_size-1); -- cgit v1.2.3 From 796fe3648a13b311f5b9a125e2d2532a2ce7c78a Mon Sep 17 00:00:00 2001 From: Raphaël Poggi Date: Tue, 29 Jul 2014 15:27:27 +0200 Subject: mtd: atmel_nand: increase chip_delay Some nand with 8k page size like Micron MT29F32G08ABAAAWP need more than 20us. Signed-off-by: Raphaël Poggi Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e321c564ff05..77bd877d8f28 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -2099,7 +2099,7 @@ static int atmel_nand_probe(struct platform_device *pdev) } nand_chip->ecc.mode = host->board.ecc_mode; - nand_chip->chip_delay = 20; /* 20us command delay time */ + nand_chip->chip_delay = 40; /* 40us command delay time */ if (host->board.bus_width_16) /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; -- cgit v1.2.3 From a35571058ec8e7c82dceea90cdecead51674f963 Mon Sep 17 00:00:00 2001 From: Wu, Josh Date: Tue, 22 Jul 2014 17:24:18 +0800 Subject: mtd: atmel_nand: add pmecc support for 512, 1k, 4k, 8k page size PMECC can support 512, 1k, 2k, 4k, 8k page size. The driver currently only support 2k page size nand flash. So this patch add support to 512, 1k, 4k and 8k page size nand flash. Signed-off-by: Josh Wu Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 77bd877d8f28..e4d57ffef07e 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1174,7 +1174,17 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, /* set ECC page size and oob layout */ switch (mtd->writesize) { + case 512: + case 1024: case 2048: + case 4096: + case 8192: + if (sector_size > mtd->writesize) { + dev_err(host->dev, "pmecc sector size is bigger than the page size!\n"); + err_no = -EINVAL; + goto err; + } + host->pmecc_degree = (sector_size == 512) ? PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14; host->pmecc_cw_len = (1 << host->pmecc_degree) - 1; @@ -1201,13 +1211,9 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, nand_chip->ecc.layout = &atmel_pmecc_oobinfo; break; - case 512: - case 1024: - case 4096: - /* TODO */ + default: dev_warn(host->dev, "Unsupported page size for PMECC, use Software ECC\n"); - default: /* page size not handled by HW ECC */ /* switching back to soft ECC */ nand_chip->ecc.mode = NAND_ECC_SOFT; -- cgit v1.2.3 From f2fabe16b819cdead86fb38c8ab88a0d9c308293 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 27 Jul 2014 23:56:08 +0200 Subject: mtd: spi-nor: add support for Micron M25PX80 This commit adds the support in the spi-nor driver of the Micron M25PX80 flash, a 8 Mbit SPI flash from Micron. Signed-off-by: Thomas Petazzoni Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b5ad6bebf5e7..4dc0c8662265 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -611,6 +611,7 @@ const struct spi_device_id spi_nor_ids[] = { { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, + { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, -- cgit v1.2.3 From 8fb7b9309c41407801958138db978eb38fd80c01 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 28 Jul 2014 21:19:55 +0800 Subject: mtd: atmel_nand: remove redundant dev_err call There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Wei Yongjun Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e4d57ffef07e..0abc965caedf 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1148,7 +1148,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, host->ecc = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(host->ecc)) { - dev_err(host->dev, "ioremap failed\n"); err_no = PTR_ERR(host->ecc); goto err; } @@ -1156,8 +1155,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2); host->pmerrloc_base = devm_ioremap_resource(&pdev->dev, regs_pmerr); if (IS_ERR(host->pmerrloc_base)) { - dev_err(host->dev, - "Can not get I/O resource for PMECC ERRLOC controller!\n"); err_no = PTR_ERR(host->pmerrloc_base); goto err; } @@ -1165,7 +1162,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3); host->pmecc_rom_base = devm_ioremap_resource(&pdev->dev, regs_rom); if (IS_ERR(host->pmecc_rom_base)) { - dev_err(host->dev, "Can not get I/O resource for ROM!\n"); err_no = PTR_ERR(host->pmecc_rom_base); goto err; } @@ -1536,10 +1532,8 @@ static int atmel_hw_nand_init_params(struct platform_device *pdev, } host->ecc = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(host->ecc)) { - dev_err(host->dev, "ioremap failed\n"); + if (IS_ERR(host->ecc)) return PTR_ERR(host->ecc); - } /* ECC is calculated for the whole page (1 step) */ nand_chip->ecc.size = mtd->writesize; @@ -2046,7 +2040,6 @@ static int atmel_nand_probe(struct platform_device *pdev) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->io_base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(host->io_base)) { - dev_err(&pdev->dev, "atmel_nand: ioremap resource failed\n"); res = PTR_ERR(host->io_base); goto err_nand_ioremap; } -- cgit v1.2.3 From 2902330e7ac16d5962f114d92bb17631e9cb49e9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 11 Jul 2014 11:14:05 +0900 Subject: mtd: denali: avoid using a magic number MAP10 command with '0x2000' data sets up a read-ahead/write access. Signed-off-by: Masahiro Yamada Signed-off-by: Brian Norris --- drivers/mtd/nand/denali.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 0b071a3136a2..da0fcc224739 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -74,6 +74,7 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting." #define SPARE_ACCESS 0x41 #define MAIN_ACCESS 0x42 #define MAIN_SPARE_ACCESS 0x43 +#define PIPELINE_ACCESS 0x2000 #define DENALI_READ 0 #define DENALI_WRITE 0x100 @@ -765,7 +766,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, iowrite32(cmd, denali->flash_mem); } else { index_addr(denali, (uint32_t)cmd, - 0x2000 | op | page_count); + PIPELINE_ACCESS | op | page_count); /* wait for command to be accepted * can always use status0 bit as the -- cgit v1.2.3 From 6f3c0f163103fb225c77b73ca17fc4ecea308103 Mon Sep 17 00:00:00 2001 From: Samarth Parikh Date: Wed, 16 Jul 2014 16:14:37 +0530 Subject: mtd: Fixed checkpatch seq_printf warnings Fixed checkpatch warnings: "WARNING: Prefer seq_puts to seq_printf" This patch is created with reference to the ongoing lkml thread https://lkml.org/lkml/2014/7/15/646 where Andrew Morton wrote: " - puts is presumably faster - puts doesn't go rogue if you accidentally pass it a "%". - this patch would actually make compiled object files few bytes smaller. Perhaps because seq_printf() is a varargs function, forcing the caller to pass args on the stack instead of in registers. " Signed-off-by: Samarth Parikh Signed-off-by: Brian Norris --- drivers/mtd/devices/docg3.c | 26 +++++++++++++------------- drivers/mtd/mtdswap.c | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 91a169c44b39..21cc4b66feaa 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1697,16 +1697,16 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) switch (mode) { case DOC_ASICMODE_RESET: - pos += seq_printf(s, "reset"); + pos += seq_puts(s, "reset"); break; case DOC_ASICMODE_NORMAL: - pos += seq_printf(s, "normal"); + pos += seq_puts(s, "normal"); break; case DOC_ASICMODE_POWERDOWN: - pos += seq_printf(s, "powerdown"); + pos += seq_puts(s, "powerdown"); break; } - pos += seq_printf(s, ")\n"); + pos += seq_puts(s, ")\n"); return pos; } DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); @@ -1745,22 +1745,22 @@ static int dbg_protection_show(struct seq_file *s, void *p) pos += seq_printf(s, "Protection = 0x%02x (", protect); if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) - pos += seq_printf(s, "FOUNDRY_OTP_LOCK,"); + pos += seq_puts(s, "FOUNDRY_OTP_LOCK,"); if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) - pos += seq_printf(s, "CUSTOMER_OTP_LOCK,"); + pos += seq_puts(s, "CUSTOMER_OTP_LOCK,"); if (protect & DOC_PROTECT_LOCK_INPUT) - pos += seq_printf(s, "LOCK_INPUT,"); + pos += seq_puts(s, "LOCK_INPUT,"); if (protect & DOC_PROTECT_STICKY_LOCK) - pos += seq_printf(s, "STICKY_LOCK,"); + pos += seq_puts(s, "STICKY_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ENABLED) - pos += seq_printf(s, "PROTECTION ON,"); + pos += seq_puts(s, "PROTECTION ON,"); if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) - pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,"); + pos += seq_puts(s, "IPL_DOWNLOAD_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ERROR) - pos += seq_printf(s, "PROTECT_ERR,"); + pos += seq_puts(s, "PROTECT_ERR,"); else - pos += seq_printf(s, "NO_PROTECT_ERR"); - pos += seq_printf(s, ")\n"); + pos += seq_puts(s, "NO_PROTECT_ERR"); + pos += seq_puts(s, ")\n"); pos += seq_printf(s, "DPS0 = 0x%02x : " "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 8b33b26eb12b..0ec96cd5dc78 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1287,7 +1287,7 @@ static int mtdswap_show(struct seq_file *s, void *data) seq_printf(s, "total erasures: %lu\n", sum); - seq_printf(s, "\n"); + seq_puts(s, "\n"); seq_printf(s, "mtdswap_readsect count: %llu\n", d->sect_read_count); seq_printf(s, "mtdswap_writesect count: %llu\n", d->sect_write_count); @@ -1296,7 +1296,7 @@ static int mtdswap_show(struct seq_file *s, void *data) seq_printf(s, "mtd write count: %llu\n", d->mtd_write_count); seq_printf(s, "discarded pages count: %llu\n", d->discard_page_count); - seq_printf(s, "\n"); + seq_puts(s, "\n"); seq_printf(s, "total pages: %u\n", pages); seq_printf(s, "pages mapped: %u\n", mapped); -- cgit v1.2.3 From 57d3a9a89a0645f3597561e214f8d6852a2c56b4 Mon Sep 17 00:00:00 2001 From: White Ding Date: Thu, 24 Jul 2014 00:10:45 +0800 Subject: mtd: nand: fix nand_lock/unlock() function Do nand reset before write protect check. If we want to check the WP# low or high through STATUS READ and check bit 7, we must reset the device, other operation (eg.erase/program a locked block) can also clear the bit 7 of status register. As we know the status register can be refreshed, if we do some operation to trigger it, for example if we do erase/program operation to one block that is locked, then READ STATUS, the bit 7 of READ STATUS will be 0 indicate the device in write protect, then if we do erase/program operation to another block that is unlocked, the bit 7 of READ STATUS will be 1 indicate the device is not write protect. Suppose we checked the bit 7 of READ STATUS is 0 then judge the WP# is low (write protect), but in this case the WP# maybe high if we do erase/program operation to a locked block, so we must reset the device if we want to check the WP# low or high through STATUS READ and check bit 7. Signed-off-by: White Ding Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d8cdf06343fb..1a27c2da29ff 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -982,6 +982,15 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) chip->select_chip(mtd, chipnr); + /* + * Reset the chip. + * If we want to check the WP through READ STATUS and check the bit 7 + * we must reset the chip + * some operation can also clear the bit 7 of status register + * eg. erase/program a locked block + */ + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* Check, if it is write protected */ if (nand_check_wp(mtd)) { pr_debug("%s: device is write protected!\n", @@ -1032,6 +1041,15 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) chip->select_chip(mtd, chipnr); + /* + * Reset the chip. + * If we want to check the WP through READ STATUS and check the bit 7 + * we must reset the chip + * some operation can also clear the bit 7 of status register + * eg. erase/program a locked block + */ + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* Check, if it is write protected */ if (nand_check_wp(mtd)) { pr_debug("%s: device is write protected!\n", -- cgit v1.2.3 From 36c6a7ac74044b8025488c018279115bb3c32eb0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:19 -0700 Subject: mtd: cfi_cmdset_0002: allow retry/timeout loop to exit The variable 'retries' is never modified, so if the reset operation never is going to complete, we'll get stuck in an infinite loop. It looks like the intention was to decrement 'retries' on every loop. Untested. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0002.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5a4bfe33112a..6da141af9cba 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -2029,6 +2029,8 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip, udelay(1); } + + retries--; } /* the chip never became ready */ -- cgit v1.2.3 From 0c2b4e21444d0e274e91fc7db85caddb30988853 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:27 -0700 Subject: mtd: correct upper bounds check for mtd_*() APIs When checking the upper boundary (i.e., whether an address is higher than the maximum size of the MTD), we should be doing an inclusive check (greater or equal). For instance, an address of 16MB (0x1000000) on a 16MB device is invalid. The strengthening of this bounds check is redundant for those which already have a address+length check and ensure that the length is non-zero, but let's just fix them all, for completeness. Signed-off-by: Brian Norris --- drivers/mtd/mtdcore.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index e4831b4159db..c1015173f2d9 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -778,7 +778,7 @@ EXPORT_SYMBOL_GPL(__put_mtd_device); */ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { - if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) + if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -804,7 +804,7 @@ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, *phys = 0; if (!mtd->_point) return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -817,7 +817,7 @@ int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { if (!mtd->_point) return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -835,7 +835,7 @@ unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, { if (!mtd->_get_unmapped_area) return -EOPNOTSUPP; - if (offset > mtd->size || len > mtd->size - offset) + if (offset >= mtd->size || len > mtd->size - offset) return -EINVAL; return mtd->_get_unmapped_area(mtd, len, offset, flags); } @@ -846,7 +846,7 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, { int ret_code; *retlen = 0; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -869,7 +869,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { *retlen = 0; - if (to < 0 || to > mtd->size || len > mtd->size - to) + if (to < 0 || to >= mtd->size || len > mtd->size - to) return -EINVAL; if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -892,7 +892,7 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, *retlen = 0; if (!mtd->_panic_write) return -EOPNOTSUPP; - if (to < 0 || to > mtd->size || len > mtd->size - to) + if (to < 0 || to >= mtd->size || len > mtd->size - to) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -1011,7 +1011,7 @@ int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_lock) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1023,7 +1023,7 @@ int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_unlock) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1035,7 +1035,7 @@ int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_is_locked) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1045,7 +1045,7 @@ EXPORT_SYMBOL_GPL(mtd_is_locked); int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) { - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!mtd->_block_isreserved) return 0; @@ -1055,7 +1055,7 @@ EXPORT_SYMBOL_GPL(mtd_block_isreserved); int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!mtd->_block_isbad) return 0; @@ -1067,7 +1067,7 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->_block_markbad) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; -- cgit v1.2.3 From f7f0d358f5f2f1133b5a14337028ddab848cd74e Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:39 -0700 Subject: mtd: sm_ftl: initialize error code There is one theoretical case that could fall through to using an uninitialized value as the return code. Let's give it a value of 0. Untested. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/sm_ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index cf49c22673b9..c23184a47fc4 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -1058,7 +1058,7 @@ static int sm_write(struct mtd_blktrans_dev *dev, { struct sm_ftl *ftl = dev->priv; struct ftl_zone *zone; - int error, zone_num, block, boffset; + int error = 0, zone_num, block, boffset; BUG_ON(ftl->readonly); sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset); -- cgit v1.2.3 From 5e47212831ac565993d21ebd36216d98f2b58f30 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:47 -0700 Subject: mtd: remove dead non-char logic MTD used to allow compiling out character device support. This was dropped in the following commit, but some of the accompanying logic was never dropped: commit 660685d9d1b4730f0b5ca97fa95f272f99c63bce Author: Artem Bityutskiy Date: Thu Mar 14 13:27:40 2013 +0200 mtd: merge mtdchar module with mtdcore The weird logic was flagged by Coverity. Signed-off-by: Brian Norris Cc: Artem Bityutskiy --- drivers/mtd/mtdcore.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index c1015173f2d9..4c611871d7e6 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -105,12 +105,11 @@ static LIST_HEAD(mtd_notifiers); */ static void mtd_release(struct device *dev) { - struct mtd_info __maybe_unused *mtd = dev_get_drvdata(dev); + struct mtd_info *mtd = dev_get_drvdata(dev); dev_t index = MTD_DEVT(mtd->index); - /* remove /dev/mtdXro node if needed */ - if (index) - device_destroy(&mtd_class, index + 1); + /* remove /dev/mtdXro node */ + device_destroy(&mtd_class, index + 1); } static int mtd_cls_suspend(struct device *dev, pm_message_t state) @@ -442,10 +441,8 @@ int add_mtd_device(struct mtd_info *mtd) if (device_register(&mtd->dev) != 0) goto fail_added; - if (MTD_DEVT(i)) - device_create(&mtd_class, mtd->dev.parent, - MTD_DEVT(i) + 1, - NULL, "mtd%dro", i); + device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, + "mtd%dro", i); pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name); /* No need to get a refcount on the module containing -- cgit v1.2.3 From 8c3f3f1d7941bcb25590b784f84accd7dcb44ba3 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:02 -0700 Subject: mtd: mtdswap: fix integer overflow Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/mtdswap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 0ec96cd5dc78..48cf6f98df44 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1474,7 +1474,7 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) } eblocks = mtd_div_by_eb(use_size, mtd); - use_size = eblocks * mtd->erasesize; + use_size = (uint64_t)eblocks * mtd->erasesize; bad_blocks = mtdswap_badblocks(mtd, use_size); eavailable = eblocks - bad_blocks; -- cgit v1.2.3 From 1001ff7a4f64f3f4264e69d3ed70ff428f627e01 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:12 -0700 Subject: mtd: tests: fix integer overflow issues These multiplications are done with 32-bit arithmetic, then converted to 64-bit. We should widen the integers first to prevent overflow. This could be a problem for large (>4GB) MTD's. Detected by Coverity. Signed-off-by: Brian Norris Cc: Akinobu Mita --- drivers/mtd/tests/mtd_test.c | 4 ++-- drivers/mtd/tests/nandbiterrs.c | 2 +- drivers/mtd/tests/oobtest.c | 8 ++++---- drivers/mtd/tests/pagetest.c | 4 ++-- drivers/mtd/tests/readtest.c | 2 +- drivers/mtd/tests/speedtest.c | 14 +++++++------- drivers/mtd/tests/subpagetest.c | 10 +++++----- 7 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/tests/mtd_test.c b/drivers/mtd/tests/mtd_test.c index 111ee46a7428..34736bbcc07b 100644 --- a/drivers/mtd/tests/mtd_test.c +++ b/drivers/mtd/tests/mtd_test.c @@ -10,7 +10,7 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) { int err; struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(&ei, 0, sizeof(struct erase_info)); ei.mtd = mtd; @@ -33,7 +33,7 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum) { int ret; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; ret = mtd_block_isbad(mtd, addr); if (ret) diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c index 6f976159611f..273f7e553954 100644 --- a/drivers/mtd/tests/nandbiterrs.c +++ b/drivers/mtd/tests/nandbiterrs.c @@ -364,7 +364,7 @@ static int __init mtd_nandbiterrs_init(void) pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize); - offset = page_offset * mtd->writesize; + offset = (loff_t)page_offset * mtd->writesize; eraseblock = mtd_div_by_eb(offset, mtd); pr_info("Using page=%u, offset=%llu, eraseblock=%u\n", diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index f19ab1acde1f..dc4f9602b97e 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -120,7 +120,7 @@ static int verify_eraseblock(int ebnum) int i; struct mtd_oob_ops ops; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { @@ -214,7 +214,7 @@ static int verify_eraseblock_in_one_go(int ebnum) { struct mtd_oob_ops ops; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; size_t len = mtd->ecclayout->oobavail * pgcnt; prandom_bytes_state(&rnd_state, writebuf, len); @@ -568,7 +568,7 @@ static int __init mtd_oobtest_init(void) size_t sz = mtd->ecclayout->oobavail; if (bbt[i] || bbt[i + 1]) continue; - addr = (i + 1) * mtd->erasesize - mtd->writesize; + addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; prandom_bytes_state(&rnd_state, writebuf, sz * cnt); for (pg = 0; pg < cnt; ++pg) { ops.mode = MTD_OPS_AUTO_OOB; @@ -598,7 +598,7 @@ static int __init mtd_oobtest_init(void) continue; prandom_bytes_state(&rnd_state, writebuf, mtd->ecclayout->oobavail * 2); - addr = (i + 1) * mtd->erasesize - mtd->writesize; + addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c index ed2d3f656fd2..88296e888e9d 100644 --- a/drivers/mtd/tests/pagetest.c +++ b/drivers/mtd/tests/pagetest.c @@ -52,7 +52,7 @@ static struct rnd_state rnd_state; static int write_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); cond_resched(); @@ -64,7 +64,7 @@ static int verify_eraseblock(int ebnum) uint32_t j; int err = 0, i; loff_t addr0, addrn; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; addr0 = 0; for (i = 0; i < ebcnt && bbt[i]; ++i) diff --git a/drivers/mtd/tests/readtest.c b/drivers/mtd/tests/readtest.c index 626e66d0f7e7..a54cf1511114 100644 --- a/drivers/mtd/tests/readtest.c +++ b/drivers/mtd/tests/readtest.c @@ -47,7 +47,7 @@ static int pgcnt; static int read_eraseblock_by_page(int ebnum) { int i, ret, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; void *oobbuf = iobuf1; diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c index 87ff6a29f84e..5ee9f7021020 100644 --- a/drivers/mtd/tests/speedtest.c +++ b/drivers/mtd/tests/speedtest.c @@ -55,7 +55,7 @@ static int multiblock_erase(int ebnum, int blocks) { int err; struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(&ei, 0, sizeof(struct erase_info)); ei.mtd = mtd; @@ -80,7 +80,7 @@ static int multiblock_erase(int ebnum, int blocks) static int write_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; return mtdtest_write(mtd, addr, mtd->erasesize, iobuf); } @@ -88,7 +88,7 @@ static int write_eraseblock(int ebnum) static int write_eraseblock_by_page(int ebnum) { int i, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { @@ -106,7 +106,7 @@ static int write_eraseblock_by_2pages(int ebnum) { size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { @@ -124,7 +124,7 @@ static int write_eraseblock_by_2pages(int ebnum) static int read_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; return mtdtest_read(mtd, addr, mtd->erasesize, iobuf); } @@ -132,7 +132,7 @@ static int read_eraseblock(int ebnum) static int read_eraseblock_by_page(int ebnum) { int i, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { @@ -150,7 +150,7 @@ static int read_eraseblock_by_2pages(int ebnum) { size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { diff --git a/drivers/mtd/tests/subpagetest.c b/drivers/mtd/tests/subpagetest.c index a876371ad410..7b59ef522d5e 100644 --- a/drivers/mtd/tests/subpagetest.c +++ b/drivers/mtd/tests/subpagetest.c @@ -57,7 +57,7 @@ static int write_eraseblock(int ebnum) { size_t written; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, subpgsize); err = mtd_write(mtd, addr, subpgsize, &written, writebuf); @@ -92,7 +92,7 @@ static int write_eraseblock2(int ebnum) { size_t written; int err = 0, k; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; for (k = 1; k < 33; ++k) { if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) @@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum) { size_t read; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, subpgsize); clear_data(readbuf, subpgsize); @@ -192,7 +192,7 @@ static int verify_eraseblock2(int ebnum) { size_t read; int err = 0, k; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; for (k = 1; k < 33; ++k) { if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) @@ -227,7 +227,7 @@ static int verify_eraseblock_ff(int ebnum) uint32_t j; size_t read; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(writebuf, 0xff, subpgsize); for (j = 0; j < mtd->erasesize / subpgsize; ++j) { -- cgit v1.2.3 From 31f754628cbb12c983600f22d9f0fed50dfe2134 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:22 -0700 Subject: mtd: use __packed shorthand Signed-off-by: Brian Norris --- drivers/mtd/mtdswap.c | 2 +- drivers/mtd/nand/sm_common.h | 2 +- include/linux/mtd/cfi.h | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 48cf6f98df44..fc8b3d16cce7 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -145,7 +145,7 @@ struct mtdswap_dev { struct mtdswap_oobdata { __le16 magic; __le32 count; -} __attribute__((packed)); +} __packed; #define MTDSWAP_MAGIC_CLEAN 0x2095 #define MTDSWAP_MAGIC_DIRTY (MTDSWAP_MAGIC_CLEAN + 1) diff --git a/drivers/mtd/nand/sm_common.h b/drivers/mtd/nand/sm_common.h index 00f4a83359b2..d3e028e58b0f 100644 --- a/drivers/mtd/nand/sm_common.h +++ b/drivers/mtd/nand/sm_common.h @@ -18,7 +18,7 @@ struct sm_oob { uint8_t ecc2[3]; uint8_t lba_copy2[2]; uint8_t ecc1[3]; -} __attribute__((packed)); +} __packed; /* one sector is always 512 bytes, but it can consist of two nand pages */ diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 37ef6b194089..299d7d31fe53 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -153,7 +153,7 @@ struct cfi_ident { uint16_t MaxBufWriteSize; uint8_t NumEraseRegions; uint32_t EraseRegionInfo[0]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; /* Extended Query Structure for both PRI and ALT */ @@ -161,7 +161,7 @@ struct cfi_extquery { uint8_t pri[3]; uint8_t MajorVersion; uint8_t MinorVersion; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ @@ -180,7 +180,7 @@ struct cfi_pri_intelext { uint8_t FactProtRegSize; uint8_t UserProtRegSize; uint8_t extra[0]; -} __attribute__((packed)); +} __packed; struct cfi_intelext_otpinfo { uint32_t ProtRegAddr; @@ -188,7 +188,7 @@ struct cfi_intelext_otpinfo { uint8_t FactProtRegSize; uint16_t UserGroups; uint8_t UserProtRegSize; -} __attribute__((packed)); +} __packed; struct cfi_intelext_blockinfo { uint16_t NumIdentBlocks; @@ -196,7 +196,7 @@ struct cfi_intelext_blockinfo { uint16_t MinBlockEraseCycles; uint8_t BitsPerCell; uint8_t BlockCap; -} __attribute__((packed)); +} __packed; struct cfi_intelext_regioninfo { uint16_t NumIdentPartitions; @@ -205,7 +205,7 @@ struct cfi_intelext_regioninfo { uint8_t NumOpAllowedSimEraMode; uint8_t NumBlockTypes; struct cfi_intelext_blockinfo BlockTypes[1]; -} __attribute__((packed)); +} __packed; struct cfi_intelext_programming_regioninfo { uint8_t ProgRegShift; @@ -214,7 +214,7 @@ struct cfi_intelext_programming_regioninfo { uint8_t Reserved2; uint8_t ControlInvalid; uint8_t Reserved3; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ @@ -233,7 +233,7 @@ struct cfi_pri_amdstd { uint8_t VppMin; uint8_t VppMax; uint8_t TopBottom; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for Atmel chips (command set 0x0002) */ @@ -245,18 +245,18 @@ struct cfi_pri_atmel { uint8_t BottomBoot; uint8_t BurstMode; uint8_t PageMode; -} __attribute__((packed)); +} __packed; struct cfi_pri_query { uint8_t NumFields; uint32_t ProtField[1]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; struct cfi_bri_query { uint8_t PageModeReadCap; uint8_t NumFields; uint32_t ConfField[1]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; #define P_ID_NONE 0x0000 #define P_ID_INTEL_EXT 0x0001 -- cgit v1.2.3 From c115add9d073752d38f6517882dfeafe76fc4458 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:31 -0700 Subject: mtd: nand: denali: set proper error code on timeout The condition "if (irq_status == 0)" already ensures that one half of the ternary ?: is dead. I think this should probably actually be a FAIL, not a PASS. Caught by Coverity. Signed-off-by: Brian Norris Cc: Jamie Iles --- drivers/mtd/nand/denali.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index da0fcc224739..4885a0f573cd 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1062,9 +1062,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, dev_err(denali->dev, "timeout on write_page (type = %d)\n", raw_xfer); - denali->status = - (irq_status & INTR_STATUS__PROGRAM_FAIL) ? - NAND_STATUS_FAIL : PASS; + denali->status = NAND_STATUS_FAIL; } denali_enable_dma(denali, false); -- cgit v1.2.3 From b033e1aac9afd314add799b6cd2a5489f892757f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:44 -0700 Subject: mtd: nandsim: fix integer widening This multiplication should be done in 64-bit, not 32-bit. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/nand/nandsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 4f0d83648e5a..7dc1dd28d896 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -827,7 +827,7 @@ static int parse_badblocks(struct nandsim *ns, struct mtd_info *mtd) NS_ERR("invalid badblocks.\n"); return -EINVAL; } - offset = erase_block_no * ns->geom.secsz; + offset = (loff_t)erase_block_no * ns->geom.secsz; if (mtd_block_markbad(mtd, offset)) { NS_ERR("invalid badblocks.\n"); return -EINVAL; -- cgit v1.2.3 From 7a6f43958a53020f85818ff5c895623e88781fd6 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:56 -0700 Subject: mtd: maps: solutionengine: drop excess dependency Already depends on SOLUTION_ENGINE, so we don't need the SUPERH dependency too. Signed-off-by: Brian Norris --- drivers/mtd/maps/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 21b2874a303b..ba801d2c6dcc 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -249,7 +249,7 @@ config MTD_CFI_FLAGADM config MTD_SOLUTIONENGINE tristate "CFI Flash device mapped on Hitachi SolutionEngine" - depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS + depends on SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS help This enables access to the flash chips on the Hitachi SolutionEngine and similar boards. Say 'Y' if you are building a kernel for such a board. -- cgit v1.2.3 From 537ab1bd47d6518e8a40207a80dd0c2c4bc43aed Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:08:03 -0700 Subject: mtd: nand: fix integer widening problems chip->pagebuf is a 32-bit type (int), so the shift will only be applied as 32-bit. Fix this for 64-bit safety. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1a27c2da29ff..ae6e7c47f8e2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2409,8 +2409,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, 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)) + if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && + ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; /* Don't allow multipage oob writes with offset */ -- cgit v1.2.3 From 1cc8d8413327a684cd5e93cd52ececb0223bb40b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:08:13 -0700 Subject: mtd: terminate user-provided string Noticed by Coverity as a potential security issue. Signed-off-by: Brian Norris --- drivers/mtd/mtdchar.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/mtd') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index a0f54e80670c..53563955931b 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -549,6 +549,9 @@ static int mtdchar_blkpg_ioctl(struct mtd_info *mtd, if (mtd_is_partition(mtd)) return -EINVAL; + /* Sanitize user input */ + p.devname[BLKPG_DEVNAMELTH - 1] = '\0'; + return mtd_add_partition(mtd, p.devname, p.start, p.length); case BLKPG_DEL_PARTITION: -- cgit v1.2.3 From ff0a215438cf7be0a652cb3457f562539bd40b22 Mon Sep 17 00:00:00 2001 From: Wu, Josh Date: Tue, 5 Aug 2014 18:38:52 +0800 Subject: mtd: atmel_nand: NFC: fix mtd_nandbiterrs.ko test fail when using sram write When enable NFC sram write, it will failed the mtd_nandbiterrs.ko test. As in driver's nfc_sram_write_page(), if ops->mode equal to MTD_OSP_RAW, driver assumes the data buffer contains one page data and one oob data followed. And driver will write the page data and oob data to nand. But this is wrong implementation. Since the data buffer don't contains the oob data to write. We should write the chip->oob_poi to nand's oob. So this patch fix it by writing the oob data from chip->oob_poi. Signed-off-by: Josh Wu Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 0abc965caedf..9c5f717bda54 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1907,15 +1907,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (offset || (data_len < mtd->writesize)) return -EINVAL; - cfg = nfc_readl(host->nfc->hsmc_regs, CFG); len = mtd->writesize; - - if (unlikely(raw)) { - len += mtd->oobsize; - nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); - } else - nfc_writel(host->nfc->hsmc_regs, CFG, cfg & ~NFC_CFG_WSPARE); - /* Copy page data to sram that will write to nand via NFC */ if (use_dma) { if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) != 0) @@ -1925,6 +1917,15 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, memcpy32_toio(sram, buf, len); } + cfg = nfc_readl(host->nfc->hsmc_regs, CFG); + if (unlikely(raw) && oob_required) { + memcpy32_toio(sram + len, chip->oob_poi, mtd->oobsize); + len += mtd->oobsize; + nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); + } else { + nfc_writel(host->nfc->hsmc_regs, CFG, cfg & ~NFC_CFG_WSPARE); + } + if (chip->ecc.mode == NAND_ECC_HW && host->has_pmecc) /* * When use NFC sram, need set up PMECC before send -- cgit v1.2.3 From bd8898db3e03147d9d7ddd48876fb3f3bcbab6c1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 9 Aug 2014 19:07:53 +0200 Subject: mtd: nand: Use ULL-suffix for big u64 constant drivers/mtd/nand/nand_timings.c:45: warning: integer constant is too large for ‘long’ type [ Editorial note: This is a false warning. Looking at ISO draft N1124 (this is approximately C11, the first PDF I had lying around), section 6.4.4.1 (statement 5): "The type of an integer constant is the first of the corresponding list in which its value can be represented." So this should not be an overflow, and any toolchain that says so (e.g., GCC 4.4) is buggy. -Brian ] Signed-off-by: Geert Uytterhoeven Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_timings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c index 8b36253420fa..e81470a8ac67 100644 --- a/drivers/mtd/nand/nand_timings.c +++ b/drivers/mtd/nand/nand_timings.c @@ -42,7 +42,7 @@ static const struct nand_sdr_timings onfi_sdr_timings[] = { .tRHZ_max = 200000, .tRLOH_min = 0, .tRP_min = 50000, - .tRST_max = 250000000000, + .tRST_max = 250000000000ULL, .tWB_max = 200000, .tRR_min = 40000, .tWC_min = 100000, -- cgit v1.2.3 From 02f8a24e7b1c253ee37edc684200c11300de23f9 Mon Sep 17 00:00:00 2001 From: Aaron Wu Date: Thu, 7 Aug 2014 11:43:49 +0800 Subject: mtd: gpio_flash: handle case where offset + len exceeds the window size Fix the bug in handling gpio flash read/write when offset + len from MTD exceeds the window size Signed-off-by: Aaron Wu [Brian: made some commentary edits. Also note that the BUG_ON() was provably false for all non-negative inputs (since x % y <= x), so we dropped it.] Signed-off-by: Brian Norris --- drivers/mtd/maps/gpio-addr-flash.c | 42 +++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index a4c477b9fdd6..2fb346091af2 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c @@ -99,22 +99,28 @@ static map_word gf_read(struct map_info *map, unsigned long ofs) * @from: flash offset to copy from * @len: how much to copy * - * We rely on the MTD layer to chunk up copies such that a single request here - * will not cross a window size. This allows us to only wiggle the GPIOs once - * before falling back to a normal memcpy. Reading the higher layer code shows - * that this is indeed the case, but add a BUG_ON() to future proof. + * The "from" region may straddle more than one window, so toggle the GPIOs for + * each window region before reading its data. */ static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { struct async_state *state = gf_map_info_to_state(map); - gf_set_gpios(state, from); + int this_len; - /* BUG if operation crosses the win_size */ - BUG_ON(!((from + len) % state->win_size <= (from + len))); + while (len) { + if ((from % state->win_size) + len > state->win_size) + this_len = state->win_size - (from % state->win_size); + else + this_len = len; - /* operation does not cross the win_size, so one shot it */ - memcpy_fromio(to, map->virt + (from % state->win_size), len); + gf_set_gpios(state, from); + memcpy_fromio(to, map->virt + (from % state->win_size), + this_len); + len -= this_len; + from += this_len; + to += this_len; + } } /** @@ -147,13 +153,21 @@ static void gf_copy_to(struct map_info *map, unsigned long to, { struct async_state *state = gf_map_info_to_state(map); - gf_set_gpios(state, to); + int this_len; + + while (len) { + if ((to % state->win_size) + len > state->win_size) + this_len = state->win_size - (to % state->win_size); + else + this_len = len; - /* BUG if operation crosses the win_size */ - BUG_ON(!((to + len) % state->win_size <= (to + len))); + gf_set_gpios(state, to); + memcpy_toio(map->virt + (to % state->win_size), from, len); - /* operation does not cross the win_size, so one shot it */ - memcpy_toio(map->virt + (to % state->win_size), from, len); + len -= this_len; + to += this_len; + from += this_len; + } } static const char * const part_probe_types[] = { -- cgit v1.2.3 From ab75e89c013d8fff8bd8a6e520d184c3da1a4583 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Aug 2014 09:47:01 +0200 Subject: mtd: spi-nor: remove duplicated w25q128 entry Signed-off-by: Rafał Miłecki Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 4dc0c8662265..2fea172dd530 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -624,7 +624,6 @@ const struct spi_device_id spi_nor_ids[] = { { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -- cgit v1.2.3 From 54ea17a597b00e46b3720e75dd7595cd5dfa5670 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 7 Aug 2014 09:47:02 +0200 Subject: mtd: spi-nor: drop jedec_probe /helper/ function It's a one-liner doing no magic and its name may be confusing because it does not have to use JEDEC (e.g. when using alternative read_id). Signed-off-by: Rafał Miłecki Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 2fea172dd530..03e0ab8b2086 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -671,11 +671,6 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) return ERR_PTR(-ENODEV); } -static const struct spi_device_id *jedec_probe(struct spi_nor *nor) -{ - return nor->read_id(nor); -} - static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { @@ -958,7 +953,7 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, if (info->jedec_id) { const struct spi_device_id *jid; - jid = jedec_probe(nor); + jid = nor->read_id(nor); if (IS_ERR(jid)) { return PTR_ERR(jid); } else if (jid != id) { -- cgit v1.2.3