cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

led.c (2910B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <net/mac80211.h>
      3#include <linux/bcma/bcma_driver_chipcommon.h>
      4#include <linux/gpio/driver.h>
      5#include <linux/gpio/machine.h>
      6#include <linux/gpio/consumer.h>
      7
      8#include "mac80211_if.h"
      9#include "pub.h"
     10#include "main.h"
     11#include "led.h"
     12
     13	/* number of leds */
     14#define  BRCMS_LED_NO		4
     15	/* behavior mask */
     16#define  BRCMS_LED_BEH_MASK	0x7f
     17	/* activelow (polarity) bit */
     18#define  BRCMS_LED_AL_MASK	0x80
     19	/* radio enabled */
     20#define  BRCMS_LED_RADIO	3
     21
     22static void brcms_radio_led_ctrl(struct brcms_info *wl, bool state)
     23{
     24	if (!wl->radio_led.gpiod)
     25		return;
     26
     27	if (state)
     28		gpiod_set_value(wl->radio_led.gpiod, 1);
     29	else
     30		gpiod_set_value(wl->radio_led.gpiod, 0);
     31}
     32
     33
     34/* Callback from the LED subsystem. */
     35static void brcms_led_brightness_set(struct led_classdev *led_dev,
     36				   enum led_brightness brightness)
     37{
     38	struct brcms_info *wl = container_of(led_dev,
     39		struct brcms_info, led_dev);
     40	brcms_radio_led_ctrl(wl, brightness);
     41}
     42
     43void brcms_led_unregister(struct brcms_info *wl)
     44{
     45	if (wl->led_dev.dev)
     46		led_classdev_unregister(&wl->led_dev);
     47	if (wl->radio_led.gpiod)
     48		gpiochip_free_own_desc(wl->radio_led.gpiod);
     49}
     50
     51int brcms_led_register(struct brcms_info *wl)
     52{
     53	int i, err;
     54	struct brcms_led *radio_led = &wl->radio_led;
     55	/* get CC core */
     56	struct bcma_drv_cc *cc_drv  = &wl->wlc->hw->d11core->bus->drv_cc;
     57	struct gpio_chip *bcma_gpio = &cc_drv->gpio;
     58	struct ssb_sprom *sprom = &wl->wlc->hw->d11core->bus->sprom;
     59	u8 *leds[] = { &sprom->gpio0,
     60		&sprom->gpio1,
     61		&sprom->gpio2,
     62		&sprom->gpio3 };
     63	int hwnum = -1;
     64	enum gpio_lookup_flags lflags = GPIO_ACTIVE_HIGH;
     65
     66	if (!bcma_gpio || !gpio_is_valid(bcma_gpio->base))
     67		return -ENODEV;
     68
     69	/* find radio enabled LED */
     70	for (i = 0; i < BRCMS_LED_NO; i++) {
     71		u8 led = *leds[i];
     72		if ((led & BRCMS_LED_BEH_MASK) == BRCMS_LED_RADIO) {
     73			hwnum = i;
     74			if (led & BRCMS_LED_AL_MASK)
     75				lflags = GPIO_ACTIVE_LOW;
     76			break;
     77		}
     78	}
     79
     80	/* No LED, bail out */
     81	if (hwnum == -1)
     82		return -ENODEV;
     83
     84	/* Try to obtain this LED GPIO line */
     85	radio_led->gpiod = gpiochip_request_own_desc(bcma_gpio, hwnum,
     86						     "radio on", lflags,
     87						     GPIOD_OUT_LOW);
     88
     89	if (IS_ERR(radio_led->gpiod)) {
     90		err = PTR_ERR(radio_led->gpiod);
     91		wiphy_err(wl->wiphy, "requesting led GPIO failed (err: %d)\n",
     92			  err);
     93		return err;
     94	}
     95
     96	snprintf(wl->radio_led.name, sizeof(wl->radio_led.name),
     97		 "brcmsmac-%s:radio", wiphy_name(wl->wiphy));
     98
     99	wl->led_dev.name = wl->radio_led.name;
    100	wl->led_dev.default_trigger =
    101		ieee80211_get_radio_led_name(wl->pub->ieee_hw);
    102	wl->led_dev.brightness_set = brcms_led_brightness_set;
    103	err = led_classdev_register(wiphy_dev(wl->wiphy), &wl->led_dev);
    104
    105	if (err) {
    106		wiphy_err(wl->wiphy, "cannot register led device: %s (err: %d)\n",
    107			  wl->radio_led.name, err);
    108		return err;
    109	}
    110
    111	wiphy_info(wl->wiphy, "registered radio enabled led device: %s\n",
    112		   wl->radio_led.name);
    113
    114	return 0;
    115}