Skip to content

Commit ac9c517

Browse files
subbu-m37gregkh
authored andcommitted
pps: generators: replace copy of pps-gen info struct with const pointer
Some PPS generator drivers may need to retrieve a pointer to their internal data while executing the PPS generator enable() method. During the driver registration the pps_gen_device pointer is returned from the framework, and for that reason, there is difficulty in getting generator driver data back in the enable function. We won't be able to use container_of macro as it results in static assert, and we might end up in using static pointer. To solve the issue and to get back the generator driver data back, we should not copy the struct pps_gen_source_info within the struct pps_gen_device during the registration stage, but simply save the pointer of the driver one. In this manner, driver may get a pointer to their internal data as shown below: struct pps_gen_foo_data_s { ... struct pps_gen_source_info gen_info; struct pps_gen_device *pps_gen; ... }; static int __init pps_gen_foo_init(void) { struct pps_gen_foo_data_s *foo; ... foo->pps_gen = pps_gen_register_source(&foo->gen_info); ... } Then, in the enable() method, we can retrieve the pointer to the main struct by using the code below: static int pps_gen_foo_enable(struct pps_gen_device *pps_gen, bool enable) { struct pps_gen_foo_data_s *foo = container_of(pps_gen->info, struct pps_gen_foo_data_s, gen_info); ... } Signed-off-by: Rodolfo Giometti <[email protected]> Tested-by: Subramanian Mohan <[email protected]> Suggested-by: Andy Shevchenko <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Subramanian Mohan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 6aa9826 commit ac9c517

File tree

5 files changed

+14
-15
lines changed

5 files changed

+14
-15
lines changed

Documentation/driver-api/pps.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,7 @@ To do so the class pps-gen has been added. PPS generators can be
206206
registered in the kernel by defining a struct pps_gen_source_info as
207207
follows::
208208

209-
static struct pps_gen_source_info pps_gen_dummy_info = {
210-
.name = "dummy",
209+
static const struct pps_gen_source_info pps_gen_dummy_info = {
211210
.use_system_clock = true,
212211
.get_time = pps_gen_dummy_get_time,
213212
.enable = pps_gen_dummy_enable,

drivers/pps/generators/pps_gen-dummy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int pps_gen_dummy_enable(struct pps_gen_device *pps_gen, bool enable)
6161
* The PPS info struct
6262
*/
6363

64-
static struct pps_gen_source_info pps_gen_dummy_info = {
64+
static const struct pps_gen_source_info pps_gen_dummy_info = {
6565
.use_system_clock = true,
6666
.get_time = pps_gen_dummy_get_time,
6767
.enable = pps_gen_dummy_enable,

drivers/pps/generators/pps_gen.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static long pps_gen_cdev_ioctl(struct file *file,
6666
if (ret)
6767
return -EFAULT;
6868

69-
ret = pps_gen->info.enable(pps_gen, status);
69+
ret = pps_gen->info->enable(pps_gen, status);
7070
if (ret)
7171
return ret;
7272
pps_gen->enabled = status;
@@ -76,7 +76,7 @@ static long pps_gen_cdev_ioctl(struct file *file,
7676
case PPS_GEN_USESYSTEMCLOCK:
7777
dev_dbg(pps_gen->dev, "PPS_GEN_USESYSTEMCLOCK\n");
7878

79-
ret = put_user(pps_gen->info.use_system_clock, uiuarg);
79+
ret = put_user(pps_gen->info->use_system_clock, uiuarg);
8080
if (ret)
8181
return -EFAULT;
8282

@@ -175,16 +175,16 @@ static int pps_gen_register_cdev(struct pps_gen_device *pps_gen)
175175
devt = MKDEV(MAJOR(pps_gen_devt), pps_gen->id);
176176

177177
cdev_init(&pps_gen->cdev, &pps_gen_cdev_fops);
178-
pps_gen->cdev.owner = pps_gen->info.owner;
178+
pps_gen->cdev.owner = pps_gen->info->owner;
179179

180180
err = cdev_add(&pps_gen->cdev, devt, 1);
181181
if (err) {
182182
pr_err("failed to add char device %d:%d\n",
183183
MAJOR(pps_gen_devt), pps_gen->id);
184184
goto free_ida;
185185
}
186-
pps_gen->dev = device_create(pps_gen_class, pps_gen->info.parent, devt,
187-
pps_gen, "pps-gen%d", pps_gen->id);
186+
pps_gen->dev = device_create(pps_gen_class, pps_gen->info->parent, devt,
187+
pps_gen, "pps-gen%d", pps_gen->id);
188188
if (IS_ERR(pps_gen->dev)) {
189189
err = PTR_ERR(pps_gen->dev);
190190
goto del_cdev;
@@ -225,7 +225,7 @@ static void pps_gen_unregister_cdev(struct pps_gen_device *pps_gen)
225225
* Return: the PPS generator device in case of success, and ERR_PTR(errno)
226226
* otherwise.
227227
*/
228-
struct pps_gen_device *pps_gen_register_source(struct pps_gen_source_info *info)
228+
struct pps_gen_device *pps_gen_register_source(const struct pps_gen_source_info *info)
229229
{
230230
struct pps_gen_device *pps_gen;
231231
int err;
@@ -235,7 +235,7 @@ struct pps_gen_device *pps_gen_register_source(struct pps_gen_source_info *info)
235235
err = -ENOMEM;
236236
goto pps_gen_register_source_exit;
237237
}
238-
pps_gen->info = *info;
238+
pps_gen->info = info;
239239
pps_gen->enabled = false;
240240

241241
init_waitqueue_head(&pps_gen->queue);

drivers/pps/generators/sysfs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static ssize_t system_show(struct device *dev, struct device_attribute *attr,
1919
{
2020
struct pps_gen_device *pps_gen = dev_get_drvdata(dev);
2121

22-
return sysfs_emit(buf, "%d\n", pps_gen->info.use_system_clock);
22+
return sysfs_emit(buf, "%d\n", pps_gen->info->use_system_clock);
2323
}
2424
static DEVICE_ATTR_RO(system);
2525

@@ -30,7 +30,7 @@ static ssize_t time_show(struct device *dev, struct device_attribute *attr,
3030
struct timespec64 time;
3131
int ret;
3232

33-
ret = pps_gen->info.get_time(pps_gen, &time);
33+
ret = pps_gen->info->get_time(pps_gen, &time);
3434
if (ret)
3535
return ret;
3636

@@ -49,7 +49,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
4949
if (ret)
5050
return ret;
5151

52-
ret = pps_gen->info.enable(pps_gen, status);
52+
ret = pps_gen->info->enable(pps_gen, status);
5353
if (ret)
5454
return ret;
5555
pps_gen->enabled = status;

include/linux/pps_gen_kernel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct pps_gen_source_info {
4343

4444
/* The main struct */
4545
struct pps_gen_device {
46-
struct pps_gen_source_info info; /* PSS generator info */
46+
const struct pps_gen_source_info *info; /* PSS generator info */
4747
bool enabled; /* PSS generator status */
4848

4949
unsigned int event;
@@ -70,7 +70,7 @@ extern const struct attribute_group *pps_gen_groups[];
7070
*/
7171

7272
extern struct pps_gen_device *pps_gen_register_source(
73-
struct pps_gen_source_info *info);
73+
const struct pps_gen_source_info *info);
7474
extern void pps_gen_unregister_source(struct pps_gen_device *pps_gen);
7575
extern void pps_gen_event(struct pps_gen_device *pps_gen,
7676
unsigned int event, void *data);

0 commit comments

Comments
 (0)