Skip to content

Commit 60c6946

Browse files
reibax-marcusdavem330
authored andcommitted
posix-clock: introduce posix_clock_context concept
Add the necessary structure to support custom private-data per posix-clock user. The previous implementation of posix-clock assumed all file open instances need access to the same clock structure on private_data. The need for individual data structures per file open instance has been identified when developing support for multiple timestamp event queue users for ptp_clock. Signed-off-by: Xabier Marquiegui <[email protected]> Suggested-by: Richard Cochran <[email protected]> Suggested-by: Vinicius Costa Gomes <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 99620ea commit 60c6946

File tree

4 files changed

+76
-32
lines changed

4 files changed

+76
-32
lines changed

drivers/ptp/ptp_chardev.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
101101
return 0;
102102
}
103103

104-
int ptp_open(struct posix_clock *pc, fmode_t fmode)
104+
int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
105105
{
106106
return 0;
107107
}
108108

109-
long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
109+
long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
110+
unsigned long arg)
110111
{
111-
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
112+
struct ptp_clock *ptp =
113+
container_of(pccontext->clk, struct ptp_clock, clock);
112114
struct ptp_sys_offset_extended *extoff = NULL;
113115
struct ptp_sys_offset_precise precise_offset;
114116
struct system_device_crosststamp xtstamp;
@@ -432,9 +434,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
432434
return err;
433435
}
434436

435-
__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
437+
__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
438+
poll_table *wait)
436439
{
437-
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
440+
struct ptp_clock *ptp =
441+
container_of(pccontext->clk, struct ptp_clock, clock);
438442

439443
poll_wait(fp, &ptp->tsev_wq, wait);
440444

@@ -443,10 +447,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
443447

444448
#define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
445449

446-
ssize_t ptp_read(struct posix_clock *pc,
447-
uint rdflags, char __user *buf, size_t cnt)
450+
ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
451+
char __user *buf, size_t cnt)
448452
{
449-
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
453+
struct ptp_clock *ptp =
454+
container_of(pccontext->clk, struct ptp_clock, clock);
450455
struct timestamp_event_queue *queue = &ptp->tsevq;
451456
struct ptp_extts_event *event;
452457
unsigned long flags;

drivers/ptp/ptp_private.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,18 @@ extern struct class *ptp_class;
117117
int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
118118
enum ptp_pin_function func, unsigned int chan);
119119

120-
long ptp_ioctl(struct posix_clock *pc,
121-
unsigned int cmd, unsigned long arg);
120+
long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
121+
unsigned long arg);
122122

123-
int ptp_open(struct posix_clock *pc, fmode_t fmode);
123+
int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
124124

125-
ssize_t ptp_read(struct posix_clock *pc,
126-
uint flags, char __user *buf, size_t cnt);
125+
int ptp_release(struct posix_clock_context *pccontext);
127126

128-
__poll_t ptp_poll(struct posix_clock *pc,
129-
struct file *fp, poll_table *wait);
127+
ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
128+
size_t cnt);
129+
130+
__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
131+
poll_table *wait);
130132

131133
/*
132134
* see ptp_sysfs.c

include/linux/posix-clock.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/rwsem.h>
1515

1616
struct posix_clock;
17+
struct posix_clock_context;
1718

1819
/**
1920
* struct posix_clock_operations - functional interface to the clock
@@ -50,18 +51,18 @@ struct posix_clock_operations {
5051
/*
5152
* Optional character device methods:
5253
*/
53-
long (*ioctl) (struct posix_clock *pc,
54-
unsigned int cmd, unsigned long arg);
54+
long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
55+
unsigned long arg);
5556

56-
int (*open) (struct posix_clock *pc, fmode_t f_mode);
57+
int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
5758

58-
__poll_t (*poll) (struct posix_clock *pc,
59-
struct file *file, poll_table *wait);
59+
__poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
60+
poll_table *wait);
6061

61-
int (*release) (struct posix_clock *pc);
62+
int (*release)(struct posix_clock_context *pccontext);
6263

63-
ssize_t (*read) (struct posix_clock *pc,
64-
uint flags, char __user *buf, size_t cnt);
64+
ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
65+
char __user *buf, size_t cnt);
6566
};
6667

