|
@@ -19,22 +19,6 @@
|
|
|
#include <linux/bitops.h>
|
|
|
#include <linux/gpio.h>
|
|
|
|
|
|
-static struct pinmux_info *registered_gpio;
|
|
|
-
|
|
|
-static struct pinmux_info *gpio_controller(unsigned gpio)
|
|
|
-{
|
|
|
- if (!registered_gpio)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- if (gpio < registered_gpio->first_gpio)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- if (gpio > registered_gpio->last_gpio)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- return registered_gpio;
|
|
|
-}
|
|
|
-
|
|
|
static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
|
|
|
{
|
|
|
if (enum_id < r->begin)
|
|
@@ -398,9 +382,14 @@ static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
|
|
|
|
|
|
static DEFINE_SPINLOCK(gpio_lock);
|
|
|
|
|
|
-int __gpio_request(unsigned gpio)
|
|
|
+static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
|
|
|
{
|
|
|
- struct pinmux_info *gpioc = gpio_controller(gpio);
|
|
|
+ return container_of(chip, struct pinmux_info, chip);
|
|
|
+}
|
|
|
+
|
|
|
+static int sh_gpio_request(struct gpio_chip *chip, unsigned offset)
|
|
|
+{
|
|
|
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
|
|
|
struct pinmux_data_reg *dummy;
|
|
|
unsigned long flags;
|
|
|
int i, ret, pinmux_type;
|
|
@@ -412,30 +401,30 @@ int __gpio_request(unsigned gpio)
|
|
|
|
|
|
spin_lock_irqsave(&gpio_lock, flags);
|
|
|
|
|
|
- if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
|
|
|
+ if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
|
|
|
goto err_unlock;
|
|
|
|
|
|
/* setup pin function here if no data is associated with pin */
|
|
|
|
|
|
- if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
|
|
|
+ if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
|
|
|
pinmux_type = PINMUX_TYPE_FUNCTION;
|
|
|
else
|
|
|
pinmux_type = PINMUX_TYPE_GPIO;
|
|
|
|
|
|
if (pinmux_type == PINMUX_TYPE_FUNCTION) {
|
|
|
- if (pinmux_config_gpio(gpioc, gpio,
|
|
|
+ if (pinmux_config_gpio(gpioc, offset,
|
|
|
pinmux_type,
|
|
|
GPIO_CFG_DRYRUN) != 0)
|
|
|
goto err_unlock;
|
|
|
|
|
|
- if (pinmux_config_gpio(gpioc, gpio,
|
|
|
+ if (pinmux_config_gpio(gpioc, offset,
|
|
|
pinmux_type,
|
|
|
GPIO_CFG_REQ) != 0)
|
|
|
BUG();
|
|
|
}
|
|
|
|
|
|
- gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
|
|
|
- gpioc->gpios[gpio].flags |= pinmux_type;
|
|
|
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
|
|
|
+ gpioc->gpios[offset].flags |= pinmux_type;
|
|
|
|
|
|
ret = 0;
|
|
|
err_unlock:
|
|
@@ -443,11 +432,10 @@ int __gpio_request(unsigned gpio)
|
|
|
err_out:
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(__gpio_request);
|
|
|
|
|
|
-void gpio_free(unsigned gpio)
|
|
|
+static void sh_gpio_free(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
- struct pinmux_info *gpioc = gpio_controller(gpio);
|
|
|
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
|
|
|
unsigned long flags;
|
|
|
int pinmux_type;
|
|
|
|
|
@@ -456,14 +444,13 @@ void gpio_free(unsigned gpio)
|
|
|
|
|
|
spin_lock_irqsave(&gpio_lock, flags);
|
|
|
|
|
|
- pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
|
|
|
- pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
|
|
|
- gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
|
|
|
- gpioc->gpios[gpio].flags |= PINMUX_TYPE_NONE;
|
|
|
+ pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
|
|
|
+ pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
|
|
|
+ gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
|
|
|
+ gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
|
|
|
|
|
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gpio_free);
|
|
|
|
|
|
static int pinmux_direction(struct pinmux_info *gpioc,
|
|
|
unsigned gpio, int new_pinmux_type)
|
|
@@ -507,21 +494,20 @@ static int pinmux_direction(struct pinmux_info *gpioc,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-int gpio_direction_input(unsigned gpio)
|
|
|
+static int sh_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
- struct pinmux_info *gpioc = gpio_controller(gpio);
|
|
|
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
|
|
|
unsigned long flags;
|
|
|
int ret;
|
|
|
|
|
|
spin_lock_irqsave(&gpio_lock, flags);
|
|
|
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
|
|
|
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
|
|
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gpio_direction_input);
|
|
|
|
|
|
-static void __gpio_set_value(struct pinmux_info *gpioc,
|
|
|
+static void sh_gpio_set_value(struct pinmux_info *gpioc,
|
|
|
unsigned gpio, int value)
|
|
|
{
|
|
|
struct pinmux_data_reg *dr = NULL;
|
|
@@ -533,22 +519,22 @@ static void __gpio_set_value(struct pinmux_info *gpioc,
|
|
|
gpio_write_bit(dr, bit, value);
|
|
|
}
|
|
|
|
|
|
-int gpio_direction_output(unsigned gpio, int value)
|
|
|
+static int sh_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
|
|
|
+ int value)
|
|
|
{
|
|
|
- struct pinmux_info *gpioc = gpio_controller(gpio);
|
|
|
+ struct pinmux_info *gpioc = chip_to_pinmux(chip);
|
|
|
unsigned long flags;
|
|
|
int ret;
|
|
|
|
|
|
- __gpio_set_value(gpioc, gpio, value);
|
|
|
+ sh_gpio_set_value(gpioc, offset, value);
|
|
|
spin_lock_irqsave(&gpio_lock, flags);
|
|
|
- ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
|
|
|
+ ret = pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
|
|
|
spin_unlock_irqrestore(&gpio_lock, flags);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gpio_direction_output);
|
|
|
|
|
|
-static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
|
|
|
+static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
|
|
|
{
|
|
|
struct pinmux_data_reg *dr = NULL;
|
|
|
int bit = 0;
|
|
@@ -561,24 +547,38 @@ static int __gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
|
|
|
return gpio_read_reg(dr->reg, dr->reg_width, 1, bit);
|
|
|
}
|
|
|
|
|
|
-int gpio_get_value(unsigned gpio)
|
|
|
+static int sh_gpio_get(struct gpio_chip *chip, unsigned offset)
|
|
|
{
|
|
|
- return __gpio_get_value(gpio_controller(gpio), gpio);
|
|
|
+ return sh_gpio_get_value(chip_to_pinmux(chip), offset);
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gpio_get_value);
|
|
|
|
|
|
-void gpio_set_value(unsigned gpio, int value)
|
|
|
+static void sh_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|
|
{
|
|
|
- __gpio_set_value(gpio_controller(gpio), gpio, value);
|
|
|
+ sh_gpio_set_value(chip_to_pinmux(chip), offset, value);
|
|
|
}
|
|
|
-EXPORT_SYMBOL(gpio_set_value);
|
|
|
|
|
|
int register_pinmux(struct pinmux_info *pip)
|
|
|
{
|
|
|
- registered_gpio = pip;
|
|
|
- setup_data_regs(pip);
|
|
|
- pr_info("pinmux: %s handling gpio %d -> %d\n",
|
|
|
+ struct gpio_chip *chip = &pip->chip;
|
|
|
+
|
|
|
+ pr_info("sh pinmux: %s handling gpio %d -> %d\n",
|
|
|
pip->name, pip->first_gpio, pip->last_gpio);
|
|
|
|
|
|
- return 0;
|
|
|
+ setup_data_regs(pip);
|
|
|
+
|
|
|
+ chip->request = sh_gpio_request;
|
|
|
+ chip->free = sh_gpio_free;
|
|
|
+ chip->direction_input = sh_gpio_direction_input;
|
|
|
+ chip->get = sh_gpio_get;
|
|
|
+ chip->direction_output = sh_gpio_direction_output;
|
|
|
+ chip->set = sh_gpio_set;
|
|
|
+
|
|
|
+ WARN_ON(pip->first_gpio != 0); /* needs testing */
|
|
|
+
|
|
|
+ chip->label = pip->name;
|
|
|
+ chip->owner = THIS_MODULE;
|
|
|
+ chip->base = pip->first_gpio;
|
|
|
+ chip->ngpio = (pip->last_gpio - pip->first_gpio) + 1;
|
|
|
+
|
|
|
+ return gpiochip_add(chip);
|
|
|
}
|