@@ -79,6 +79,11 @@ static int at25_ee_read(void *priv, unsigned int offset,
7979{
8080 struct at25_data * at25 = priv ;
8181 char * buf = val ;
82+ size_t max_chunk = spi_max_transfer_size (at25 -> spi );
83+ size_t num_msgs = DIV_ROUND_UP (count , max_chunk );
84+ size_t nr_bytes = 0 ;
85+ unsigned int msg_offset ;
86+ size_t msg_count ;
8287 u8 * cp ;
8388 ssize_t status ;
8489 struct spi_transfer t [2 ];
@@ -92,54 +97,59 @@ static int at25_ee_read(void *priv, unsigned int offset,
9297 if (unlikely (!count ))
9398 return - EINVAL ;
9499
95- cp = at25 -> command ;
100+ msg_offset = (unsigned int )offset ;
101+ msg_count = min (count , max_chunk );
102+ while (num_msgs ) {
103+ cp = at25 -> command ;
96104
97- instr = AT25_READ ;
98- if (at25 -> chip .flags & EE_INSTR_BIT3_IS_ADDR )
99- if (offset >= BIT (at25 -> addrlen * 8 ))
100- instr |= AT25_INSTR_BIT3 ;
105+ instr = AT25_READ ;
106+ if (at25 -> chip .flags & EE_INSTR_BIT3_IS_ADDR )
107+ if (msg_offset >= BIT (at25 -> addrlen * 8 ))
108+ instr |= AT25_INSTR_BIT3 ;
101109
102- mutex_lock (& at25 -> lock );
110+ mutex_lock (& at25 -> lock );
103111
104- * cp ++ = instr ;
105-
106- /* 8/16/24-bit address is written MSB first */
107- switch (at25 -> addrlen ) {
108- default : /* case 3 */
109- * cp ++ = offset >> 16 ;
110- fallthrough ;
111- case 2 :
112- * cp ++ = offset >> 8 ;
113- fallthrough ;
114- case 1 :
115- case 0 : /* can't happen: for better code generation */
116- * cp ++ = offset >> 0 ;
117- }
112+ * cp ++ = instr ;
118113
119- spi_message_init (& m );
120- memset (t , 0 , sizeof (t ));
114+ /* 8/16/24-bit address is written MSB first */
115+ switch (at25 -> addrlen ) {
116+ default : /* case 3 */
117+ * cp ++ = msg_offset >> 16 ;
118+ fallthrough ;
119+ case 2 :
120+ * cp ++ = msg_offset >> 8 ;
121+ fallthrough ;
122+ case 1 :
123+ case 0 : /* can't happen: for better code generation */
124+ * cp ++ = msg_offset >> 0 ;
125+ }
121126
122- t [0 ].tx_buf = at25 -> command ;
123- t [0 ].len = at25 -> addrlen + 1 ;
124- spi_message_add_tail (& t [0 ], & m );
127+ spi_message_init (& m );
128+ memset (t , 0 , sizeof (t ));
125129
126- t [ 1 ]. rx_buf = buf ;
127- t [ 1 ].len = count ;
128- spi_message_add_tail (& t [1 ], & m );
130+ t [ 0 ]. tx_buf = at25 -> command ;
131+ t [ 0 ].len = at25 -> addrlen + 1 ;
132+ spi_message_add_tail (& t [0 ], & m );
129133
130- /*
131- * Read it all at once.
132- *
133- * REVISIT that's potentially a problem with large chips, if
134- * other devices on the bus need to be accessed regularly or
135- * this chip is clocked very slowly.
136- */
137- status = spi_sync (at25 -> spi , & m );
138- dev_dbg (& at25 -> spi -> dev , "read %zu bytes at %d --> %zd\n" ,
139- count , offset , status );
134+ t [1 ].rx_buf = buf + nr_bytes ;
135+ t [1 ].len = msg_count ;
136+ spi_message_add_tail (& t [1 ], & m );
140137
141- mutex_unlock (& at25 -> lock );
142- return status ;
138+ status = spi_sync (at25 -> spi , & m );
139+
140+ mutex_unlock (& at25 -> lock );
141+
142+ if (status )
143+ return status ;
144+
145+ -- num_msgs ;
146+ msg_offset += msg_count ;
147+ nr_bytes += msg_count ;
148+ }
149+
150+ dev_dbg (& at25 -> spi -> dev , "read %zu bytes at %d\n" ,
151+ count , offset );
152+ return 0 ;
143153}
144154
145155/* Read extra registers as ID or serial number */
@@ -190,6 +200,7 @@ ATTRIBUTE_GROUPS(sernum);
190200static int at25_ee_write (void * priv , unsigned int off , void * val , size_t count )
191201{
192202 struct at25_data * at25 = priv ;
203+ size_t maxsz = spi_max_transfer_size (at25 -> spi );
193204 const char * buf = val ;
194205 int status = 0 ;
195206 unsigned buf_size ;
@@ -253,6 +264,8 @@ static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count)
253264 segment = buf_size - (offset % buf_size );
254265 if (segment > count )
255266 segment = count ;
267+ if (segment > maxsz )
268+ segment = maxsz ;
256269 memcpy (cp , buf , segment );
257270 status = spi_write (at25 -> spi , bounce ,
258271 segment + at25 -> addrlen + 1 );
0 commit comments