static int __init pps_ktimer_init(void) { pps = pps_register_source(&pps_ktimer_info, PPS_CAPTUREASSERT | PPS_OFFSETASSERT); if (pps == NULL) { pr_err("cannot register PPS source\n"); return -ENOMEM; } setup_timer(&ktimer, pps_ktimer_event, 0); mod_timer(&ktimer, jiffies + HZ); dev_info(pps->dev, "ktimer PPS source registered\n"); return 0; }
static int __init pps_ktimer_init(void) { int ret; ret = pps_register_source(&pps_ktimer_info, PPS_CAPTUREASSERT | PPS_OFFSETASSERT); if (ret < 0) { printk(KERN_ERR "cannot register ktimer source\n"); return ret; } source = ret; setup_timer(&ktimer, pps_ktimer_event, 0); mod_timer(&ktimer, jiffies + HZ); pr_info("ktimer PPS source registered at %d\n", source); return 0; }
static int pps_tty_open(struct tty_struct *tty) { struct pps_source_info info; struct tty_driver *drv = tty->driver; int index = tty->index + drv->name_base; struct pps_device *pps; int ret; info.owner = THIS_MODULE; info.dev = NULL; snprintf(info.name, PPS_MAX_NAME_LEN, "%s%d", drv->driver_name, index); snprintf(info.path, PPS_MAX_NAME_LEN, "/dev/%s%d", drv->name, index); info.mode = PPS_CAPTUREBOTH | \ PPS_OFFSETASSERT | PPS_OFFSETCLEAR | \ PPS_CANWAIT | PPS_TSFMT_TSPEC; pps = pps_register_source(&info, PPS_CAPTUREBOTH | \ PPS_OFFSETASSERT | PPS_OFFSETCLEAR); if (pps == NULL) { pr_err("cannot register PPS source \"%s\"\n", info.path); return -ENOMEM; } tty->disc_data = pps; /* Should open N_TTY ldisc too */ ret = alias_n_tty_open(tty); if (ret < 0) { pr_err("cannot open tty ldisc \"%s\"\n", info.path); goto err_unregister; } dev_info(pps->dev, "source \"%s\" added\n", info.path); return 0; err_unregister: tty->disc_data = NULL; pps_unregister_source(pps); return ret; }
struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, struct device *parent) { struct ptp_clock *ptp; int err = 0, index, major = MAJOR(ptp_devt); if (info->n_alarm > PTP_MAX_ALARMS) return ERR_PTR(-EINVAL); /* Find a free clock slot and reserve it. */ err = -EBUSY; mutex_lock(&ptp_clocks_mutex); index = find_first_zero_bit(ptp_clocks_map, PTP_MAX_CLOCKS); if (index < PTP_MAX_CLOCKS) set_bit(index, ptp_clocks_map); else goto no_slot; /* Initialize a clock structure. */ err = -ENOMEM; ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL); if (ptp == NULL) goto no_memory; ptp->clock.ops = ptp_clock_ops; ptp->clock.release = delete_ptp_clock; ptp->info = info; ptp->devid = MKDEV(major, index); ptp->index = index; spin_lock_init(&ptp->tsevq.lock); mutex_init(&ptp->tsevq_mux); init_waitqueue_head(&ptp->tsev_wq); /* Create a new device in our class. */ ptp->dev = device_create(ptp_class, parent, ptp->devid, ptp, "ptp%d", ptp->index); if (IS_ERR(ptp->dev)) goto no_device; dev_set_drvdata(ptp->dev, ptp); err = ptp_populate_sysfs(ptp); if (err) goto no_sysfs; /* Register a new PPS source. */ if (info->pps) { struct pps_source_info pps; memset(&pps, 0, sizeof(pps)); snprintf(pps.name, PPS_MAX_NAME_LEN, "ptp%d", index); pps.mode = PTP_PPS_MODE; pps.owner = info->owner; ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS); if (!ptp->pps_source) { pr_err("failed to register pps source\n"); goto no_pps; } } /* Create a posix clock. */ err = posix_clock_register(&ptp->clock, ptp->devid); if (err) { pr_err("failed to create posix clock\n"); goto no_clock; } mutex_unlock(&ptp_clocks_mutex); return ptp; no_clock: if (ptp->pps_source) pps_unregister_source(ptp->pps_source); no_pps: ptp_cleanup_sysfs(ptp); no_sysfs: device_destroy(ptp_class, ptp->devid); no_device: mutex_destroy(&ptp->tsevq_mux); kfree(ptp); no_memory: clear_bit(index, ptp_clocks_map); no_slot: mutex_unlock(&ptp_clocks_mutex); return ERR_PTR(err); }
static int pps_gpio_probe(struct platform_device *pdev) { struct pps_gpio_device_data *data; int irq; int ret; int err; int pps_default_params; const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data; /* GPIO setup */ ret = pps_gpio_setup(pdev); if (ret) return -EINVAL; /* IRQ setup */ irq = gpio_to_irq(pdata->gpio_pin); if (irq < 0) { pr_err("failed to map GPIO to IRQ: %d\n", irq); err = -EINVAL; goto return_error; } /* allocate space for device info */ data = kzalloc(sizeof(struct pps_gpio_device_data), GFP_KERNEL); if (data == NULL) { err = -ENOMEM; goto return_error; } /* initialize PPS specific parts of the bookkeeping data structure. */ data->info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC; if (pdata->capture_clear) data->info.mode |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR | PPS_ECHOCLEAR; data->info.owner = THIS_MODULE; snprintf(data->info.name, PPS_MAX_NAME_LEN - 1, "%s.%d", pdev->name, pdev->id); /* register PPS source */ pps_default_params = PPS_CAPTUREASSERT | PPS_OFFSETASSERT; if (pdata->capture_clear) pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR; data->pps = pps_register_source(&data->info, pps_default_params); if (data->pps == NULL) { kfree(data); pr_err("failed to register IRQ %d as PPS source\n", irq); err = -EINVAL; goto return_error; } data->irq = irq; data->pdata = pdata; /* register IRQ interrupt handler */ ret = request_irq(irq, pps_gpio_irq_handler, get_irqf_trigger_flags(pdata), data->info.name, data); if (ret) { pps_unregister_source(data->pps); kfree(data); pr_err("failed to acquire IRQ %d\n", irq); err = -EINVAL; goto return_error; } platform_set_drvdata(pdev, data); dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", irq); return 0; return_error: gpio_free(pdata->gpio_pin); return err; }
static int pps_gpio_probe(struct platform_device *pdev) { struct pps_gpio_device_data *data; const char *gpio_label; int ret; int pps_default_params; const struct pps_gpio_platform_data *pdata = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; /* allocate space for device info */ data = devm_kzalloc(&pdev->dev, sizeof(struct pps_gpio_device_data), GFP_KERNEL); if (!data) return -ENOMEM; if (pdata) { data->gpio_pin = pdata->gpio_pin; gpio_label = pdata->gpio_label; data->assert_falling_edge = pdata->assert_falling_edge; data->capture_clear = pdata->capture_clear; } else { ret = of_get_gpio(np, 0); if (ret < 0) { dev_err(&pdev->dev, "failed to get GPIO from device tree\n"); return ret; } data->gpio_pin = ret; gpio_label = PPS_GPIO_NAME; if (of_get_property(np, "assert-falling-edge", NULL)) data->assert_falling_edge = true; } /* GPIO setup */ ret = devm_gpio_request(&pdev->dev, data->gpio_pin, gpio_label); if (ret) { dev_err(&pdev->dev, "failed to request GPIO %u\n", data->gpio_pin); return ret; } ret = gpio_direction_input(data->gpio_pin); if (ret) { dev_err(&pdev->dev, "failed to set pin direction\n"); return -EINVAL; } /* IRQ setup */ ret = gpio_to_irq(data->gpio_pin); if (ret < 0) { dev_err(&pdev->dev, "failed to map GPIO to IRQ: %d\n", ret); return -EINVAL; } data->irq = ret; /* initialize PPS specific parts of the bookkeeping data structure. */ data->info.mode = PPS_CAPTUREASSERT | PPS_OFFSETASSERT | PPS_ECHOASSERT | PPS_CANWAIT | PPS_TSFMT_TSPEC; if (data->capture_clear) data->info.mode |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR | PPS_ECHOCLEAR; data->info.owner = THIS_MODULE; snprintf(data->info.name, PPS_MAX_NAME_LEN - 1, "%s.%d", pdev->name, pdev->id); /* register PPS source */ pps_default_params = PPS_CAPTUREASSERT | PPS_OFFSETASSERT; if (data->capture_clear) pps_default_params |= PPS_CAPTURECLEAR | PPS_OFFSETCLEAR; data->pps = pps_register_source(&data->info, pps_default_params); if (data->pps == NULL) { dev_err(&pdev->dev, "failed to register IRQ %d as PPS source\n", data->irq); return -EINVAL; } /* register IRQ interrupt handler */ ret = devm_request_irq(&pdev->dev, data->irq, pps_gpio_irq_handler, get_irqf_trigger_flags(data), data->info.name, data); if (ret) { pps_unregister_source(data->pps); dev_err(&pdev->dev, "failed to acquire IRQ %d\n", data->irq); return -EINVAL; } platform_set_drvdata(pdev, data); dev_info(data->pps->dev, "Registered IRQ %d as PPS source\n", data->irq); return 0; }