6768
/**
@@ -90,6 +91,24 @@ struct posix_clock {
9091
bool zombie;
9192
};
9293

94+
/**
95+
* struct posix_clock_context - represents clock file operations context
96+
*
97+
* @clk: Pointer to the clock
98+
* @private_clkdata: Pointer to user data
99+
*
100+
* Drivers should use struct posix_clock_context during specific character
101+
* device file operation methods to access the posix clock.
102+
*
103+
* Drivers can store a private data structure during the open operation
104+
* if they have specific information that is required in other file
105+
* operations.
106+
*/
107+
struct posix_clock_context {
108+
struct posix_clock *clk;
109+
void *private_clkdata;
110+
};
111+
93112
/**
94113
* posix_clock_register() - register a new clock
95114
* @clk: Pointer to the clock. Caller must provide 'ops' field

kernel/time/posix-clock.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
*/
2020
static struct posix_clock *get_posix_clock(struct file *fp)
2121
{
22-
struct posix_clock *clk = fp->private_data;
22+
struct posix_clock_context *pccontext = fp->private_data;
23+
struct posix_clock *clk = pccontext->clk;
2324

2425
down_read(&clk->rwsem);
2526

@@ -39,14 +40,15 @@ static void put_posix_clock(struct posix_clock *clk)
3940
static ssize_t posix_clock_read(struct file *fp, char __user *buf,
4041
size_t count, loff_t *ppos)
4142
{
43+
struct posix_clock_context *pccontext = fp->private_data;
4244
struct posix_clock *clk = get_posix_clock(fp);
4345
int err = -EINVAL;
4446

4547
if (!clk)
4648
return -ENODEV;
4749

4850
if (clk->ops.read)
49-
err = clk->ops.read(clk, fp->f_flags, buf, count);
51+
err = clk->ops.read(pccontext, fp->f_flags, buf, count);
5052

5153
put_posix_clock(clk);
5254

@@ -55,14 +57,15 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
5557

5658
static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
5759
{
60+
struct posix_clock_context *pccontext = fp->private_data;
5861
struct posix_clock *clk = get_posix_clock(fp);
5962
__poll_t result = 0;
6063

6164
if (!clk)
6265
return EPOLLERR;
6366

6467
if (clk->ops.poll)
65-
result = clk->ops.poll(clk, fp, wait);
68+
result = clk->ops.poll(pccontext, fp, wait);
6669

6770
put_posix_clock(clk);
6871

@@ -72,14 +75,15 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
7275
static long posix_clock_ioctl(struct file *fp,
7376
unsigned int cmd, unsigned long arg)
7477
{
78+
struct posix_clock_context *pccontext = fp->private_data;
7579
struct posix_clock *clk = get_posix_clock(fp);
7680
int err = -ENOTTY;
7781

7882
if (!clk)
7983
return -ENODEV;
8084

8185
if (clk->ops.ioctl)
82-
err = clk->ops.ioctl(clk, cmd, arg);
86+
err = clk->ops.ioctl(pccontext, cmd, arg);
8387

8488
put_posix_clock(clk);
8589

@@ -90,14 +94,15 @@ static long posix_clock_ioctl(struct file *fp,
9094
static long posix_clock_compat_ioctl(struct file *fp,
9195
unsigned int cmd, unsigned long arg)
9296
{
97+
struct posix_clock_context *pccontext = fp->private_data;
9398
struct posix_clock *clk = get_posix_clock(fp);
9499
int err = -ENOTTY;
95100

96101
if (!clk)
97102
return -ENODEV;
98103

99104
if (clk->ops.ioctl)
100-
err = clk->ops.ioctl(clk, cmd, arg);
105+
err = clk->ops.ioctl(pccontext, cmd, arg);
101106

102107
put_posix_clock(clk);
103108

@@ -110,21 +115,28 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
110115
int err;
111116
struct posix_clock *clk =
112117
container_of(inode->i_cdev, struct posix_clock, cdev);
118+
struct posix_clock_context *pccontext;
113119

114120
down_read(&clk->rwsem);
115121

116122
if (clk->zombie) {
117123
err = -ENODEV;
118124
goto out;
119125
}
126+
pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
127+
if (!pccontext) {
128+
err = -ENOMEM;
129+
goto out;
130+
}
131+
pccontext->clk = clk;
132+
fp->private_data = pccontext;
120133
if (clk->ops.open)
121-
err = clk->ops.open(clk, fp->f_mode);
134+
err = clk->ops.open(pccontext, fp->f_mode);
122135
else
123136
err = 0;
124137

125138
if (!err) {
126139
get_device(clk->dev);
127-
fp->private_data = clk;
128140
}
129141
out:
130142
up_read(&clk->rwsem);
@@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
133145

134146
static int posix_clock_release(struct inode *inode, struct file *fp)
135147
{
136-
struct posix_clock *clk = fp->private_data;
148+
struct posix_clock_context *pccontext = fp->private_data;
149+
struct posix_clock *clk;
137150
int err = 0;
138151

152+
if (!pccontext)
153+
return -ENODEV;
154+
clk = pccontext->clk;
155+
139156
if (clk->ops.release)
140-
err = clk->ops.release(clk);
157+
err = clk->ops.release(pccontext);
141158

142159
put_device(clk->dev);
143160

161+
kfree(pccontext);
144162
fp->private_data = NULL;
145163

146164
return err;

0 commit comments

Comments
 (0)