Skip to content

Commit

Permalink
misc: rp1-pio: Support larger data transfers
Browse files Browse the repository at this point in the history
Add a separate IOCTL for larger transfer with a 32-bit data_bytes
field.

See: raspberrypi/utils#107

Signed-off-by: Phil Elwell <[email protected]>
  • Loading branch information
pelwell committed Dec 16, 2024
1 parent b75fd2a commit 0a6aa02
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
43 changes: 40 additions & 3 deletions drivers/misc/rp1-pio.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,9 +824,9 @@ static int rp1_pio_sm_rx_user(struct rp1_pio_device *pio, struct dma_info *dma,
return ret;
}

static int rp1_pio_sm_xfer_data(struct rp1_pio_client *client, void *param)
static int rp1_pio_sm_xfer_data32(struct rp1_pio_client *client, void *param)
{
struct rp1_pio_sm_xfer_data_args *args = param;
struct rp1_pio_sm_xfer_data32_args *args = param;
struct rp1_pio_device *pio = client->pio;
struct dma_info *dma;

Expand All @@ -842,13 +842,27 @@ static int rp1_pio_sm_xfer_data(struct rp1_pio_client *client, void *param)
return rp1_pio_sm_rx_user(pio, dma, args->data, args->data_bytes);
}

static int rp1_pio_sm_xfer_data(struct rp1_pio_client *client, void *param)
{
struct rp1_pio_sm_xfer_data_args *args = param;
struct rp1_pio_sm_xfer_data32_args args32;

args32.sm = args->sm;
args32.dir = args->dir;
args32.data_bytes = args->data_bytes;
args32.data = args->data;

return rp1_pio_sm_xfer_data32(client, &args32);
}

struct handler_info {
const char *name;
int (*func)(struct rp1_pio_client *client, void *param);
int argsize;
} ioctl_handlers[] = {
HANDLER(SM_CONFIG_XFER, sm_config_xfer),
HANDLER(SM_XFER_DATA, sm_xfer_data),
HANDLER(SM_XFER_DATA32, sm_xfer_data32),

HANDLER(CAN_ADD_PROGRAM, can_add_program),
HANDLER(ADD_PROGRAM, add_program),
Expand Down Expand Up @@ -1032,13 +1046,23 @@ struct rp1_pio_sm_xfer_data_args_compat {
compat_uptr_t data;
};

struct rp1_pio_sm_xfer_data32_args_compat {
uint16_t sm;
uint16_t dir;
uint32_t data_bytes;
compat_uptr_t data;
};

struct rp1_access_hw_args_compat {
uint32_t addr;
uint32_t len;
compat_uptr_t data;
};

#define PIO_IOC_SM_XFER_DATA_COMPAT _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args_compat)
#define PIO_IOC_SM_XFER_DATA_COMPAT \
_IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args_compat)
#define PIO_IOC_SM_XFER_DATA32_COMPAT \
_IOW(PIO_IOC_MAGIC, 2, struct rp1_pio_sm_xfer_data32_args_compat)
#define PIO_IOC_READ_HW_COMPAT _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args_compat)
#define PIO_IOC_WRITE_HW_COMPAT _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args_compat)

Expand All @@ -1061,6 +1085,19 @@ static long rp1_pio_compat_ioctl(struct file *filp, unsigned int ioctl_num,
param.data = compat_ptr(compat_param.data);
return rp1_pio_sm_xfer_data(client, &param);
}
case PIO_IOC_SM_XFER_DATA32_COMPAT:
{
struct rp1_pio_sm_xfer_data32_args_compat compat_param;
struct rp1_pio_sm_xfer_data32_args param;

if (copy_from_user(&compat_param, compat_ptr(ioctl_param), sizeof(compat_param)))
return -EFAULT;
param.sm = compat_param.sm;
param.dir = compat_param.dir;
param.data_bytes = compat_param.data_bytes;
param.data = compat_ptr(compat_param.data);
return rp1_pio_sm_xfer_data32(client, &param);
}

case PIO_IOC_READ_HW_COMPAT:
case PIO_IOC_WRITE_HW_COMPAT:
Expand Down
8 changes: 8 additions & 0 deletions include/uapi/misc/rp1_pio_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ struct rp1_pio_sm_xfer_data_args {
void *data;
};

struct rp1_pio_sm_xfer_data32_args {
uint16_t sm;
uint16_t dir;
uint32_t data_bytes;
void *data;
};

struct rp1_access_hw_args {
uint32_t addr;
uint32_t len;
Expand All @@ -177,6 +184,7 @@ struct rp1_access_hw_args {

#define PIO_IOC_SM_CONFIG_XFER _IOW(PIO_IOC_MAGIC, 0, struct rp1_pio_sm_config_xfer_args)
#define PIO_IOC_SM_XFER_DATA _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args)
#define PIO_IOC_SM_XFER_DATA32 _IOW(PIO_IOC_MAGIC, 2, struct rp1_pio_sm_xfer_data32_args)

#define PIO_IOC_READ_HW _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args)
#define PIO_IOC_WRITE_HW _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args)
Expand Down

0 comments on commit 0a6aa02

Please sign in to comment.