1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-27 23:22:37 +02:00

linux_spi.c: Refactor singleton states into reentrant pattern

Move global singleton states into a struct and store within
the spi_master data field for the life-time of the driver.

This is one of the steps on the way to move spi_master data
memory management behind the initialisation API, for more
context see other patches under the same topic "register_master_api".

TEST=builds
BUG=b:140394053

Change-Id: I93408c2ca846fca6a1c7eda7180862c51bd48078
Signed-off-by: Anastasia Klimchuk <aklm@chromium.org>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/52285
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
This commit is contained in:
Anastasia Klimchuk 2021-04-13 11:26:25 +10:00 committed by Edward O'Callaghan
parent 6b5736c991
commit 1b13f25ef2

View File

@ -44,29 +44,35 @@
* HummingBoard * HummingBoard
*/ */
static int fd = -1;
#define BUF_SIZE_FROM_SYSFS "/sys/module/spidev/parameters/bufsiz" #define BUF_SIZE_FROM_SYSFS "/sys/module/spidev/parameters/bufsiz"
static size_t max_kernel_buf_size;
struct linux_spi_data {
int fd;
size_t max_kernel_buf_size;
};
static int linux_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) static int linux_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
{ {
struct linux_spi_data *spi_data = flash->mst->spi.data;
/* Older kernels use a single buffer for combined input and output /* Older kernels use a single buffer for combined input and output
data. So account for longest possible command + address, too. */ data. So account for longest possible command + address, too. */
return spi_read_chunked(flash, buf, start, len, max_kernel_buf_size - 5); return spi_read_chunked(flash, buf, start, len, spi_data->max_kernel_buf_size - 5);
} }
static int linux_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len) static int linux_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
{ {
struct linux_spi_data *spi_data = flash->mst->spi.data;
/* 5 bytes must be reserved for longest possible command + address. */ /* 5 bytes must be reserved for longest possible command + address. */
return spi_write_chunked(flash, buf, start, len, max_kernel_buf_size - 5); return spi_write_chunked(flash, buf, start, len, spi_data->max_kernel_buf_size - 5);
} }
static int linux_spi_shutdown(void *data) static int linux_spi_shutdown(void *data)
{ {
if (fd != -1) { struct linux_spi_data *spi_data = (struct linux_spi_data *) data;
close(fd); if (spi_data->fd != -1)
fd = -1; close(spi_data->fd);
}
free(spi_data);
return 0; return 0;
} }
@ -75,6 +81,7 @@ static int linux_spi_send_command(const struct flashctx *flash, unsigned int wri
const unsigned char *txbuf, const unsigned char *txbuf,
unsigned char *rxbuf) unsigned char *rxbuf)
{ {
struct linux_spi_data *spi_data = flash->mst->spi.data;
int iocontrol_code; int iocontrol_code;
struct spi_ioc_transfer msg[2] = { struct spi_ioc_transfer msg[2] = {
{ {
@ -87,7 +94,7 @@ static int linux_spi_send_command(const struct flashctx *flash, unsigned int wri
}, },
}; };
if (fd == -1) if (spi_data->fd == -1)
return -1; return -1;
/* The implementation currently does not support requests that /* The implementation currently does not support requests that
don't start with sending a command. */ don't start with sending a command. */
@ -101,14 +108,14 @@ static int linux_spi_send_command(const struct flashctx *flash, unsigned int wri
else else
iocontrol_code = SPI_IOC_MESSAGE(2); iocontrol_code = SPI_IOC_MESSAGE(2);
if (ioctl(fd, iocontrol_code, msg) == -1) { if (ioctl(spi_data->fd, iocontrol_code, msg) == -1) {
msg_cerr("%s: ioctl: %s\n", __func__, strerror(errno)); msg_cerr("%s: ioctl: %s\n", __func__, strerror(errno));
return -1; return -1;
} }
return 0; return 0;
} }
static const struct spi_master spi_master_linux = { static struct spi_master spi_master_linux = {
.features = SPI_MASTER_4BA, .features = SPI_MASTER_4BA,
.max_data_read = MAX_DATA_UNSPECIFIED, /* TODO? */ .max_data_read = MAX_DATA_UNSPECIFIED, /* TODO? */
.max_data_write = MAX_DATA_UNSPECIFIED, /* TODO? */ .max_data_write = MAX_DATA_UNSPECIFIED, /* TODO? */
@ -167,6 +174,9 @@ int linux_spi_init(void)
/* SPI mode 0 (beware this also includes: MSB first, CS active low and others */ /* SPI mode 0 (beware this also includes: MSB first, CS active low and others */
const uint8_t mode = SPI_MODE_0; const uint8_t mode = SPI_MODE_0;
const uint8_t bits = 8; const uint8_t bits = 8;
int fd = -1;
size_t max_kernel_buf_size;
struct linux_spi_data *spi_data;
int ret = 0; int ret = 0;
p = extract_programmer_param("spispeed"); p = extract_programmer_param("spispeed");
@ -226,7 +236,18 @@ int linux_spi_init(void)
max_kernel_buf_size = get_max_kernel_buf_size(); max_kernel_buf_size = get_max_kernel_buf_size();
msg_pdbg("%s: max_kernel_buf_size: %zu\n", __func__, max_kernel_buf_size); msg_pdbg("%s: max_kernel_buf_size: %zu\n", __func__, max_kernel_buf_size);
if (register_shutdown(linux_spi_shutdown, NULL)) { spi_data = calloc(1, sizeof(*spi_data));
if (!spi_data) {
msg_perr("Unable to allocated space for SPI master data\n");
ret = SPI_GENERIC_ERROR;
goto init_err;
}
spi_data->fd = fd;
spi_data->max_kernel_buf_size = max_kernel_buf_size;
spi_master_linux.data = spi_data;
if (register_shutdown(linux_spi_shutdown, spi_data)) {
free(spi_data);
ret = 1; ret = 1;
goto init_err; goto init_err;
} }