static void rt_timer_trig_activate(struct led_classdev *led_cdev) { struct rt_timer *rt = container_of(led_cdev->trigger, struct rt_timer, led_trigger); struct rt_timer_gpio *gpio_data; int rc; led_cdev->trigger_data = NULL; gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); if (!gpio_data) return; rc = device_create_file(led_cdev->dev, &dev_attr_duty_cycle); if (rc) goto err_gpio; rc = device_create_file(led_cdev->dev, &dev_attr_fade); if (rc) goto err_out_duty_cycle; led_cdev->activated = true; led_cdev->trigger_data = gpio_data; gpio_data->led = led_cdev; list_add(&gpio_data->list, &rt->gpios); led_cdev->trigger_data = gpio_data; rt_timer_enable(rt); return; err_out_duty_cycle: device_remove_file(led_cdev->dev, &dev_attr_duty_cycle); err_gpio: kfree(gpio_data); }
static int rt_timer_probe(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct rt_timer *rt; struct clk *clk; rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL); if (!rt) { dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } rt->irq = platform_get_irq(pdev, 0); if (!rt->irq) { dev_err(&pdev->dev, "failed to load irq\n"); return -ENOENT; } rt->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rt->membase)) return PTR_ERR(rt->membase); clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed get clock rate\n"); return PTR_ERR(clk); } rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV; if (!rt->timer_freq) return -EINVAL; rt->dev = &pdev->dev; platform_set_drvdata(pdev, rt); rt_timer_request(rt); rt_timer_config(rt, 2); rt_timer_enable(rt); dev_info(&pdev->dev, "maximum frequency is %luHz\n", rt->timer_freq); return 0; }