@@ -2025,35 +2025,6 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
20252025 * Serial Flash Discoverable Parameters (SFDP) parsing.
20262026 */
20272027
2028- /**
2029- * spi_nor_read_raw() - raw read of serial flash memory. read_opcode,
2030- * addr_width and read_dummy members of the struct spi_nor should be previously
2031- * set.
2032- * @nor: pointer to a 'struct spi_nor'
2033- * @addr: offset in the serial flash memory
2034- * @len: number of bytes to read
2035- * @buf: buffer where the data is copied into
2036- *
2037- * Return: 0 on success, -errno otherwise.
2038- */
2039- static int spi_nor_read_raw (struct spi_nor * nor , u32 addr , size_t len , u8 * buf )
2040- {
2041- int ret ;
2042-
2043- while (len ) {
2044- ret = nor -> read (nor , addr , len , buf );
2045- if (!ret || ret > len )
2046- return - EIO ;
2047- if (ret < 0 )
2048- return ret ;
2049-
2050- buf += ret ;
2051- addr += ret ;
2052- len -= ret ;
2053- }
2054- return 0 ;
2055- }
2056-
20572028/**
20582029 * spi_nor_read_sfdp() - read Serial Flash Discoverable Parameters.
20592030 * @nor: pointer to a 'struct spi_nor'
@@ -2081,8 +2052,22 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr,
20812052 nor -> addr_width = 3 ;
20822053 nor -> read_dummy = 8 ;
20832054
2084- ret = spi_nor_read_raw (nor , addr , len , buf );
2055+ while (len ) {
2056+ ret = nor -> read (nor , addr , len , (u8 * )buf );
2057+ if (!ret || ret > len ) {
2058+ ret = - EIO ;
2059+ goto read_err ;
2060+ }
2061+ if (ret < 0 )
2062+ goto read_err ;
20852063
2064+ buf += ret ;
2065+ addr += ret ;
2066+ len -= ret ;
2067+ }
2068+ ret = 0 ;
2069+
2070+ read_err :
20862071 nor -> read_opcode = read_opcode ;
20872072 nor -> addr_width = addr_width ;
20882073 nor -> read_dummy = read_dummy ;
@@ -2602,228 +2587,6 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
26022587 return 0 ;
26032588}
26042589
2605- #define SMPT_CMD_ADDRESS_LEN_MASK GENMASK(23, 22)
2606- #define SMPT_CMD_ADDRESS_LEN_0 (0x0UL << 22)
2607- #define SMPT_CMD_ADDRESS_LEN_3 (0x1UL << 22)
2608- #define SMPT_CMD_ADDRESS_LEN_4 (0x2UL << 22)
2609- #define SMPT_CMD_ADDRESS_LEN_USE_CURRENT (0x3UL << 22)
2610-
2611- #define SMPT_CMD_READ_DUMMY_MASK GENMASK(19, 16)
2612- #define SMPT_CMD_READ_DUMMY_SHIFT 16
2613- #define SMPT_CMD_READ_DUMMY (_cmd ) \
2614- ((_cmd & SMPT_CMD_READ_DUMMY_MASK) >> SMPT_CMD_READ_DUMMY_SHIFT)
2615- #define SMPT_CMD_READ_DUMMY_IS_VARIABLE 0xfUL
2616-
2617- #define SMPT_CMD_READ_DATA_MASK GENMASK(31, 24)
2618- #define SMPT_CMD_READ_DATA_SHIFT 24
2619- #define SMPT_CMD_READ_DATA (_cmd ) \
2620- ((_cmd & SMPT_CMD_READ_DATA_MASK) >> SMPT_CMD_READ_DATA_SHIFT)
2621-
2622- #define SMPT_CMD_OPCODE_MASK GENMASK(15, 8)
2623- #define SMPT_CMD_OPCODE_SHIFT 8
2624- #define SMPT_CMD_OPCODE (_cmd ) \
2625- ((_cmd & SMPT_CMD_OPCODE_MASK) >> SMPT_CMD_OPCODE_SHIFT)
2626-
2627- #define SMPT_MAP_REGION_COUNT_MASK GENMASK(23, 16)
2628- #define SMPT_MAP_REGION_COUNT_SHIFT 16
2629- #define SMPT_MAP_REGION_COUNT (_header ) \
2630- (((_header & SMPT_MAP_REGION_COUNT_MASK) >> \
2631- SMPT_MAP_REGION_COUNT_SHIFT) + 1)
2632-
2633- #define SMPT_MAP_ID_MASK GENMASK(15, 8)
2634- #define SMPT_MAP_ID_SHIFT 8
2635- #define SMPT_MAP_ID (_header ) ((_header & SMPT_MAP_ID_MASK) >> SMPT_MAP_ID_SHIFT)
2636-
2637- #define SMPT_MAP_REGION_SIZE_MASK GENMASK(31, 8)
2638- #define SMPT_MAP_REGION_SIZE_SHIFT 8
2639- #define SMPT_MAP_REGION_SIZE (_region ) \
2640- ((((_region & SMPT_MAP_REGION_SIZE_MASK) >> \
2641- SMPT_MAP_REGION_SIZE_SHIFT) + 1) * 256)
2642-
2643- #define SMPT_MAP_REGION_ERASE_TYPE_MASK GENMASK(3, 0)
2644- #define SMPT_MAP_REGION_ERASE_TYPE (_region ) \
2645- (_region & SMPT_MAP_REGION_ERASE_TYPE_MASK)
2646-
2647- #define SMPT_DESC_TYPE_MAP BIT(1)
2648- #define SMPT_DESC_END BIT(0)
2649-
2650- static u8 spi_nor_smpt_addr_width (const struct spi_nor * nor , const u32 settings )
2651- {
2652- switch (settings & SMPT_CMD_ADDRESS_LEN_MASK ) {
2653- case SMPT_CMD_ADDRESS_LEN_0 :
2654- return 0 ;
2655- case SMPT_CMD_ADDRESS_LEN_3 :
2656- return 3 ;
2657- case SMPT_CMD_ADDRESS_LEN_4 :
2658- return 4 ;
2659- case SMPT_CMD_ADDRESS_LEN_USE_CURRENT :
2660- /* fall through */
2661- default :
2662- return nor -> addr_width ;
2663- }
2664- }
2665-
2666- static u8 spi_nor_smpt_read_dummy (const struct spi_nor * nor , const u32 settings )
2667- {
2668- u8 read_dummy = SMPT_CMD_READ_DUMMY (settings );
2669-
2670- if (read_dummy == SMPT_CMD_READ_DUMMY_IS_VARIABLE )
2671- return nor -> read_dummy ;
2672- return read_dummy ;
2673- }
2674-
2675- static const u32 * spi_nor_get_map_in_use (struct spi_nor * nor , const u32 * smpt )
2676- {
2677- const u32 * ret = NULL ;
2678- u32 i , addr ;
2679- int err ;
2680- u8 addr_width , read_opcode , read_dummy ;
2681- u8 read_data_mask , data_byte , map_id ;
2682-
2683- addr_width = nor -> addr_width ;
2684- read_dummy = nor -> read_dummy ;
2685- read_opcode = nor -> read_opcode ;
2686-
2687- map_id = 0 ;
2688- i = 0 ;
2689- /* Determine if there are any optional Detection Command Descriptors */
2690- while (!(smpt [i ] & SMPT_DESC_TYPE_MAP )) {
2691- read_data_mask = SMPT_CMD_READ_DATA (smpt [i ]);
2692- nor -> addr_width = spi_nor_smpt_addr_width (nor , smpt [i ]);
2693- nor -> read_dummy = spi_nor_smpt_read_dummy (nor , smpt [i ]);
2694- nor -> read_opcode = SMPT_CMD_OPCODE (smpt [i ]);
2695- addr = smpt [i + 1 ];
2696-
2697- err = spi_nor_read_raw (nor , addr , 1 , & data_byte );
2698- if (err )
2699- goto out ;
2700-
2701- /*
2702- * Build an index value that is used to select the Sector Map
2703- * Configuration that is currently in use.
2704- */
2705- map_id = map_id << 1 | (!(data_byte & read_data_mask ) ? 0 : 1 );
2706- i = i + 2 ;
2707- }
2708-
2709- /* Find the matching configuration map */
2710- while (SMPT_MAP_ID (smpt [i ]) != map_id ) {
2711- if (smpt [i ] & SMPT_DESC_END )
2712- goto out ;
2713- /* increment the table index to the next map */
2714- i += SMPT_MAP_REGION_COUNT (smpt [i ]) + 1 ;
2715- }
2716-
2717- ret = smpt + i ;
2718- /* fall through */
2719- out :
2720- nor -> addr_width = addr_width ;
2721- nor -> read_dummy = read_dummy ;
2722- nor -> read_opcode = read_opcode ;
2723- return ret ;
2724- }
2725-
2726- static void
2727- spi_nor_region_check_overlay (struct spi_nor_erase_region * region ,
2728- const struct spi_nor_erase_type * erase ,
2729- const u8 erase_type )
2730- {
2731- int i ;
2732-
2733- for (i = 0 ; i < SNOR_ERASE_TYPE_MAX ; i ++ ) {
2734- if (!(erase_type & BIT (i )))
2735- continue ;
2736- if (region -> size & erase [i ].size_mask ) {
2737- spi_nor_region_mark_overlay (region );
2738- return ;
2739- }
2740- }
2741- }
2742-
2743- static int spi_nor_init_non_uniform_erase_map (struct spi_nor * nor ,
2744- const u32 * smpt )
2745- {
2746- struct spi_nor_erase_map * map = & nor -> erase_map ;
2747- const struct spi_nor_erase_type * erase = map -> erase_type ;
2748- struct spi_nor_erase_region * region ;
2749- u64 offset ;
2750- u32 region_count ;
2751- int i , j ;
2752- u8 erase_type ;
2753-
2754- region_count = SMPT_MAP_REGION_COUNT (* smpt );
2755- region = devm_kcalloc (nor -> dev , region_count , sizeof (* region ),
2756- GFP_KERNEL );
2757- if (!region )
2758- return - ENOMEM ;
2759- map -> regions = region ;
2760-
2761- map -> uniform_erase_type = 0xff ;
2762- offset = 0 ;
2763- for (i = 0 ; i < region_count ; i ++ ) {
2764- j = i + 1 ; /* index for the region dword */
2765- region [i ].size = SMPT_MAP_REGION_SIZE (smpt [j ]);
2766- erase_type = SMPT_MAP_REGION_ERASE_TYPE (smpt [j ]);
2767- region [i ].offset = offset | erase_type ;
2768-
2769- spi_nor_region_check_overlay (& region [i ], erase , erase_type );
2770-
2771- /*
2772- * Save the erase types that are supported in all regions and
2773- * can erase the entire flash memory.
2774- */
2775- map -> uniform_erase_type &= erase_type ;
2776-
2777- offset = (region [i ].offset & ~SNOR_ERASE_FLAGS_MASK ) +
2778- region [i ].size ;
2779- }
2780-
2781- spi_nor_region_mark_end (& region [i - 1 ]);
2782-
2783- return 0 ;
2784- }
2785-
2786- static int spi_nor_parse_smpt (struct spi_nor * nor ,
2787- const struct sfdp_parameter_header * smpt_header )
2788- {
2789- const u32 * sector_map ;
2790- u32 * smpt ;
2791- size_t len ;
2792- u32 addr ;
2793- int i , ret ;
2794-
2795- /* Read the Sector Map Parameter Table. */
2796- len = smpt_header -> length * sizeof (* smpt );
2797- smpt = kzalloc (len , GFP_KERNEL );
2798- if (!smpt )
2799- return - ENOMEM ;
2800-
2801- addr = SFDP_PARAM_HEADER_PTP (smpt_header );
2802- ret = spi_nor_read_sfdp (nor , addr , len , smpt );
2803- if (ret )
2804- goto out ;
2805-
2806- /* Fix endianness of the SMPT DWORDs. */
2807- for (i = 0 ; i < smpt_header -> length ; i ++ )
2808- smpt [i ] = le32_to_cpu (smpt [i ]);
2809-
2810- sector_map = spi_nor_get_map_in_use (nor , smpt );
2811- if (!sector_map ) {
2812- ret = - EINVAL ;
2813- goto out ;
2814- }
2815-
2816- ret = spi_nor_init_non_uniform_erase_map (nor , sector_map );
2817- if (ret )
2818- goto out ;
2819-
2820- spi_nor_regions_sort_erase_types (& nor -> erase_map );
2821- /* fall through */
2822- out :
2823- kfree (smpt );
2824- return ret ;
2825- }
2826-
28272590/**
28282591 * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters.
28292592 * @nor: pointer to a 'struct spi_nor'
@@ -2919,7 +2682,7 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor,
29192682
29202683 switch (SFDP_PARAM_HEADER_ID (param_header )) {
29212684 case SFDP_SECTOR_MAP_ID :
2922- err = spi_nor_parse_smpt ( nor , param_header );
2685+ dev_info ( dev , "non-uniform erase sector maps are not supported yet.\n" );
29232686 break ;
29242687
29252688 default :
0 commit comments