LCOV - code coverage report
Current view: top level - include/linux/mtd - map.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 37 0.0 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 0 362 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright © 2000-2010 David Woodhouse <dwmw2@infradead.org> et al.
       3                 :            :  *
       4                 :            :  * This program is free software; you can redistribute it and/or modify
       5                 :            :  * it under the terms of the GNU General Public License as published by
       6                 :            :  * the Free Software Foundation; either version 2 of the License, or
       7                 :            :  * (at your option) any later version.
       8                 :            :  *
       9                 :            :  * This program is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            :  * GNU General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU General Public License
      15                 :            :  * along with this program; if not, write to the Free Software
      16                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      17                 :            :  *
      18                 :            :  */
      19                 :            : 
      20                 :            : /* Overhauled routines for dealing with different mmap regions of flash */
      21                 :            : 
      22                 :            : #ifndef __LINUX_MTD_MAP_H__
      23                 :            : #define __LINUX_MTD_MAP_H__
      24                 :            : 
      25                 :            : #include <linux/types.h>
      26                 :            : #include <linux/list.h>
      27                 :            : #include <linux/string.h>
      28                 :            : #include <linux/bug.h>
      29                 :            : #include <linux/kernel.h>
      30                 :            : 
      31                 :            : #include <asm/unaligned.h>
      32                 :            : #include <asm/io.h>
      33                 :            : #include <asm/barrier.h>
      34                 :            : 
      35                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
      36                 :            : #define map_bankwidth(map) 1
      37                 :            : #define map_bankwidth_is_1(map) (map_bankwidth(map) == 1)
      38                 :            : #define map_bankwidth_is_large(map) (0)
      39                 :            : #define map_words(map) (1)
      40                 :            : #define MAX_MAP_BANKWIDTH 1
      41                 :            : #else
      42                 :            : #define map_bankwidth_is_1(map) (0)
      43                 :            : #endif
      44                 :            : 
      45                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
      46                 :            : # ifdef map_bankwidth
      47                 :            : #  undef map_bankwidth
      48                 :            : #  define map_bankwidth(map) ((map)->bankwidth)
      49                 :            : # else
      50                 :            : #  define map_bankwidth(map) 2
      51                 :            : #  define map_bankwidth_is_large(map) (0)
      52                 :            : #  define map_words(map) (1)
      53                 :            : # endif
      54                 :            : #define map_bankwidth_is_2(map) (map_bankwidth(map) == 2)
      55                 :            : #undef MAX_MAP_BANKWIDTH
      56                 :            : #define MAX_MAP_BANKWIDTH 2
      57                 :            : #else
      58                 :            : #define map_bankwidth_is_2(map) (0)
      59                 :            : #endif
      60                 :            : 
      61                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
      62                 :            : # ifdef map_bankwidth
      63                 :            : #  undef map_bankwidth
      64                 :            : #  define map_bankwidth(map) ((map)->bankwidth)
      65                 :            : # else
      66                 :            : #  define map_bankwidth(map) 4
      67                 :            : #  define map_bankwidth_is_large(map) (0)
      68                 :            : #  define map_words(map) (1)
      69                 :            : # endif
      70                 :            : #define map_bankwidth_is_4(map) (map_bankwidth(map) == 4)
      71                 :            : #undef MAX_MAP_BANKWIDTH
      72                 :            : #define MAX_MAP_BANKWIDTH 4
      73                 :            : #else
      74                 :            : #define map_bankwidth_is_4(map) (0)
      75                 :            : #endif
      76                 :            : 
      77                 :            : /* ensure we never evaluate anything shorted than an unsigned long
      78                 :            :  * to zero, and ensure we'll never miss the end of an comparison (bjd) */
      79                 :            : 
      80                 :            : #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long))
      81                 :            : 
      82                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
      83                 :            : # ifdef map_bankwidth
      84                 :            : #  undef map_bankwidth
      85                 :            : #  define map_bankwidth(map) ((map)->bankwidth)
      86                 :            : #  if BITS_PER_LONG < 64
      87                 :            : #   undef map_bankwidth_is_large
      88                 :            : #   define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
      89                 :            : #   undef map_words
      90                 :            : #   define map_words(map) map_calc_words(map)
      91                 :            : #  endif
      92                 :            : # else
      93                 :            : #  define map_bankwidth(map) 8
      94                 :            : #  define map_bankwidth_is_large(map) (BITS_PER_LONG < 64)
      95                 :            : #  define map_words(map) map_calc_words(map)
      96                 :            : # endif
      97                 :            : #define map_bankwidth_is_8(map) (map_bankwidth(map) == 8)
      98                 :            : #undef MAX_MAP_BANKWIDTH
      99                 :            : #define MAX_MAP_BANKWIDTH 8
     100                 :            : #else
     101                 :            : #define map_bankwidth_is_8(map) (0)
     102                 :            : #endif
     103                 :            : 
     104                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
     105                 :            : # ifdef map_bankwidth
     106                 :            : #  undef map_bankwidth
     107                 :            : #  define map_bankwidth(map) ((map)->bankwidth)
     108                 :            : #  undef map_bankwidth_is_large
     109                 :            : #  define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
     110                 :            : #  undef map_words
     111                 :            : #  define map_words(map) map_calc_words(map)
     112                 :            : # else
     113                 :            : #  define map_bankwidth(map) 16
     114                 :            : #  define map_bankwidth_is_large(map) (1)
     115                 :            : #  define map_words(map) map_calc_words(map)
     116                 :            : # endif
     117                 :            : #define map_bankwidth_is_16(map) (map_bankwidth(map) == 16)
     118                 :            : #undef MAX_MAP_BANKWIDTH
     119                 :            : #define MAX_MAP_BANKWIDTH 16
     120                 :            : #else
     121                 :            : #define map_bankwidth_is_16(map) (0)
     122                 :            : #endif
     123                 :            : 
     124                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
     125                 :            : # ifdef map_bankwidth
     126                 :            : #  undef map_bankwidth
     127                 :            : #  define map_bankwidth(map) ((map)->bankwidth)
     128                 :            : #  undef map_bankwidth_is_large
     129                 :            : #  define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
     130                 :            : #  undef map_words
     131                 :            : #  define map_words(map) map_calc_words(map)
     132                 :            : # else
     133                 :            : #  define map_bankwidth(map) 32
     134                 :            : #  define map_bankwidth_is_large(map) (1)
     135                 :            : #  define map_words(map) map_calc_words(map)
     136                 :            : # endif
     137                 :            : #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
     138                 :            : #undef MAX_MAP_BANKWIDTH
     139                 :            : #define MAX_MAP_BANKWIDTH 32
     140                 :            : #else
     141                 :            : #define map_bankwidth_is_32(map) (0)
     142                 :            : #endif
     143                 :            : 
     144                 :            : #ifndef map_bankwidth
     145                 :            : #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work"
     146                 :            : static inline int map_bankwidth(void *map)
     147                 :            : {
     148                 :            :         BUG();
     149                 :            :         return 0;
     150                 :            : }
     151                 :            : #define map_bankwidth_is_large(map) (0)
     152                 :            : #define map_words(map) (0)
     153                 :            : #define MAX_MAP_BANKWIDTH 1
     154                 :            : #endif
     155                 :            : 
     156                 :            : static inline int map_bankwidth_supported(int w)
     157                 :            : {
     158                 :            :         switch (w) {
     159                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
     160                 :            :         case 1:
     161                 :            : #endif
     162                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
     163                 :            :         case 2:
     164                 :            : #endif
     165                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
     166                 :            :         case 4:
     167                 :            : #endif
     168                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
     169                 :            :         case 8:
     170                 :            : #endif
     171                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
     172                 :            :         case 16:
     173                 :            : #endif
     174                 :            : #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
     175                 :            :         case 32:
     176                 :            : #endif
     177                 :            :                 return 1;
     178                 :            : 
     179                 :            :         default:
     180                 :            :                 return 0;
     181                 :            :         }
     182                 :            : }
     183                 :            : 
     184                 :            : #define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG )
     185                 :            : 
     186                 :            : typedef union {
     187                 :            :         unsigned long x[MAX_MAP_LONGS];
     188                 :            : } map_word;
     189                 :            : 
     190                 :            : /* The map stuff is very simple. You fill in your struct map_info with
     191                 :            :    a handful of routines for accessing the device, making sure they handle
     192                 :            :    paging etc. correctly if your device needs it. Then you pass it off
     193                 :            :    to a chip probe routine -- either JEDEC or CFI probe or both -- via
     194                 :            :    do_map_probe(). If a chip is recognised, the probe code will invoke the
     195                 :            :    appropriate chip driver (if present) and return a struct mtd_info.
     196                 :            :    At which point, you fill in the mtd->module with your own module
     197                 :            :    address, and register it with the MTD core code. Or you could partition
     198                 :            :    it and register the partitions instead, or keep it for your own private
     199                 :            :    use; whatever.
     200                 :            : 
     201                 :            :    The mtd->priv field will point to the struct map_info, and any further
     202                 :            :    private data required by the chip driver is linked from the
     203                 :            :    mtd->priv->fldrv_priv field. This allows the map driver to get at
     204                 :            :    the destructor function map->fldrv_destroy() when it's tired
     205                 :            :    of living.
     206                 :            : */
     207                 :            : 
     208                 :            : struct map_info {
     209                 :            :         const char *name;
     210                 :            :         unsigned long size;
     211                 :            :         resource_size_t phys;
     212                 :            : #define NO_XIP (-1UL)
     213                 :            : 
     214                 :            :         void __iomem *virt;
     215                 :            :         void *cached;
     216                 :            : 
     217                 :            :         int swap; /* this mapping's byte-swapping requirement */
     218                 :            :         int bankwidth; /* in octets. This isn't necessarily the width
     219                 :            :                        of actual bus cycles -- it's the repeat interval
     220                 :            :                       in bytes, before you are talking to the first chip again.
     221                 :            :                       */
     222                 :            : 
     223                 :            : #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
     224                 :            :         map_word (*read)(struct map_info *, unsigned long);
     225                 :            :         void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
     226                 :            : 
     227                 :            :         void (*write)(struct map_info *, const map_word, unsigned long);
     228                 :            :         void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
     229                 :            : 
     230                 :            :         /* We can perhaps put in 'point' and 'unpoint' methods, if we really
     231                 :            :            want to enable XIP for non-linear mappings. Not yet though. */
     232                 :            : #endif
     233                 :            :         /* It's possible for the map driver to use cached memory in its
     234                 :            :            copy_from implementation (and _only_ with copy_from).  However,
     235                 :            :            when the chip driver knows some flash area has changed contents,
     236                 :            :            it will signal it to the map driver through this routine to let
     237                 :            :            the map driver invalidate the corresponding cache as needed.
     238                 :            :            If there is no cache to care about this can be set to NULL. */
     239                 :            :         void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
     240                 :            : 
     241                 :            :         /* set_vpp() must handle being reentered -- enable, enable, disable
     242                 :            :            must leave it enabled. */
     243                 :            :         void (*set_vpp)(struct map_info *, int);
     244                 :            : 
     245                 :            :         unsigned long pfow_base;
     246                 :            :         unsigned long map_priv_1;
     247                 :            :         unsigned long map_priv_2;
     248                 :            :         struct device_node *device_node;
     249                 :            :         void *fldrv_priv;
     250                 :            :         struct mtd_chip_driver *fldrv;
     251                 :            : };
     252                 :            : 
     253                 :            : struct mtd_chip_driver {
     254                 :            :         struct mtd_info *(*probe)(struct map_info *map);
     255                 :            :         void (*destroy)(struct mtd_info *);
     256                 :            :         struct module *module;
     257                 :            :         char *name;
     258                 :            :         struct list_head list;
     259                 :            : };
     260                 :            : 
     261                 :            : void register_mtd_chip_driver(struct mtd_chip_driver *);
     262                 :            : void unregister_mtd_chip_driver(struct mtd_chip_driver *);
     263                 :            : 
     264                 :            : struct mtd_info *do_map_probe(const char *name, struct map_info *map);
     265                 :            : void map_destroy(struct mtd_info *mtd);
     266                 :            : 
     267                 :            : #define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
     268                 :            : #define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
     269                 :            : 
     270                 :            : #define INVALIDATE_CACHED_RANGE(map, from, size) \
     271                 :            :         do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
     272                 :            : 
     273                 :            : 
     274                 :            : static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
     275                 :            : {
     276                 :            :         int i;
     277 [ #  # ][ #  # ]:          0 :         for (i=0; i<map_words(map); i++) {
         [ #  # ][ #  # ]
     278 [ #  # ][ #  # ]:          0 :                 if (val1.x[i] != val2.x[i])
         [ #  # ][ #  # ]
     279                 :            :                         return 0;
     280                 :            :         }
     281                 :            :         return 1;
     282                 :            : }
     283                 :            : 
     284                 :            : static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
     285                 :            : {
     286                 :            :         map_word r;
     287                 :            :         int i;
     288                 :            : 
     289 [ #  # ][ #  # ]:          0 :         for (i=0; i<map_words(map); i++) {
         [ #  # ][ #  # ]
     290                 :          0 :                 r.x[i] = val1.x[i] & val2.x[i];
     291                 :            :         }
     292                 :            :         return r;
     293                 :            : }
     294                 :            : 
     295                 :            : static inline map_word map_word_clr(struct map_info *map, map_word val1, map_word val2)
     296                 :            : {
     297                 :            :         map_word r;
     298                 :            :         int i;
     299                 :            : 
     300                 :            :         for (i=0; i<map_words(map); i++) {
     301                 :            :                 r.x[i] = val1.x[i] & ~val2.x[i];
     302                 :            :         }
     303                 :            :         return r;
     304                 :            : }
     305                 :            : 
     306                 :            : static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
     307                 :            : {
     308                 :            :         map_word r;
     309                 :            :         int i;
     310                 :            : 
     311                 :            :         for (i=0; i<map_words(map); i++) {
     312                 :            :                 r.x[i] = val1.x[i] | val2.x[i];
     313                 :            :         }
     314                 :            :         return r;
     315                 :            : }
     316                 :            : 
     317                 :            : #define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
     318                 :            : 
     319                 :            : static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
     320                 :            : {
     321                 :            :         int i;
     322                 :            : 
     323 [ #  # ][ #  # ]:          0 :         for (i=0; i<map_words(map); i++) {
         [ #  # ][ #  # ]
     324 [ #  # ][ #  # ]:          0 :                 if (val1.x[i] & val2.x[i])
         [ #  # ][ #  # ]
     325                 :            :                         return 1;
     326                 :            :         }
     327                 :            :         return 0;
     328                 :            : }
     329                 :            : 
     330                 :            : static inline map_word map_word_load(struct map_info *map, const void *ptr)
     331                 :            : {
     332                 :            :         map_word r;
     333                 :            : 
     334         [ #  # ]:          0 :         if (map_bankwidth_is_1(map))
     335                 :          0 :                 r.x[0] = *(unsigned char *)ptr;
     336         [ #  # ]:          0 :         else if (map_bankwidth_is_2(map))
     337                 :          0 :                 r.x[0] = get_unaligned((uint16_t *)ptr);
     338         [ #  # ]:          0 :         else if (map_bankwidth_is_4(map))
     339                 :            :                 r.x[0] = get_unaligned((uint32_t *)ptr);
     340                 :            : #if BITS_PER_LONG >= 64
     341                 :            :         else if (map_bankwidth_is_8(map))
     342                 :            :                 r.x[0] = get_unaligned((uint64_t *)ptr);
     343                 :            : #endif
     344                 :            :         else if (map_bankwidth_is_large(map))
     345                 :            :                 memcpy(r.x, ptr, map->bankwidth);
     346                 :            :         else
     347                 :          0 :                 BUG();
     348                 :            : 
     349                 :            :         return r;
     350                 :            : }
     351                 :            : 
     352                 :            : static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
     353                 :            : {
     354                 :            :         int i;
     355                 :            : 
     356                 :            :         if (map_bankwidth_is_large(map)) {
     357                 :            :                 char *dest = (char *)&orig;
     358                 :            :                 memcpy(dest+start, buf, len);
     359                 :            :         } else {
     360 [ #  # ][ #  # ]:          0 :                 for (i=start; i < start+len; i++) {
                 [ #  # ]
     361                 :            :                         int bitpos;
     362                 :            : #ifdef __LITTLE_ENDIAN
     363                 :          0 :                         bitpos = i*8;
     364                 :            : #else /* __BIG_ENDIAN */
     365                 :            :                         bitpos = (map_bankwidth(map)-1-i)*8;
     366                 :            : #endif
     367                 :          0 :                         orig.x[0] &= ~(0xff << bitpos);
     368                 :          0 :                         orig.x[0] |= (unsigned long)buf[i-start] << bitpos;
     369                 :            :                 }
     370                 :            :         }
     371                 :            :         return orig;
     372                 :            : }
     373                 :            : 
     374                 :            : #if BITS_PER_LONG < 64
     375                 :            : #define MAP_FF_LIMIT 4
     376                 :            : #else
     377                 :            : #define MAP_FF_LIMIT 8
     378                 :            : #endif
     379                 :            : 
     380                 :            : static inline map_word map_word_ff(struct map_info *map)
     381                 :            : {
     382                 :            :         map_word r;
     383                 :            :         int i;
     384                 :            : 
     385 [ #  # ][ #  # ]:          0 :         if (map_bankwidth(map) < MAP_FF_LIMIT) {
         [ #  # ][ #  # ]
     386                 :          0 :                 int bw = 8 * map_bankwidth(map);
     387                 :          0 :                 r.x[0] = (1UL << bw) - 1;
     388                 :            :         } else {
     389                 :            :                 for (i=0; i<map_words(map); i++)
     390                 :            :                         r.x[i] = ~0UL;
     391                 :            :         }
     392                 :            :         return r;
     393                 :            : }
     394                 :            : 
     395                 :            : static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
     396                 :            : {
     397                 :            :         map_word r;
     398                 :            : 
     399 [ #  # ][ #  # ]:          0 :         if (map_bankwidth_is_1(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     400                 :          0 :                 r.x[0] = readb_relaxed(map->virt + ofs);
     401 [ #  # ][ #  # ]:          0 :         else if (map_bankwidth_is_2(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     402                 :          0 :                 r.x[0] = readw_relaxed(map->virt + ofs);
     403 [ #  # ][ #  # ]:          0 :         else if (map_bankwidth_is_4(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     404                 :          0 :                 r.x[0] = readl_relaxed(map->virt + ofs);
     405                 :            : #if BITS_PER_LONG >= 64
     406                 :            :         else if (map_bankwidth_is_8(map))
     407                 :            :                 r.x[0] = __raw_readq(map->virt + ofs);
     408                 :            : #endif
     409                 :            :         else if (map_bankwidth_is_large(map))
     410                 :            :                 memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
     411                 :            :         else
     412                 :          0 :                 BUG();
     413                 :            : 
     414                 :            :         return r;
     415                 :            : }
     416                 :            : 
     417                 :            : static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
     418                 :            : {
     419 [ #  # ][ #  # ]:          0 :         if (map_bankwidth_is_1(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     420                 :          0 :                 writeb_relaxed(datum.x[0], map->virt + ofs);
     421 [ #  # ][ #  # ]:          0 :         else if (map_bankwidth_is_2(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     422                 :          0 :                 writew_relaxed(datum.x[0], map->virt + ofs);
     423 [ #  # ][ #  # ]:          0 :         else if (map_bankwidth_is_4(map))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     424                 :          0 :                 writel_relaxed(datum.x[0], map->virt + ofs);
     425                 :            : #if BITS_PER_LONG >= 64
     426                 :            :         else if (map_bankwidth_is_8(map))
     427                 :            :                 __raw_writeq(datum.x[0], map->virt + ofs);
     428                 :            : #endif
     429                 :            :         else if (map_bankwidth_is_large(map))
     430                 :            :                 memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
     431                 :            :         else
     432                 :          0 :                 BUG();
     433                 :          0 :         mb();
     434                 :            : }
     435                 :            : 
     436                 :            : static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
     437                 :            : {
     438         [ #  # ]:          0 :         if (map->cached)
     439                 :          0 :                 memcpy(to, (char *)map->cached + from, len);
     440                 :            :         else
     441                 :          0 :                 memcpy_fromio(to, map->virt + from, len);
     442                 :            : }
     443                 :            : 
     444                 :            : static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
     445                 :            : {
     446                 :            :         memcpy_toio(map->virt + to, from, len);
     447                 :            : }
     448                 :            : 
     449                 :            : #ifdef CONFIG_MTD_COMPLEX_MAPPINGS
     450                 :            : #define map_read(map, ofs) (map)->read(map, ofs)
     451                 :            : #define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
     452                 :            : #define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
     453                 :            : #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
     454                 :            : 
     455                 :            : extern void simple_map_init(struct map_info *);
     456                 :            : #define map_is_linear(map) (map->phys != NO_XIP)
     457                 :            : 
     458                 :            : #else
     459                 :            : #define map_read(map, ofs) inline_map_read(map, ofs)
     460                 :            : #define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
     461                 :            : #define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
     462                 :            : #define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
     463                 :            : 
     464                 :            : 
     465                 :            : #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
     466                 :            : #define map_is_linear(map) ({ (void)(map); 1; })
     467                 :            : 
     468                 :            : #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
     469                 :            : 
     470                 :            : #endif /* __LINUX_MTD_MAP_H__ */

Generated by: LCOV version 1.9