Skip to content

Commit 4fc08d7

Browse files
committed
misc: rp1-pio: Add compat_ioctl method
Provide a compat_ioctl method, to support running a 64-bit kernel with a 32-bit userland. Signed-off-by: Phil Elwell <[email protected]>
1 parent 1b5acd4 commit 4fc08d7

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

drivers/misc/rp1-pio.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,11 +996,75 @@ static long rp1_pio_ioctl(struct file *filp, unsigned int ioctl_num,
996996
return ret;
997997
}
998998

999+
#ifdef CONFIG_COMPAT
1000+
1001+
struct rp1_pio_sm_xfer_data_args_compat {
1002+
uint16_t sm;
1003+
uint16_t dir;
1004+
uint16_t data_bytes;
1005+
compat_uptr_t data;
1006+
};
1007+
1008+
struct rp1_access_hw_args_compat {
1009+
uint32_t addr;
1010+
uint32_t len;
1011+
compat_uptr_t data;
1012+
};
1013+
1014+
#define PIO_IOC_SM_XFER_DATA_COMPAT _IOW(PIO_IOC_MAGIC, 1, struct rp1_pio_sm_xfer_data_args_compat)
1015+
#define PIO_IOC_READ_HW_COMPAT _IOW(PIO_IOC_MAGIC, 8, struct rp1_access_hw_args_compat)
1016+
#define PIO_IOC_WRITE_HW_COMPAT _IOW(PIO_IOC_MAGIC, 9, struct rp1_access_hw_args_compat)
1017+
1018+
static long rp1_pio_compat_ioctl(struct file *filp, unsigned int ioctl_num,
1019+
unsigned long ioctl_param)
1020+
{
1021+
struct rp1_pio_client *client = filp->private_data;
1022+
1023+
switch (ioctl_num) {
1024+
case PIO_IOC_SM_XFER_DATA_COMPAT:
1025+
{
1026+
struct rp1_pio_sm_xfer_data_args_compat compat_param;
1027+
struct rp1_pio_sm_xfer_data_args param;
1028+
1029+
if (copy_from_user(&compat_param, compat_ptr(ioctl_param), sizeof(compat_param)))
1030+
return -EFAULT;
1031+
param.sm = compat_param.sm;
1032+
param.dir = compat_param.dir;
1033+
param.data_bytes = compat_param.data_bytes;
1034+
param.data = compat_ptr(compat_param.data);
1035+
return rp1_pio_sm_xfer_data(client, &param);
1036+
}
1037+
1038+
case PIO_IOC_READ_HW_COMPAT:
1039+
case PIO_IOC_WRITE_HW_COMPAT:
1040+
{
1041+
struct rp1_access_hw_args_compat compat_param;
1042+
struct rp1_access_hw_args param;
1043+
1044+
if (copy_from_user(&compat_param, compat_ptr(ioctl_param), sizeof(compat_param)))
1045+
return -EFAULT;
1046+
param.addr = compat_param.addr;
1047+
param.len = compat_param.len;
1048+
param.data = compat_ptr(compat_param.data);
1049+
if (ioctl_num == PIO_IOC_READ_HW_COMPAT)
1050+
return rp1_pio_read_hw(client, &param);
1051+
else
1052+
return rp1_pio_write_hw(client, &param);
1053+
}
1054+
default:
1055+
return rp1_pio_ioctl(filp, ioctl_num, ioctl_param);
1056+
}
1057+
}
1058+
#else
1059+
#define rp1_pio_compat_ioctl NULL
1060+
#endif
1061+
9991062
const struct file_operations rp1_pio_fops = {
10001063
.owner = THIS_MODULE,
10011064
.open = rp1_pio_open,
10021065
.release = rp1_pio_release,
10031066
.unlocked_ioctl = rp1_pio_ioctl,
1067+
.compat_ioctl = rp1_pio_compat_ioctl,
10041068
};
10051069

10061070
static int rp1_pio_probe(struct platform_device *pdev)

0 commit comments

Comments
 (0)