leds-ip30.c (1804B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * LED Driver for SGI Octane machines 4 */ 5 6#include <asm/io.h> 7#include <linux/module.h> 8#include <linux/kernel.h> 9#include <linux/platform_device.h> 10#include <linux/leds.h> 11 12#define IP30_LED_SYSTEM 0 13#define IP30_LED_FAULT 1 14 15struct ip30_led { 16 struct led_classdev cdev; 17 u32 __iomem *reg; 18}; 19 20static void ip30led_set(struct led_classdev *led_cdev, 21 enum led_brightness value) 22{ 23 struct ip30_led *led = container_of(led_cdev, struct ip30_led, cdev); 24 25 writel(value, led->reg); 26} 27 28static int ip30led_create(struct platform_device *pdev, int num) 29{ 30 struct resource *res; 31 struct ip30_led *data; 32 33 res = platform_get_resource(pdev, IORESOURCE_MEM, num); 34 if (!res) 35 return -EBUSY; 36 37 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 38 if (!data) 39 return -ENOMEM; 40 41 data->reg = devm_ioremap_resource(&pdev->dev, res); 42 if (IS_ERR(data->reg)) 43 return PTR_ERR(data->reg); 44 45 46 switch (num) { 47 case IP30_LED_SYSTEM: 48 data->cdev.name = "white:power"; 49 break; 50 case IP30_LED_FAULT: 51 data->cdev.name = "red:fault"; 52 break; 53 default: 54 return -EINVAL; 55 } 56 57 data->cdev.brightness = readl(data->reg); 58 data->cdev.max_brightness = 1; 59 data->cdev.brightness_set = ip30led_set; 60 61 return devm_led_classdev_register(&pdev->dev, &data->cdev); 62} 63 64static int ip30led_probe(struct platform_device *pdev) 65{ 66 int ret; 67 68 ret = ip30led_create(pdev, IP30_LED_SYSTEM); 69 if (ret < 0) 70 return ret; 71 72 return ip30led_create(pdev, IP30_LED_FAULT); 73} 74 75static struct platform_driver ip30led_driver = { 76 .probe = ip30led_probe, 77 .driver = { 78 .name = "ip30-leds", 79 }, 80}; 81 82module_platform_driver(ip30led_driver); 83 84MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>"); 85MODULE_DESCRIPTION("SGI Octane LED driver"); 86MODULE_LICENSE("GPL"); 87MODULE_ALIAS("platform:ip30-leds");