mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 22:02:28 +00:00
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: 92bf78b33b
("gpio: omap: use dynamic allocation of base")
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
c729baa860
commit
d5f4fa60d6
@ -244,7 +244,6 @@ static int _omap_device_notifier_call(struct notifier_block *nb,
|
||||
case BUS_NOTIFY_ADD_DEVICE:
|
||||
if (pdev->dev.of_node)
|
||||
omap_device_build_from_dt(pdev);
|
||||
omap_auxdata_legacy_init(dev);
|
||||
fallthrough;
|
||||
default:
|
||||
od = to_omap_device(pdev);
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
#include <linux/clk.h>
|
||||
#include <linux/davinci_emac.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/init.h>
|
||||
@ -41,7 +42,6 @@ struct pdata_init {
|
||||
};
|
||||
|
||||
static struct of_dev_auxdata omap_auxdata_lookup[];
|
||||
static struct twl4030_gpio_platform_data twl_gpio_auxdata;
|
||||
|
||||
#ifdef CONFIG_MACH_NOKIA_N8X0
|
||||
static void __init omap2420_n8x0_legacy_init(void)
|
||||
@ -98,22 +98,6 @@ static struct iommu_platform_data omap3_iommu_isp_pdata = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int omap3_sbc_t3730_twl_callback(struct device *dev,
|
||||
unsigned gpio,
|
||||
unsigned ngpio)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
|
||||
"wlan pwr");
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
gpiod_export(gpio_to_desc(gpio), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name)
|
||||
{
|
||||
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)
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
static void __init omap3_sbc_t3730_twl_init(void)
|
||||
{
|
||||
twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback;
|
||||
}
|
||||
|
||||
static void __init omap3_sbc_t3730_legacy_init(void)
|
||||
{
|
||||
omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
|
||||
@ -393,21 +372,6 @@ static struct ti_prm_platform_data ti_prm_pdata = {
|
||||
.clkdm_lookup = clkdm_lookup,
|
||||
};
|
||||
|
||||
/*
|
||||
* GPIOs for TWL are initialized by the I2C bus and need custom
|
||||
* handing until DSS has device tree bindings.
|
||||
*/
|
||||
void omap_auxdata_legacy_init(struct device *dev)
|
||||
{
|
||||
if (dev->platform_data)
|
||||
return;
|
||||
|
||||
if (strcmp("twl4030-gpio", dev_name(dev)))
|
||||
return;
|
||||
|
||||
dev->platform_data = &twl_gpio_auxdata;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3) && IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP)
|
||||
static struct omap_mcbsp_platform_data mcbsp_pdata;
|
||||
static void __init omap3_mcbsp_init(void)
|
||||
@ -427,9 +391,6 @@ static struct pdata_init auxdata_quirks[] __initdata = {
|
||||
{ "nokia,n800", omap2420_n8x0_legacy_init, },
|
||||
{ "nokia,n810", omap2420_n8x0_legacy_init, },
|
||||
{ "nokia,n810-wimax", omap2420_n8x0_legacy_init, },
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_OMAP3
|
||||
{ "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, },
|
||||
#endif
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
@ -17,7 +17,9 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/irqdomain.h>
|
||||
@ -465,8 +467,7 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd)
|
||||
REG_GPIO_DEBEN1, 3);
|
||||
}
|
||||
|
||||
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
|
||||
struct twl4030_gpio_platform_data *pdata)
|
||||
static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev)
|
||||
{
|
||||
struct twl4030_gpio_platform_data *omap_twl_info;
|
||||
|
||||
@ -474,9 +475,6 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev,
|
||||
if (!omap_twl_info)
|
||||
return NULL;
|
||||
|
||||
if (pdata)
|
||||
*omap_twl_info = *pdata;
|
||||
|
||||
omap_twl_info->use_leds = of_property_read_bool(dev->of_node,
|
||||
"ti,use-leds");
|
||||
|
||||
@ -504,9 +502,18 @@ static int gpio_twl4030_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called from the registered devm action */
|
||||
static void gpio_twl4030_power_off_action(void *data)
|
||||
{
|
||||
struct gpio_desc *d = data;
|
||||
|
||||
gpiod_unexport(d);
|
||||
gpiochip_free_own_desc(d);
|
||||
}
|
||||
|
||||
static int gpio_twl4030_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct twl4030_gpio_platform_data *pdata;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct gpio_twl4030_priv *priv;
|
||||
int ret, irq_base;
|
||||
@ -546,9 +553,7 @@ no_irqs:
|
||||
|
||||
mutex_init(&priv->mutex);
|
||||
|
||||
if (node)
|
||||
pdata = of_gpio_twl4030(&pdev->dev, pdata);
|
||||
|
||||
pdata = of_gpio_twl4030(&pdev->dev);
|
||||
if (pdata == NULL) {
|
||||
dev_err(&pdev->dev, "Platform data is missing\n");
|
||||
return -ENXIO;
|
||||
@ -585,17 +590,32 @@ no_irqs:
|
||||
goto out;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
/*
|
||||
* Special quirk for the OMAP3 to hog and export a WLAN power
|
||||
* GPIO.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_ARCH_OMAP3) &&
|
||||
of_machine_is_compatible("compulab,omap3-sbc-t3730")) {
|
||||
struct gpio_desc *d;
|
||||
|
||||
if (pdata->setup) {
|
||||
int status;
|
||||
d = gpiochip_request_own_desc(&priv->gpio_chip,
|
||||
2, "wlan pwr",
|
||||
GPIO_ACTIVE_HIGH,
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(d))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(d),
|
||||
"unable to hog wlan pwr GPIO\n");
|
||||
|
||||
gpiod_export(d, 0);
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev, gpio_twl4030_power_off_action, d);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to install power off handler\n");
|
||||
|
||||
status = pdata->setup(&pdev->dev, priv->gpio_chip.base,
|
||||
TWL4030_GPIO_MAX);
|
||||
if (status)
|
||||
dev_dbg(&pdev->dev, "setup --> %d\n", status);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -593,9 +593,6 @@ struct twl4030_gpio_platform_data {
|
||||
*/
|
||||
u32 pullups;
|
||||
u32 pulldowns;
|
||||
|
||||
int (*setup)(struct device *dev,
|
||||
unsigned gpio, unsigned ngpio);
|
||||
};
|
||||
|
||||
struct twl4030_madc_platform_data {
|
||||
|
Loading…
Reference in New Issue
Block a user