Commit 6c8f2df3 authored by Hans de Goede's avatar Hans de Goede

Merge tag 'intel-gpio-v5.14-1' into review-hans

intel-gpio for v5.14-1

* Export two functions from GPIO ACPI for wider use
* Clean up Whiskey Cove and Crystal Cove GPIO drivers

The following is an automated git shortlog grouped by driver:

crystalcove:
 -  remove platform_set_drvdata() + cleanup probe

gpiolib:
 -  acpi: Add acpi_gpio_get_io_resource()
 -  acpi: Introduce acpi_get_and_request_gpiod() helper

wcove:
 -  Split error handling for CTRL and IRQ registers
 -  Unify style of to_reg() with to_ireg()
 -  Use IRQ hardware number getter instead of direct access
parents cf80294e 043d7f09
...@@ -339,8 +339,6 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) ...@@ -339,8 +339,6 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
if (!cg) if (!cg)
return -ENOMEM; return -ENOMEM;
platform_set_drvdata(pdev, cg);
mutex_init(&cg->buslock); mutex_init(&cg->buslock);
cg->chip.label = KBUILD_MODNAME; cg->chip.label = KBUILD_MODNAME;
cg->chip.direction_input = crystalcove_gpio_dir_in; cg->chip.direction_input = crystalcove_gpio_dir_in;
...@@ -372,13 +370,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev) ...@@ -372,13 +370,7 @@ static int crystalcove_gpio_probe(struct platform_device *pdev)
return retval; return retval;
} }
retval = devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg); return devm_gpiochip_add_data(&pdev->dev, &cg->chip, cg);
if (retval) {
dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval);
return retval;
}
return 0;
} }
static struct platform_driver crystalcove_gpio_driver = { static struct platform_driver crystalcove_gpio_driver = {
......
...@@ -99,19 +99,14 @@ struct wcove_gpio { ...@@ -99,19 +99,14 @@ struct wcove_gpio {
bool set_irq_mask; bool set_irq_mask;
}; };
static inline int to_reg(int gpio, enum ctrl_register reg_type) static inline int to_reg(int gpio, enum ctrl_register type)
{ {
unsigned int reg; unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;
if (gpio >= WCOVE_GPIO_NUM) if (gpio >= WCOVE_GPIO_NUM)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (reg_type == CTRL_IN) return reg + gpio;
reg = GPIO_IN_CTRL_BASE + gpio;
else
reg = GPIO_OUT_CTRL_BASE + gpio;
return reg;
} }
static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask)
...@@ -129,7 +124,7 @@ static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask) ...@@ -129,7 +124,7 @@ static inline int to_ireg(int gpio, enum ctrl_register type, unsigned int *mask)
return reg; return reg;
} }
static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) static void wcove_update_irq_mask(struct wcove_gpio *wg, irq_hw_number_t gpio)
{ {
unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask); unsigned int mask, reg = to_ireg(gpio, IRQ_MASK, &mask);
...@@ -139,13 +134,10 @@ static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio) ...@@ -139,13 +134,10 @@ static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio)
regmap_clear_bits(wg->regmap, reg, mask); regmap_clear_bits(wg->regmap, reg, mask);
} }
static void wcove_update_irq_ctrl(struct wcove_gpio *wg, int gpio) static void wcove_update_irq_ctrl(struct wcove_gpio *wg, irq_hw_number_t gpio)
{ {
int reg = to_reg(gpio, CTRL_IN); int reg = to_reg(gpio, CTRL_IN);
if (reg < 0)
return;
regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt); regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt);
} }
...@@ -248,8 +240,9 @@ static int wcove_irq_type(struct irq_data *data, unsigned int type) ...@@ -248,8 +240,9 @@ static int wcove_irq_type(struct irq_data *data, unsigned int type)
{ {
struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct wcove_gpio *wg = gpiochip_get_data(chip); struct wcove_gpio *wg = gpiochip_get_data(chip);
irq_hw_number_t gpio = irqd_to_hwirq(data);
if (data->hwirq >= WCOVE_GPIO_NUM) if (gpio >= WCOVE_GPIO_NUM)
return 0; return 0;
switch (type) { switch (type) {
...@@ -286,7 +279,7 @@ static void wcove_bus_sync_unlock(struct irq_data *data) ...@@ -286,7 +279,7 @@ static void wcove_bus_sync_unlock(struct irq_data *data)
{ {
struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct wcove_gpio *wg = gpiochip_get_data(chip); struct wcove_gpio *wg = gpiochip_get_data(chip);
int gpio = data->hwirq; irq_hw_number_t gpio = irqd_to_hwirq(data);
if (wg->update & UPDATE_IRQ_TYPE) if (wg->update & UPDATE_IRQ_TYPE)
wcove_update_irq_ctrl(wg, gpio); wcove_update_irq_ctrl(wg, gpio);
...@@ -301,8 +294,9 @@ static void wcove_irq_unmask(struct irq_data *data) ...@@ -301,8 +294,9 @@ static void wcove_irq_unmask(struct irq_data *data)
{ {
struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct wcove_gpio *wg = gpiochip_get_data(chip); struct wcove_gpio *wg = gpiochip_get_data(chip);
irq_hw_number_t gpio = irqd_to_hwirq(data);
if (data->hwirq >= WCOVE_GPIO_NUM) if (gpio >= WCOVE_GPIO_NUM)
return; return;
wg->set_irq_mask = false; wg->set_irq_mask = false;
...@@ -313,8 +307,9 @@ static void wcove_irq_mask(struct irq_data *data) ...@@ -313,8 +307,9 @@ static void wcove_irq_mask(struct irq_data *data)
{ {
struct gpio_chip *chip = irq_data_get_irq_chip_data(data); struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
struct wcove_gpio *wg = gpiochip_get_data(chip); struct wcove_gpio *wg = gpiochip_get_data(chip);
irq_hw_number_t gpio = irqd_to_hwirq(data);
if (data->hwirq >= WCOVE_GPIO_NUM) if (gpio >= WCOVE_GPIO_NUM)
return; return;
wg->set_irq_mask = true; wg->set_irq_mask = true;
...@@ -369,8 +364,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) ...@@ -369,8 +364,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void wcove_gpio_dbg_show(struct seq_file *s, static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
struct gpio_chip *chip)
{ {
unsigned int ctlo, ctli, irq_mask, irq_status; unsigned int ctlo, ctli, irq_mask, irq_status;
struct wcove_gpio *wg = gpiochip_get_data(chip); struct wcove_gpio *wg = gpiochip_get_data(chip);
...@@ -379,10 +373,15 @@ static void wcove_gpio_dbg_show(struct seq_file *s, ...@@ -379,10 +373,15 @@ static void wcove_gpio_dbg_show(struct seq_file *s,
for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) { for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli); ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli);
if (ret) {
dev_err(wg->dev, "Failed to read registers: CTRL out/in\n");
break;
}
ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask); ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_MASK, &mask), &irq_mask);
ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status); ret += regmap_read(wg->regmap, to_ireg(gpio, IRQ_STATUS, &mask), &irq_status);
if (ret) { if (ret) {
pr_err("Failed to read registers: ctrl out/in or irq status/mask\n"); dev_err(wg->dev, "Failed to read registers: IRQ status/mask\n");
break; break;
} }
......
...@@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin) ...@@ -128,6 +128,34 @@ static struct gpio_desc *acpi_get_gpiod(char *path, int pin)
return gpiochip_get_desc(chip, pin); return gpiochip_get_desc(chip, pin);
} }
/**
* acpi_get_and_request_gpiod - Translate ACPI GPIO pin to GPIO descriptor and
* hold a refcount to the GPIO device.
* @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1")
* @pin: ACPI GPIO pin number (0-based, controller-relative)
* @label: Label to pass to gpiod_request()
*
* This function is a simple pass-through to acpi_get_gpiod(), except that
* as it is intended for use outside of the GPIO layer (in a similar fashion to
* gpiod_get_index() for example) it also holds a reference to the GPIO device.
*/
struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label)
{
struct gpio_desc *gpio;
int ret;
gpio = acpi_get_gpiod(path, pin);
if (IS_ERR(gpio))
return gpio;
ret = gpiod_request(gpio, label);
if (ret)
return ERR_PTR(ret);
return gpio;
}
EXPORT_SYMBOL_GPL(acpi_get_and_request_gpiod);
static irqreturn_t acpi_gpio_irq_handler(int irq, void *data) static irqreturn_t acpi_gpio_irq_handler(int irq, void *data)
{ {
struct acpi_gpio_event *event = data; struct acpi_gpio_event *event = data;
...@@ -168,6 +196,29 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, ...@@ -168,6 +196,29 @@ bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
} }
EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource); EXPORT_SYMBOL_GPL(acpi_gpio_get_irq_resource);
/**
* acpi_gpio_get_io_resource - Fetch details of an ACPI resource if it is a GPIO
* I/O resource or return False if not.
* @ares: Pointer to the ACPI resource to fetch
* @agpio: Pointer to a &struct acpi_resource_gpio to store the output pointer
*/
bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio)
{
struct acpi_resource_gpio *gpio;
if (ares->type != ACPI_RESOURCE_TYPE_GPIO)
return false;
gpio = &ares->data.gpio;
if (gpio->connection_type != ACPI_RESOURCE_GPIO_TYPE_IO)
return false;
*agpio = gpio;
return true;
}
EXPORT_SYMBOL_GPL(acpi_gpio_get_io_resource);
static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio, static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
struct acpi_gpio_event *event) struct acpi_gpio_event *event)
{ {
......
...@@ -1096,6 +1096,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c ...@@ -1096,6 +1096,8 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
#if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB) #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio); struct acpi_resource_gpio **agpio);
bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio);
int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index); int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int index);
#else #else
static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
...@@ -1103,6 +1105,11 @@ static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares, ...@@ -1103,6 +1105,11 @@ static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
{ {
return false; return false;
} }
static inline bool acpi_gpio_get_io_resource(struct acpi_resource *ares,
struct acpi_resource_gpio **agpio)
{
return false;
}
static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, static inline int acpi_dev_gpio_irq_get_by(struct acpi_device *adev,
const char *name, int index) const char *name, int index)
{ {
......
...@@ -692,6 +692,8 @@ int devm_acpi_dev_add_driver_gpios(struct device *dev, ...@@ -692,6 +692,8 @@ int devm_acpi_dev_add_driver_gpios(struct device *dev,
const struct acpi_gpio_mapping *gpios); const struct acpi_gpio_mapping *gpios);
void devm_acpi_dev_remove_driver_gpios(struct device *dev); void devm_acpi_dev_remove_driver_gpios(struct device *dev);
struct gpio_desc *acpi_get_and_request_gpiod(char *path, int pin, char *label);
#else /* CONFIG_GPIOLIB && CONFIG_ACPI */ #else /* CONFIG_GPIOLIB && CONFIG_ACPI */
struct acpi_device; struct acpi_device;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment