Skip to content

Commit d5f4fa6

Browse files
author
Linus Walleij
committed
ARM/gpio: Push OMAP2 quirk down into TWL4030 driver
The TWL4030 GPIO driver has a custom platform data .set_up() callback to call back into the platform and do misc stuff such as hog and export a GPIO for WLAN PWR on a specific OMAP3 board. Avoid all the kludgery in the platform data and the boardfile and just put the quirks right into the driver. Make it conditional on OMAP3. I think the exported GPIO is used by some kind of userspace so ordinary DTS hogs will probably not work. Fixes: 92bf78b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent c729baa commit d5f4fa6

4 files changed

Lines changed: 37 additions & 60 deletions

File tree

arch/arm/mach-omap2/omap_device.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
244244
case BUS_NOTIFY_ADD_DEVICE:
245245
if (pdev->dev.of_node)
246246
omap_device_build_from_dt(pdev);
247-
omap_auxdata_legacy_init(dev);
248247
fallthrough;
249248
default:
250249
od = to_omap_device(pdev);

arch/arm/mach-omap2/pdata-quirks.c

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
#include <linux/clk.h>
88
#include <linux/davinci_emac.h>
9+
#include <linux/gpio/machine.h>
910
#include <linux/gpio/consumer.h>
1011
#include <linux/gpio.h>
1112
#include <linux/init.h>
@@ -41,7 +42,6 @@ struct pdata_init {
4142
};
4243

4344
static struct of_dev_auxdata omap_auxdata_lookup[];
44-
static struct twl4030_gpio_platform_data twl_gpio_auxdata;
4545

4646
#ifdef CONFIG_MACH_NOKIA_N8X0
4747
static void __init omap2420_n8x0_legacy_init(void)
@@ -98,22 +98,6 @@ static struct iommu_platform_data omap3_iommu_isp_pdata = {
9898
};
9999
#endif
100100

101-
static int omap3_sbc_t3730_twl_callback(struct device *dev,
102-
unsigned gpio,
103-
unsigned ngpio)
104-
{
105-
int res;
106-
107-
res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
108-
"wlan pwr");
109-
if (res)
110-
return res;
111-
112-
gpiod_export(gpio_to_desc(gpio), 0);
113-
114-
return 0;
115-
}
116-
117101
static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
118102
{
119103
int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name);
@@ -131,11 +115,6 @@ static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
131115
msleep(1);
132116
}
133117

134-
static void __init omap3_sbc_t3730_twl_init(void)
135-
{
136-
twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback;
137-
}
138-
139118
static void __init omap3_sbc_t3730_legacy_init(void)
140119
{
141120
omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
@@ -393,21 +372,6 @@ static struct ti_prm_platform_data ti_prm_pdata = {
393372
.clkdm_lookup = clkdm_lookup,
394373
};
395374

396-
/*
397-
* GPIOs for TWL are initialized by the I2C bus and need custom
398-
* handing until DSS has device tree bindings.
399-
*/
400-
void omap_auxdata_legacy_init(struct device *dev)
401-
{
402-
if (dev->platform_data)
403-
return;
404-
405-
if (strcmp("twl4030-gpio", dev_name(dev)))
406-
return;
407-
408-
dev->platform_data = &twl_gpio_auxdata;
409-
}
410-
411375
#if defined(CONFIG_ARCH_OMAP3) && IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP)
412376
static struct omap_mcbsp_platform_data mcbsp_pdata;
413377
static void __init omap3_mcbsp_init(void)
@@ -427,9 +391,6 @@ static struct pdata_init auxdata_quirks[] __initdata = {
427391
{ "nokia,n800", omap2420_n8x0_legacy_init, },
428392
{ "nokia,n810", omap2420_n8x0_legacy_init, },
429393
{ "nokia,n810-wimax", omap2420_n8x0_legacy_init, },
430-
#endif
431-
#ifdef CONFIG_ARCH_OMAP3
432-
{ "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, },
433394
#endif
434395
{ /* sentinel */ },
435396
};

drivers/gpio/gpio-twl4030.c

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#include <linux/interrupt.h>
1818
#include <linux/kthread.h>
1919
#include <linux/irq.h>
20+
#include <linux/gpio/machine.h>
2021
#include <linux/gpio/driver.h>
22+
#include <linux/gpio/consumer.h>
2123
#include <linux/platform_device.h>
2224
#include <linux/of.h>
2325
#include <linux/irqdomain.h>
@@ -465,18 +467,14 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
465467
REG_GPIO_DEBEN1, 3);
466468
}
467469

468-
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
469-
struct twl4030_gpio_platform_data *pdata)
470+
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
470471
{
471472
struct twl4030_gpio_platform_data *omap_twl_info;
472473

473474
omap_twl_info = devm_kzalloc(dev, sizeof(*omap_twl_info), GFP_KERNEL);
474475
if (!omap_twl_info)
475476
return NULL;
476477

477-
if (pdata)
478-
*omap_twl_info = *pdata;
479-
480478
omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
481479
"ti,use-leds");
482480

@@ -504,9 +502,18 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
504502
return 0;
505503
}
506504

505+
/* Called from the registered devm action */
506+
static void gpio_twl4030_power_off_action(void *data)
507+
{
508+
struct gpio_desc *d = data;
509+
510+
gpiod_unexport(d);
511+
gpiochip_free_own_desc(d);
512+
}
513+
507514
static int gpio_twl4030_probe(struct platform_device *pdev)
508515
{
509-
struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
516+
struct twl4030_gpio_platform_data *pdata;
510517
struct device_node *node = pdev->dev.of_node;
511518
struct gpio_twl4030_priv *priv;
512519
int ret, irq_base;
@@ -546,9 +553,7 @@ static int gpio_twl4030_probe(struct platform_device *pdev)
546553

547554
mutex_init(&priv->mutex);
548555

549-
if (node)
550-
pdata = of_gpio_twl4030(&pdev->dev, pdata);
551-
556+
pdata = of_gpio_twl4030(&pdev->dev);
552557
if (pdata == NULL) {
553558
dev_err(&pdev->dev, "Platform data is missing\n");
554559
return -ENXIO;
@@ -585,17 +590,32 @@ static int gpio_twl4030_probe(struct platform_device *pdev)
585590
goto out;
586591
}
587592

588-
platform_set_drvdata(pdev, priv);
593+
/*
594+
* Special quirk for the OMAP3 to hog and export a WLAN power
595+
* GPIO.
596+
*/
597+
if (IS_ENABLED(CONFIG_ARCH_OMAP3) &&
598+
of_machine_is_compatible("compulab,omap3-sbc-t3730")) {
599+
struct gpio_desc *d;
589600

590-
if (pdata->setup) {
591-
int status;
601+
d = gpiochip_request_own_desc(&priv->gpio_chip,
602+
2, "wlan pwr",
603+
GPIO_ACTIVE_HIGH,
604+
GPIOD_OUT_HIGH);
605+
if (IS_ERR(d))
606+
return dev_err_probe(&pdev->dev, PTR_ERR(d),
607+
"unable to hog wlan pwr GPIO\n");
608+
609+
gpiod_export(d, 0);
610+
611+
ret = devm_add_action_or_reset(&pdev->dev, gpio_twl4030_power_off_action, d);
612+
if (ret)
613+
return dev_err_probe(&pdev->dev, ret,
614+
"failed to install power off handler\n");
592615

593-
status = pdata->setup(&pdev->dev, priv->gpio_chip.base,
594-
TWL4030_GPIO_MAX);
595-
if (status)
596-
dev_dbg(&pdev->dev, "setup --> %d\n", status);
597616
}
598617

618+
platform_set_drvdata(pdev, priv);
599619
out:
600620
return ret;
601621
}

include/linux/mfd/twl.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,6 @@ struct twl4030_gpio_platform_data {
593593
*/
594594
u32 pullups;
595595
u32 pulldowns;
596-
597-
int (*setup)(struct device *dev,
598-
unsigned gpio, unsigned ngpio);
599596
};
600597

601598
struct twl4030_madc_platform_data {

0 commit comments

Comments
 (0)