root/drivers/leds/leds-sunfire.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __clockboard_set
  2. clockboard_left_set
  3. clockboard_middle_set
  4. clockboard_right_set
  5. __fhc_set
  6. fhc_left_set
  7. fhc_middle_set
  8. fhc_right_set
  9. sunfire_led_generic_probe
  10. sunfire_led_generic_remove
  11. sunfire_clockboard_led_probe
  12. sunfire_fhc_led_probe
  13. sunfire_leds_init
  14. sunfire_leds_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /* leds-sunfire.c: SUNW,Ultra-Enterprise LED driver.
   3  *
   4  * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
   5  */
   6 
   7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/module.h>
  11 #include <linux/init.h>
  12 #include <linux/leds.h>
  13 #include <linux/io.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/slab.h>
  16 
  17 #include <asm/fhc.h>
  18 #include <asm/upa.h>
  19 
  20 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
  21 MODULE_DESCRIPTION("Sun Fire LED driver");
  22 MODULE_LICENSE("GPL");
  23 
  24 struct sunfire_led {
  25         struct led_classdev     led_cdev;
  26         void __iomem            *reg;
  27 };
  28 #define to_sunfire_led(d) container_of(d, struct sunfire_led, led_cdev)
  29 
  30 static void __clockboard_set(struct led_classdev *led_cdev,
  31                              enum led_brightness led_val, u8 bit)
  32 {
  33         struct sunfire_led *p = to_sunfire_led(led_cdev);
  34         u8 reg = upa_readb(p->reg);
  35 
  36         switch (bit) {
  37         case CLOCK_CTRL_LLED:
  38                 if (led_val)
  39                         reg &= ~bit;
  40                 else
  41                         reg |= bit;
  42                 break;
  43 
  44         default:
  45                 if (led_val)
  46                         reg |= bit;
  47                 else
  48                         reg &= ~bit;
  49                 break;
  50         }
  51         upa_writeb(reg, p->reg);
  52 }
  53 
  54 static void clockboard_left_set(struct led_classdev *led_cdev,
  55                                 enum led_brightness led_val)
  56 {
  57         __clockboard_set(led_cdev, led_val, CLOCK_CTRL_LLED);
  58 }
  59 
  60 static void clockboard_middle_set(struct led_classdev *led_cdev,
  61                                   enum led_brightness led_val)
  62 {
  63         __clockboard_set(led_cdev, led_val, CLOCK_CTRL_MLED);
  64 }
  65 
  66 static void clockboard_right_set(struct led_classdev *led_cdev,
  67                                  enum led_brightness led_val)
  68 {
  69         __clockboard_set(led_cdev, led_val, CLOCK_CTRL_RLED);
  70 }
  71 
  72 static void __fhc_set(struct led_classdev *led_cdev,
  73                              enum led_brightness led_val, u32 bit)
  74 {
  75         struct sunfire_led *p = to_sunfire_led(led_cdev);
  76         u32 reg = upa_readl(p->reg);
  77 
  78         switch (bit) {
  79         case FHC_CONTROL_LLED:
  80                 if (led_val)
  81                         reg &= ~bit;
  82                 else
  83                         reg |= bit;
  84                 break;
  85 
  86         default:
  87                 if (led_val)
  88                         reg |= bit;
  89                 else
  90                         reg &= ~bit;
  91                 break;
  92         }
  93         upa_writel(reg, p->reg);
  94 }
  95 
  96 static void fhc_left_set(struct led_classdev *led_cdev,
  97                          enum led_brightness led_val)
  98 {
  99         __fhc_set(led_cdev, led_val, FHC_CONTROL_LLED);
 100 }
 101 
 102 static void fhc_middle_set(struct led_classdev *led_cdev,
 103                            enum led_brightness led_val)
 104 {
 105         __fhc_set(led_cdev, led_val, FHC_CONTROL_MLED);
 106 }
 107 
 108 static void fhc_right_set(struct led_classdev *led_cdev,
 109                           enum led_brightness led_val)
 110 {
 111         __fhc_set(led_cdev, led_val, FHC_CONTROL_RLED);
 112 }
 113 
 114 typedef void (*set_handler)(struct led_classdev *, enum led_brightness);
 115 struct led_type {
 116         const char      *name;
 117         set_handler     handler;
 118         const char      *default_trigger;
 119 };
 120 
 121 #define NUM_LEDS_PER_BOARD      3
 122 struct sunfire_drvdata {
 123         struct sunfire_led      leds[NUM_LEDS_PER_BOARD];
 124 };
 125 
 126 static int sunfire_led_generic_probe(struct platform_device *pdev,
 127                                                struct led_type *types)
 128 {
 129         struct sunfire_drvdata *p;
 130         int i, err;
 131 
 132         if (pdev->num_resources != 1) {
 133                 dev_err(&pdev->dev, "Wrong number of resources %d, should be 1\n",
 134                        pdev->num_resources);
 135                 return -EINVAL;
 136         }
 137 
 138         p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
 139         if (!p)
 140                 return -ENOMEM;
 141 
 142         for (i = 0; i < NUM_LEDS_PER_BOARD; i++) {
 143                 struct led_classdev *lp = &p->leds[i].led_cdev;
 144 
 145                 p->leds[i].reg = (void __iomem *) pdev->resource[0].start;
 146                 lp->name = types[i].name;
 147                 lp->brightness = LED_FULL;
 148                 lp->brightness_set = types[i].handler;
 149                 lp->default_trigger = types[i].default_trigger;
 150 
 151                 err = led_classdev_register(&pdev->dev, lp);
 152                 if (err) {
 153                         dev_err(&pdev->dev, "Could not register %s LED\n",
 154                                lp->name);
 155                         for (i--; i >= 0; i--)
 156                                 led_classdev_unregister(&p->leds[i].led_cdev);
 157                         return err;
 158                 }
 159         }
 160 
 161         platform_set_drvdata(pdev, p);
 162 
 163         return 0;
 164 }
 165 
 166 static int sunfire_led_generic_remove(struct platform_device *pdev)
 167 {
 168         struct sunfire_drvdata *p = platform_get_drvdata(pdev);
 169         int i;
 170 
 171         for (i = 0; i < NUM_LEDS_PER_BOARD; i++)
 172                 led_classdev_unregister(&p->leds[i].led_cdev);
 173 
 174         return 0;
 175 }
 176 
 177 static struct led_type clockboard_led_types[NUM_LEDS_PER_BOARD] = {
 178         {
 179                 .name           = "clockboard-left",
 180                 .handler        = clockboard_left_set,
 181         },
 182         {
 183                 .name           = "clockboard-middle",
 184                 .handler        = clockboard_middle_set,
 185         },
 186         {
 187                 .name           = "clockboard-right",
 188                 .handler        = clockboard_right_set,
 189                 .default_trigger = "heartbeat",
 190         },
 191 };
 192 
 193 static int sunfire_clockboard_led_probe(struct platform_device *pdev)
 194 {
 195         return sunfire_led_generic_probe(pdev, clockboard_led_types);
 196 }
 197 
 198 static struct led_type fhc_led_types[NUM_LEDS_PER_BOARD] = {
 199         {
 200                 .name           = "fhc-left",
 201                 .handler        = fhc_left_set,
 202         },
 203         {
 204                 .name           = "fhc-middle",
 205                 .handler        = fhc_middle_set,
 206         },
 207         {
 208                 .name           = "fhc-right",
 209                 .handler        = fhc_right_set,
 210                 .default_trigger = "heartbeat",
 211         },
 212 };
 213 
 214 static int sunfire_fhc_led_probe(struct platform_device *pdev)
 215 {
 216         return sunfire_led_generic_probe(pdev, fhc_led_types);
 217 }
 218 
 219 MODULE_ALIAS("platform:sunfire-clockboard-leds");
 220 MODULE_ALIAS("platform:sunfire-fhc-leds");
 221 
 222 static struct platform_driver sunfire_clockboard_led_driver = {
 223         .probe          = sunfire_clockboard_led_probe,
 224         .remove         = sunfire_led_generic_remove,
 225         .driver         = {
 226                 .name   = "sunfire-clockboard-leds",
 227         },
 228 };
 229 
 230 static struct platform_driver sunfire_fhc_led_driver = {
 231         .probe          = sunfire_fhc_led_probe,
 232         .remove         = sunfire_led_generic_remove,
 233         .driver         = {
 234                 .name   = "sunfire-fhc-leds",
 235         },
 236 };
 237 
 238 static struct platform_driver * const drivers[] = {
 239         &sunfire_clockboard_led_driver,
 240         &sunfire_fhc_led_driver,
 241 };
 242 
 243 static int __init sunfire_leds_init(void)
 244 {
 245         return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
 246 }
 247 
 248 static void __exit sunfire_leds_exit(void)
 249 {
 250         platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
 251 }
 252 
 253 module_init(sunfire_leds_init);
 254 module_exit(sunfire_leds_exit);

/* [<][>][^][v][top][bottom][index][help] */