All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/17] new locomo driver set
@ 2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

Sharp Zaurus SL-5500 and SL-5600 use special companion Gate Array.
With this patchset I tried to modernise and restructure the LoCoMo drivers.

* Use platform bus and mfd core code
* Use GPIO API instead of custom locomo GPIO code
* Use irqdomains to manage IRQs
* Split mixed locomolcd driver to lcd and backlight parts
* Implement IRQ handling in GPIO driver
* Implement SPI driver used as a host for mmc_spi device to control SD cards

V1 was submitted about a half of a year ago. Major changes:
* Use gpiod_* in most of places
* Use regmap for accessing registers instead of manual RMW cycles
* Split dac driver from core module to i2c bus and separate IIO driver
* Replaced mdelay() calls with usleep_range or msleep where it was suitable
* Rewrote SPI driver to use core transfer_one() interface


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 00/17] new locomo driver set
@ 2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

Sharp Zaurus SL-5500 and SL-5600 use special companion Gate Array.
With this patchset I tried to modernise and restructure the LoCoMo drivers.

* Use platform bus and mfd core code
* Use GPIO API instead of custom locomo GPIO code
* Use irqdomains to manage IRQs
* Split mixed locomolcd driver to lcd and backlight parts
* Implement IRQ handling in GPIO driver
* Implement SPI driver used as a host for mmc_spi device to control SD cards

V1 was submitted about a half of a year ago. Major changes:
* Use gpiod_* in most of places
* Use regmap for accessing registers instead of manual RMW cycles
* Split dac driver from core module to i2c bus and separate IIO driver
* Replaced mdelay() calls with usleep_range or msleep where it was suitable
* Rewrote SPI driver to use core transfer_one() interface



^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 00/17] new locomo driver set
@ 2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Sharp Zaurus SL-5500 and SL-5600 use special companion Gate Array.
With this patchset I tried to modernise and restructure the LoCoMo drivers.

* Use platform bus and mfd core code
* Use GPIO API instead of custom locomo GPIO code
* Use irqdomains to manage IRQs
* Split mixed locomolcd driver to lcd and backlight parts
* Implement IRQ handling in GPIO driver
* Implement SPI driver used as a host for mmc_spi device to control SD cards

V1 was submitted about a half of a year ago. Major changes:
* Use gpiod_* in most of places
* Use regmap for accessing registers instead of manual RMW cycles
* Split dac driver from core module to i2c bus and separate IIO driver
* Replaced mdelay() calls with usleep_range or msleep where it was suitable
* Rewrote SPI driver to use core transfer_one() interface

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
several design issues (special bus instead of platform bus, doesn't use
mfd-core, etc).

Implement 'core' parts of locomo support as an mfd driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/mfd/Kconfig        |  10 ++
 drivers/mfd/Makefile       |   1 +
 drivers/mfd/locomo.c       | 356 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/locomo.h | 173 ++++++++++++++++++++++
 4 files changed, 540 insertions(+)
 create mode 100644 drivers/mfd/locomo.c
 create mode 100644 include/linux/mfd/locomo.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d5ad04d..8c33940 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1430,6 +1430,16 @@ config MFD_STW481X
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  Nomadik series.
 
+config MFD_LOCOMO
+	bool "Sharp LoCoMo support"
+	depends on ARM
+	select MFD_CORE
+	select IRQ_DOMAIN
+	select REGMAP_MMIO
+	help
+	  Support for Sharp LoCoMo Grid Array found in Sharp SL-5x00
+          PDA family.
+
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0e5cfeb..6c23b73 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -181,6 +181,7 @@ obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
 obj-$(CONFIG_MFD_DLN2)		+= dln2.o
 obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
+obj-$(CONFIG_MFD_LOCOMO)	+= locomo.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/locomo.c b/drivers/mfd/locomo.c
new file mode 100644
index 0000000..f981c94
--- /dev/null
+++ b/drivers/mfd/locomo.c
@@ -0,0 +1,356 @@
+/*
+ * Sharp LoCoMo support
+ *
+ * Based on old driver at arch/arm/common/locomo.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/locomo.h>
+
+/* LoCoMo Interrupts */
+#define IRQ_LOCOMO_KEY		(0)
+#define IRQ_LOCOMO_GPIO		(1)
+#define IRQ_LOCOMO_LT		(2)
+#define IRQ_LOCOMO_SPI		(3)
+
+#define LOCOMO_NR_IRQS		(4)
+
+/* the following is the overall data for the locomo chip */
+struct locomo {
+	struct device *dev;
+	unsigned int irq;
+	spinlock_t lock;
+	struct irq_domain *domain;
+	struct regmap *regmap;
+};
+
+static struct resource locomo_kbd_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
+};
+
+static struct resource locomo_gpio_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
+};
+
+/* Filled in locomo_probe() function. */
+static struct locomo_gpio_platform_data locomo_gpio_pdata;
+
+static struct resource locomo_lt_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
+};
+
+static struct resource locomo_spi_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
+};
+
+/* Filled in locomo_probe() function. */
+static struct locomo_lcd_platform_data locomo_lcd_pdata;
+
+static struct mfd_cell locomo_cells[] = {
+	{
+		.name = "locomo-kbd",
+		.resources = locomo_kbd_resources,
+		.num_resources = ARRAY_SIZE(locomo_kbd_resources),
+	},
+	{
+		.name = "locomo-gpio",
+		.resources = locomo_gpio_resources,
+		.num_resources = ARRAY_SIZE(locomo_gpio_resources),
+		.platform_data = &locomo_gpio_pdata,
+		.pdata_size = sizeof(locomo_gpio_pdata),
+	},
+	{
+		.name = "locomo-lt", /* Long time timer */
+		.resources = locomo_lt_resources,
+		.num_resources = ARRAY_SIZE(locomo_lt_resources),
+	},
+	{
+		.name = "locomo-spi",
+		.resources = locomo_spi_resources,
+		.num_resources = ARRAY_SIZE(locomo_spi_resources),
+	},
+	{
+		.name = "locomo-led",
+	},
+	{
+		.name = "locomo-backlight",
+	},
+	{
+		.name = "locomo-lcd",
+		.platform_data = &locomo_lcd_pdata,
+		.pdata_size = sizeof(locomo_lcd_pdata),
+	},
+	{
+		.name = "locomo-i2c",
+	},
+};
+
+/* IRQ support */
+static void locomo_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct locomo *lchip = irq_get_handler_data(irq);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int req;
+
+	chained_irq_enter(irqchip, desc);
+
+	/* check why this interrupt was generated */
+	while (1) {
+		regmap_read(lchip->regmap, LOCOMO_ICR, &req);
+		req &= 0x0f00;
+
+		if (!req)
+			break;
+
+		irq = ffs(req) - 9;
+		generic_handle_irq(irq_find_mapping(lchip->domain, irq));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static void locomo_ack_irq(struct irq_data *d)
+{
+}
+
+static void locomo_mask_irq(struct irq_data *d)
+{
+	struct locomo *lchip = irq_data_get_irq_chip_data(d);
+
+	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
+		0x0010 << d->hwirq,
+		0);
+}
+
+static void locomo_unmask_irq(struct irq_data *d)
+{
+	struct locomo *lchip = irq_data_get_irq_chip_data(d);
+
+	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
+		(0x0010 << d->hwirq),
+		(0x0010 << d->hwirq));
+}
+
+static struct irq_chip locomo_chip = {
+	.name		= "LOCOMO",
+	.irq_ack	= locomo_ack_irq,
+	.irq_mask	= locomo_mask_irq,
+	.irq_unmask	= locomo_unmask_irq,
+};
+
+static int locomo_irq_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hwirq)
+{
+	struct locomo *locomo = d->host_data;
+
+	irq_set_chip_data(virq, locomo);
+	irq_set_chip_and_handler(virq, &locomo_chip,
+				handle_level_irq);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static void locomo_irq_unmap(struct irq_domain *d, unsigned int virq)
+{
+	set_irq_flags(virq, 0);
+	irq_set_chip_and_handler(virq, NULL, NULL);
+	irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops locomo_irq_ops = {
+	.map    = locomo_irq_map,
+	.unmap  = locomo_irq_unmap,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int locomo_setup_irq(struct locomo *lchip)
+{
+	lchip->domain = irq_domain_add_simple(NULL, LOCOMO_NR_IRQS, 0,
+			&locomo_irq_ops, lchip);
+	if (!lchip->domain) {
+		dev_err(lchip->dev, "Failed to register irqdomain\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Install handler for IRQ_LOCOMO_HW.
+	 */
+	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
+	irq_set_handler_data(lchip->irq, lchip);
+	irq_set_chained_handler(lchip->irq, locomo_handler);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_suspend(struct device *dev)
+{
+	struct locomo *lchip = dev_get_drvdata(dev);
+
+	/* AUDIO */
+	regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
+
+	/*
+	 * Original code disabled the clock depending on leds settings
+	 * However we disable leds before suspend, thus it's safe
+	 * to just assume this setting.
+	 */
+	/* CLK32 off */
+	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
+
+	/* 22MHz/24MHz clock off */
+	regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
+
+	return 0;
+}
+
+static int locomo_resume(struct device *dev)
+{
+	struct locomo *lchip = dev_get_drvdata(dev);
+
+	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_pm, locomo_suspend, locomo_resume);
+#define LOCOMO_PM	(&locomo_pm)
+
+#else
+#define LOCOMO_PM	NULL
+#endif
+
+static const struct regmap_config locomo_regmap_config = {
+	.name = "LoCoMo",
+	.reg_bits = 8,
+	.reg_stride = 4,
+	.val_bits = 16,
+	.cache_type = REGCACHE_NONE,
+	.max_register = 0xec,
+};
+
+static int locomo_probe(struct platform_device *dev)
+{
+	struct locomo_platform_data *pdata = dev_get_platdata(&dev->dev);
+	struct resource *mem;
+	void __iomem *base;
+	struct locomo *lchip;
+	unsigned int r;
+	int ret = -ENODEV;
+
+	lchip = devm_kzalloc(&dev->dev, sizeof(struct locomo), GFP_KERNEL);
+	if (!lchip)
+		return -ENOMEM;
+
+	spin_lock_init(&lchip->lock);
+	lchip->dev = &dev->dev;
+
+	lchip->irq = platform_get_irq(dev, 0);
+	if (lchip->irq < 0)
+		return -ENXIO;
+
+	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&dev->dev, mem);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	lchip->regmap = devm_regmap_init_mmio(&dev->dev, base,
+			&locomo_regmap_config);
+	if (IS_ERR(lchip->regmap))
+		return PTR_ERR(lchip->regmap);
+
+	if (pdata) {
+		locomo_gpio_pdata.gpio_base = pdata->gpio_base;
+		locomo_lcd_pdata.comadj = pdata->comadj;
+	} else {
+		locomo_gpio_pdata.gpio_base = -1;
+		locomo_lcd_pdata.comadj = 128;
+	}
+
+	platform_set_drvdata(dev, lchip);
+
+	regmap_read(lchip->regmap, LOCOMO_VER, &r);
+	dev_info(&dev->dev, "LoCoMo Chip: %04x\n", r);
+
+	/* locomo initialize */
+	regmap_write(lchip->regmap, LOCOMO_ICR, 0);
+
+	/* Longtime timer */
+	regmap_write(lchip->regmap, LOCOMO_LTINT, 0);
+
+	/*
+	 * The interrupt controller must be initialised before any
+	 * other device to ensure that the interrupts are available.
+	 */
+	ret = locomo_setup_irq(lchip);
+	if (ret < 0)
+		goto err_add;
+
+	ret = mfd_add_devices(&dev->dev, dev->id,
+			locomo_cells, ARRAY_SIZE(locomo_cells),
+			mem, -1, lchip->domain);
+	if (ret)
+		goto err_add;
+
+	return 0;
+
+err_add:
+	irq_set_chained_handler(lchip->irq, NULL);
+	irq_set_handler_data(lchip->irq, NULL);
+	if (lchip->domain)
+		irq_domain_remove(lchip->domain);
+
+	return ret;
+}
+
+static int locomo_remove(struct platform_device *dev)
+{
+	struct locomo *lchip = platform_get_drvdata(dev);
+
+	if (!lchip)
+		return 0;
+
+	mfd_remove_devices(&dev->dev);
+
+	irq_set_chained_handler(lchip->irq, NULL);
+	irq_set_handler_data(lchip->irq, NULL);
+	if (lchip->domain)
+		irq_domain_remove(lchip->domain);
+
+	return 0;
+}
+
+static struct platform_driver locomo_device_driver = {
+	.probe		= locomo_probe,
+	.remove		= locomo_remove,
+	.driver		= {
+		.name	= "locomo",
+		.pm	= LOCOMO_PM,
+	},
+};
+
+module_platform_driver(locomo_device_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo core driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo");
diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
new file mode 100644
index 0000000..6729767
--- /dev/null
+++ b/include/linux/mfd/locomo.h
@@ -0,0 +1,173 @@
+/*
+ * include/linux/mfd/locomo.h
+ *
+ * This file contains the definitions for the LoCoMo G/A Chip
+ *
+ * (C) Copyright 2004 John Lenz
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Based on sa1111.h
+ */
+#ifndef _ASM_ARCH_LOCOMO
+#define _ASM_ARCH_LOCOMO
+
+/* LOCOMO version */
+#define LOCOMO_VER	0x00
+
+/* Pin status */
+#define LOCOMO_ST	0x04
+
+/* Pin status */
+#define LOCOMO_C32K	0x08
+
+/* Interrupt controller */
+#define LOCOMO_ICR	0x0C
+
+/* MCS decoder for boot selecting */
+#define LOCOMO_MCSX0	0x10
+#define LOCOMO_MCSX1	0x14
+#define LOCOMO_MCSX2	0x18
+#define LOCOMO_MCSX3	0x1c
+
+/* Touch panel controller */
+#define LOCOMO_ASD	0x20		/* AD start delay */
+#define LOCOMO_HSD	0x28		/* HSYS delay */
+#define LOCOMO_HSC	0x2c		/* HSYS period */
+#define LOCOMO_TADC	0x30		/* tablet ADC clock */
+
+/* Backlight controller: TFT signal */
+#define LOCOMO_TC	0x38		/* TFT control signal */
+#define LOCOMO_CPSD	0x3c		/* CPS delay */
+
+/* Keyboard controller */
+#define LOCOMO_KIB	0x40	/* KIB level */
+#define LOCOMO_KSC	0x44	/* KSTRB control */
+#define LOCOMO_KCMD	0x48	/* KSTRB command */
+#define LOCOMO_KIC	0x4c	/* Key interrupt */
+
+/* Audio clock */
+#define LOCOMO_ACC	0x54	/* Audio clock */
+#define	LOCOMO_ACC_XON		0x80
+#define	LOCOMO_ACC_XEN		0x40
+#define	LOCOMO_ACC_XSEL0	0x00
+#define	LOCOMO_ACC_XSEL1	0x20
+#define	LOCOMO_ACC_MCLKEN	0x10
+#define	LOCOMO_ACC_64FSEN	0x08
+#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
+#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
+#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
+#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
+#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
+#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */
+
+/* SPI interface */
+#define LOCOMO_SPIMD	0x60		/* SPI mode setting */
+#define LOCOMO_SPIMD_LOOPBACK (1 << 15)	/* loopback tx to rx */
+#define LOCOMO_SPIMD_MSB1ST   (1 << 14)	/* send MSB first */
+#define LOCOMO_SPIMD_DOSTAT   (1 << 13)	/* transmit line is idle high */
+#define LOCOMO_SPIMD_TCPOL    (1 << 11)	/* transmit CPOL (maybe affects CPHA) */
+#define LOCOMO_SPIMD_RCPOL    (1 << 10)	/* receive CPOL (maybe affects CPHA) */
+#define	LOCOMO_SPIMD_TDINV    (1 << 9)	/* invert transmit line */
+#define LOCOMO_SPIMD_RDINV    (1 << 8)	/* invert receive line */
+#define LOCOMO_SPIMD_XON      (1 << 7)	/* enable spi controller clock */
+#define LOCOMO_SPIMD_XEN      (1 << 6)	/* clock bit write enable */
+#define LOCOMO_SPIMD_XSEL     0x0018	/* clock select */
+/* xon must be off when enabling xen, wait 300 us before xon -> 1 */
+#define CLOCK_18MHZ	    0		/* 18,432 MHz clock */
+#define CLOCK_22MHZ	    1		/* 22,5792 MHz clock */
+#define CLOCK_25MHZ	    2		/* 24,576 MHz clock */
+#define LOCOMO_SPIMD_CLKSEL   0x7
+#define DIV_1		    0		/* don't divide clock   */
+#define DIV_2		    1		/* divide clock by two	*/
+#define DIV_4		    2		/* divide clock by four */
+#define DIV_8		    3		/* divide clock by eight*/
+#define DIV_64		    4		/* divide clock by 64 */
+
+#define LOCOMO_SPICT	0x64		/* SPI mode control */
+#define LOCOMO_SPICT_CRC16_7_B	(1 << 15)	/* 0: crc16 1: crc7 */
+#define LOCOMO_SPICT_CRCRX_TX_B	(1 << 14)
+#define LOCOMO_SPICT_CRCRESET_B	(1 << 13)
+#define LOCOMO_SPICT_CEN	(1 << 7)	/* ?? enable */
+#define LOCOMO_SPICT_CS		(1 << 6)	/* chip select */
+#define LOCOMO_SPICT_UNIT16	(1 << 5)	/* 0: 8 bit, 1: 16 bit*/
+#define LOCOMO_SPICT_ALIGNEN	(1 << 2)	/* align transfer enable */
+#define LOCOMO_SPICT_RXWEN	(1 << 1)	/* continuous receive */
+#define LOCOMO_SPICT_RXUEN	(1 << 0)	/* aligned receive */
+
+#define LOCOMO_SPIST	0x68		/* SPI status */
+#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
+#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
+#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
+#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
+
+#define LOCOMO_SPIIS	0x70		/* SPI interrupt status */
+#define LOCOMO_SPIWE	0x74		/* SPI interrupt status write enable */
+#define LOCOMO_SPIIE	0x78		/* SPI interrupt enable */
+#define LOCOMO_SPIIR	0x7c		/* SPI interrupt request */
+#define LOCOMO_SPITD	0x80		/* SPI transfer data write */
+#define LOCOMO_SPIRD	0x84		/* SPI receive data read */
+#define LOCOMO_SPITS	0x88		/* SPI transfer data shift */
+#define LOCOMO_SPIRS	0x8C		/* SPI receive data shift */
+
+/* GPIO */
+#define LOCOMO_GPD	0x90	/* GPIO direction */
+#define LOCOMO_GPE	0x94	/* GPIO input enable */
+#define LOCOMO_GPL	0x98	/* GPIO level */
+#define LOCOMO_GPO	0x9c	/* GPIO out data setting */
+#define LOCOMO_GRIE	0xa0	/* GPIO rise detection */
+#define LOCOMO_GFIE	0xa4	/* GPIO fall detection */
+#define LOCOMO_GIS	0xa8	/* GPIO edge detection status */
+#define LOCOMO_GWE	0xac	/* GPIO status write enable */
+#define LOCOMO_GIE	0xb0	/* GPIO interrupt enable */
+#define LOCOMO_GIR	0xb4	/* GPIO interrupt request */
+
+/* Front light adjustment controller */
+#define LOCOMO_ALS	0xc8	/* Adjust light cycle */
+#define LOCOMO_ALS_EN		0x8000
+#define LOCOMO_ALD	0xcc	/* Adjust light duty */
+
+/* PCM audio interface */
+#define LOCOMO_PAIF	0xd0	/* PCM audio interface */
+#define	LOCOMO_PAIF_SCINV	0x20
+#define	LOCOMO_PAIF_SCEN	0x10
+#define	LOCOMO_PAIF_LRCRST	0x08
+#define	LOCOMO_PAIF_LRCEVE	0x04
+#define	LOCOMO_PAIF_LRCINV	0x02
+#define	LOCOMO_PAIF_LRCEN	0x01
+
+/* Long time timer */
+#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
+#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
+
+/* DAC control signal for LCD (COMADJ ) */
+#define LOCOMO_DAC	0xe0
+/* DAC control */
+#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
+#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
+#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
+#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
+
+/* LED controller */
+#define LOCOMO_LPT0	0xe8
+#define LOCOMO_LPT1	0xec
+#define LOCOMO_LPT_TOFH		0x80
+#define LOCOMO_LPT_TOFL		0x08
+#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
+#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
+
+struct locomo_gpio_platform_data {
+	unsigned int gpio_base;
+};
+
+struct locomo_lcd_platform_data {
+	u8 comadj;
+};
+
+struct locomo_platform_data {
+	unsigned int gpio_base;
+	u8 comadj;
+};
+
+#endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
several design issues (special bus instead of platform bus, doesn't use
mfd-core, etc).

Implement 'core' parts of locomo support as an mfd driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/mfd/Kconfig        |  10 ++
 drivers/mfd/Makefile       |   1 +
 drivers/mfd/locomo.c       | 356 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/locomo.h | 173 ++++++++++++++++++++++
 4 files changed, 540 insertions(+)
 create mode 100644 drivers/mfd/locomo.c
 create mode 100644 include/linux/mfd/locomo.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d5ad04d..8c33940 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1430,6 +1430,16 @@ config MFD_STW481X
 	  in various ST Microelectronics and ST-Ericsson embedded
 	  Nomadik series.
 
+config MFD_LOCOMO
+	bool "Sharp LoCoMo support"
+	depends on ARM
+	select MFD_CORE
+	select IRQ_DOMAIN
+	select REGMAP_MMIO
+	help
+	  Support for Sharp LoCoMo Grid Array found in Sharp SL-5x00
+          PDA family.
+
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0e5cfeb..6c23b73 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -181,6 +181,7 @@ obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
 obj-$(CONFIG_MFD_DLN2)		+= dln2.o
 obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
+obj-$(CONFIG_MFD_LOCOMO)	+= locomo.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/locomo.c b/drivers/mfd/locomo.c
new file mode 100644
index 0000000..f981c94
--- /dev/null
+++ b/drivers/mfd/locomo.c
@@ -0,0 +1,356 @@
+/*
+ * Sharp LoCoMo support
+ *
+ * Based on old driver at arch/arm/common/locomo.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/locomo.h>
+
+/* LoCoMo Interrupts */
+#define IRQ_LOCOMO_KEY		(0)
+#define IRQ_LOCOMO_GPIO		(1)
+#define IRQ_LOCOMO_LT		(2)
+#define IRQ_LOCOMO_SPI		(3)
+
+#define LOCOMO_NR_IRQS		(4)
+
+/* the following is the overall data for the locomo chip */
+struct locomo {
+	struct device *dev;
+	unsigned int irq;
+	spinlock_t lock;
+	struct irq_domain *domain;
+	struct regmap *regmap;
+};
+
+static struct resource locomo_kbd_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
+};
+
+static struct resource locomo_gpio_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
+};
+
+/* Filled in locomo_probe() function. */
+static struct locomo_gpio_platform_data locomo_gpio_pdata;
+
+static struct resource locomo_lt_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
+};
+
+static struct resource locomo_spi_resources[] = {
+	DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
+};
+
+/* Filled in locomo_probe() function. */
+static struct locomo_lcd_platform_data locomo_lcd_pdata;
+
+static struct mfd_cell locomo_cells[] = {
+	{
+		.name = "locomo-kbd",
+		.resources = locomo_kbd_resources,
+		.num_resources = ARRAY_SIZE(locomo_kbd_resources),
+	},
+	{
+		.name = "locomo-gpio",
+		.resources = locomo_gpio_resources,
+		.num_resources = ARRAY_SIZE(locomo_gpio_resources),
+		.platform_data = &locomo_gpio_pdata,
+		.pdata_size = sizeof(locomo_gpio_pdata),
+	},
+	{
+		.name = "locomo-lt", /* Long time timer */
+		.resources = locomo_lt_resources,
+		.num_resources = ARRAY_SIZE(locomo_lt_resources),
+	},
+	{
+		.name = "locomo-spi",
+		.resources = locomo_spi_resources,
+		.num_resources = ARRAY_SIZE(locomo_spi_resources),
+	},
+	{
+		.name = "locomo-led",
+	},
+	{
+		.name = "locomo-backlight",
+	},
+	{
+		.name = "locomo-lcd",
+		.platform_data = &locomo_lcd_pdata,
+		.pdata_size = sizeof(locomo_lcd_pdata),
+	},
+	{
+		.name = "locomo-i2c",
+	},
+};
+
+/* IRQ support */
+static void locomo_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct locomo *lchip = irq_get_handler_data(irq);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int req;
+
+	chained_irq_enter(irqchip, desc);
+
+	/* check why this interrupt was generated */
+	while (1) {
+		regmap_read(lchip->regmap, LOCOMO_ICR, &req);
+		req &= 0x0f00;
+
+		if (!req)
+			break;
+
+		irq = ffs(req) - 9;
+		generic_handle_irq(irq_find_mapping(lchip->domain, irq));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static void locomo_ack_irq(struct irq_data *d)
+{
+}
+
+static void locomo_mask_irq(struct irq_data *d)
+{
+	struct locomo *lchip = irq_data_get_irq_chip_data(d);
+
+	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
+		0x0010 << d->hwirq,
+		0);
+}
+
+static void locomo_unmask_irq(struct irq_data *d)
+{
+	struct locomo *lchip = irq_data_get_irq_chip_data(d);
+
+	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
+		(0x0010 << d->hwirq),
+		(0x0010 << d->hwirq));
+}
+
+static struct irq_chip locomo_chip = {
+	.name		= "LOCOMO",
+	.irq_ack	= locomo_ack_irq,
+	.irq_mask	= locomo_mask_irq,
+	.irq_unmask	= locomo_unmask_irq,
+};
+
+static int locomo_irq_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hwirq)
+{
+	struct locomo *locomo = d->host_data;
+
+	irq_set_chip_data(virq, locomo);
+	irq_set_chip_and_handler(virq, &locomo_chip,
+				handle_level_irq);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static void locomo_irq_unmap(struct irq_domain *d, unsigned int virq)
+{
+	set_irq_flags(virq, 0);
+	irq_set_chip_and_handler(virq, NULL, NULL);
+	irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops locomo_irq_ops = {
+	.map    = locomo_irq_map,
+	.unmap  = locomo_irq_unmap,
+	.xlate  = irq_domain_xlate_onecell,
+};
+
+static int locomo_setup_irq(struct locomo *lchip)
+{
+	lchip->domain = irq_domain_add_simple(NULL, LOCOMO_NR_IRQS, 0,
+			&locomo_irq_ops, lchip);
+	if (!lchip->domain) {
+		dev_err(lchip->dev, "Failed to register irqdomain\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * Install handler for IRQ_LOCOMO_HW.
+	 */
+	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
+	irq_set_handler_data(lchip->irq, lchip);
+	irq_set_chained_handler(lchip->irq, locomo_handler);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_suspend(struct device *dev)
+{
+	struct locomo *lchip = dev_get_drvdata(dev);
+
+	/* AUDIO */
+	regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
+
+	/*
+	 * Original code disabled the clock depending on leds settings
+	 * However we disable leds before suspend, thus it's safe
+	 * to just assume this setting.
+	 */
+	/* CLK32 off */
+	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
+
+	/* 22MHz/24MHz clock off */
+	regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
+
+	return 0;
+}
+
+static int locomo_resume(struct device *dev)
+{
+	struct locomo *lchip = dev_get_drvdata(dev);
+
+	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_pm, locomo_suspend, locomo_resume);
+#define LOCOMO_PM	(&locomo_pm)
+
+#else
+#define LOCOMO_PM	NULL
+#endif
+
+static const struct regmap_config locomo_regmap_config = {
+	.name = "LoCoMo",
+	.reg_bits = 8,
+	.reg_stride = 4,
+	.val_bits = 16,
+	.cache_type = REGCACHE_NONE,
+	.max_register = 0xec,
+};
+
+static int locomo_probe(struct platform_device *dev)
+{
+	struct locomo_platform_data *pdata = dev_get_platdata(&dev->dev);
+	struct resource *mem;
+	void __iomem *base;
+	struct locomo *lchip;
+	unsigned int r;
+	int ret = -ENODEV;
+
+	lchip = devm_kzalloc(&dev->dev, sizeof(struct locomo), GFP_KERNEL);
+	if (!lchip)
+		return -ENOMEM;
+
+	spin_lock_init(&lchip->lock);
+	lchip->dev = &dev->dev;
+
+	lchip->irq = platform_get_irq(dev, 0);
+	if (lchip->irq < 0)
+		return -ENXIO;
+
+	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	base = devm_ioremap_resource(&dev->dev, mem);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	lchip->regmap = devm_regmap_init_mmio(&dev->dev, base,
+			&locomo_regmap_config);
+	if (IS_ERR(lchip->regmap))
+		return PTR_ERR(lchip->regmap);
+
+	if (pdata) {
+		locomo_gpio_pdata.gpio_base = pdata->gpio_base;
+		locomo_lcd_pdata.comadj = pdata->comadj;
+	} else {
+		locomo_gpio_pdata.gpio_base = -1;
+		locomo_lcd_pdata.comadj = 128;
+	}
+
+	platform_set_drvdata(dev, lchip);
+
+	regmap_read(lchip->regmap, LOCOMO_VER, &r);
+	dev_info(&dev->dev, "LoCoMo Chip: %04x\n", r);
+
+	/* locomo initialize */
+	regmap_write(lchip->regmap, LOCOMO_ICR, 0);
+
+	/* Longtime timer */
+	regmap_write(lchip->regmap, LOCOMO_LTINT, 0);
+
+	/*
+	 * The interrupt controller must be initialised before any
+	 * other device to ensure that the interrupts are available.
+	 */
+	ret = locomo_setup_irq(lchip);
+	if (ret < 0)
+		goto err_add;
+
+	ret = mfd_add_devices(&dev->dev, dev->id,
+			locomo_cells, ARRAY_SIZE(locomo_cells),
+			mem, -1, lchip->domain);
+	if (ret)
+		goto err_add;
+
+	return 0;
+
+err_add:
+	irq_set_chained_handler(lchip->irq, NULL);
+	irq_set_handler_data(lchip->irq, NULL);
+	if (lchip->domain)
+		irq_domain_remove(lchip->domain);
+
+	return ret;
+}
+
+static int locomo_remove(struct platform_device *dev)
+{
+	struct locomo *lchip = platform_get_drvdata(dev);
+
+	if (!lchip)
+		return 0;
+
+	mfd_remove_devices(&dev->dev);
+
+	irq_set_chained_handler(lchip->irq, NULL);
+	irq_set_handler_data(lchip->irq, NULL);
+	if (lchip->domain)
+		irq_domain_remove(lchip->domain);
+
+	return 0;
+}
+
+static struct platform_driver locomo_device_driver = {
+	.probe		= locomo_probe,
+	.remove		= locomo_remove,
+	.driver		= {
+		.name	= "locomo",
+		.pm	= LOCOMO_PM,
+	},
+};
+
+module_platform_driver(locomo_device_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo core driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo");
diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
new file mode 100644
index 0000000..6729767
--- /dev/null
+++ b/include/linux/mfd/locomo.h
@@ -0,0 +1,173 @@
+/*
+ * include/linux/mfd/locomo.h
+ *
+ * This file contains the definitions for the LoCoMo G/A Chip
+ *
+ * (C) Copyright 2004 John Lenz
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License.  See linux/COPYING for more information.
+ *
+ * Based on sa1111.h
+ */
+#ifndef _ASM_ARCH_LOCOMO
+#define _ASM_ARCH_LOCOMO
+
+/* LOCOMO version */
+#define LOCOMO_VER	0x00
+
+/* Pin status */
+#define LOCOMO_ST	0x04
+
+/* Pin status */
+#define LOCOMO_C32K	0x08
+
+/* Interrupt controller */
+#define LOCOMO_ICR	0x0C
+
+/* MCS decoder for boot selecting */
+#define LOCOMO_MCSX0	0x10
+#define LOCOMO_MCSX1	0x14
+#define LOCOMO_MCSX2	0x18
+#define LOCOMO_MCSX3	0x1c
+
+/* Touch panel controller */
+#define LOCOMO_ASD	0x20		/* AD start delay */
+#define LOCOMO_HSD	0x28		/* HSYS delay */
+#define LOCOMO_HSC	0x2c		/* HSYS period */
+#define LOCOMO_TADC	0x30		/* tablet ADC clock */
+
+/* Backlight controller: TFT signal */
+#define LOCOMO_TC	0x38		/* TFT control signal */
+#define LOCOMO_CPSD	0x3c		/* CPS delay */
+
+/* Keyboard controller */
+#define LOCOMO_KIB	0x40	/* KIB level */
+#define LOCOMO_KSC	0x44	/* KSTRB control */
+#define LOCOMO_KCMD	0x48	/* KSTRB command */
+#define LOCOMO_KIC	0x4c	/* Key interrupt */
+
+/* Audio clock */
+#define LOCOMO_ACC	0x54	/* Audio clock */
+#define	LOCOMO_ACC_XON		0x80
+#define	LOCOMO_ACC_XEN		0x40
+#define	LOCOMO_ACC_XSEL0	0x00
+#define	LOCOMO_ACC_XSEL1	0x20
+#define	LOCOMO_ACC_MCLKEN	0x10
+#define	LOCOMO_ACC_64FSEN	0x08
+#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
+#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
+#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
+#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
+#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
+#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */
+
+/* SPI interface */
+#define LOCOMO_SPIMD	0x60		/* SPI mode setting */
+#define LOCOMO_SPIMD_LOOPBACK (1 << 15)	/* loopback tx to rx */
+#define LOCOMO_SPIMD_MSB1ST   (1 << 14)	/* send MSB first */
+#define LOCOMO_SPIMD_DOSTAT   (1 << 13)	/* transmit line is idle high */
+#define LOCOMO_SPIMD_TCPOL    (1 << 11)	/* transmit CPOL (maybe affects CPHA) */
+#define LOCOMO_SPIMD_RCPOL    (1 << 10)	/* receive CPOL (maybe affects CPHA) */
+#define	LOCOMO_SPIMD_TDINV    (1 << 9)	/* invert transmit line */
+#define LOCOMO_SPIMD_RDINV    (1 << 8)	/* invert receive line */
+#define LOCOMO_SPIMD_XON      (1 << 7)	/* enable spi controller clock */
+#define LOCOMO_SPIMD_XEN      (1 << 6)	/* clock bit write enable */
+#define LOCOMO_SPIMD_XSEL     0x0018	/* clock select */
+/* xon must be off when enabling xen, wait 300 us before xon -> 1 */
+#define CLOCK_18MHZ	    0		/* 18,432 MHz clock */
+#define CLOCK_22MHZ	    1		/* 22,5792 MHz clock */
+#define CLOCK_25MHZ	    2		/* 24,576 MHz clock */
+#define LOCOMO_SPIMD_CLKSEL   0x7
+#define DIV_1		    0		/* don't divide clock   */
+#define DIV_2		    1		/* divide clock by two	*/
+#define DIV_4		    2		/* divide clock by four */
+#define DIV_8		    3		/* divide clock by eight*/
+#define DIV_64		    4		/* divide clock by 64 */
+
+#define LOCOMO_SPICT	0x64		/* SPI mode control */
+#define LOCOMO_SPICT_CRC16_7_B	(1 << 15)	/* 0: crc16 1: crc7 */
+#define LOCOMO_SPICT_CRCRX_TX_B	(1 << 14)
+#define LOCOMO_SPICT_CRCRESET_B	(1 << 13)
+#define LOCOMO_SPICT_CEN	(1 << 7)	/* ?? enable */
+#define LOCOMO_SPICT_CS		(1 << 6)	/* chip select */
+#define LOCOMO_SPICT_UNIT16	(1 << 5)	/* 0: 8 bit, 1: 16 bit*/
+#define LOCOMO_SPICT_ALIGNEN	(1 << 2)	/* align transfer enable */
+#define LOCOMO_SPICT_RXWEN	(1 << 1)	/* continuous receive */
+#define LOCOMO_SPICT_RXUEN	(1 << 0)	/* aligned receive */
+
+#define LOCOMO_SPIST	0x68		/* SPI status */
+#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
+#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
+#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
+#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
+
+#define LOCOMO_SPIIS	0x70		/* SPI interrupt status */
+#define LOCOMO_SPIWE	0x74		/* SPI interrupt status write enable */
+#define LOCOMO_SPIIE	0x78		/* SPI interrupt enable */
+#define LOCOMO_SPIIR	0x7c		/* SPI interrupt request */
+#define LOCOMO_SPITD	0x80		/* SPI transfer data write */
+#define LOCOMO_SPIRD	0x84		/* SPI receive data read */
+#define LOCOMO_SPITS	0x88		/* SPI transfer data shift */
+#define LOCOMO_SPIRS	0x8C		/* SPI receive data shift */
+
+/* GPIO */
+#define LOCOMO_GPD	0x90	/* GPIO direction */
+#define LOCOMO_GPE	0x94	/* GPIO input enable */
+#define LOCOMO_GPL	0x98	/* GPIO level */
+#define LOCOMO_GPO	0x9c	/* GPIO out data setting */
+#define LOCOMO_GRIE	0xa0	/* GPIO rise detection */
+#define LOCOMO_GFIE	0xa4	/* GPIO fall detection */
+#define LOCOMO_GIS	0xa8	/* GPIO edge detection status */
+#define LOCOMO_GWE	0xac	/* GPIO status write enable */
+#define LOCOMO_GIE	0xb0	/* GPIO interrupt enable */
+#define LOCOMO_GIR	0xb4	/* GPIO interrupt request */
+
+/* Front light adjustment controller */
+#define LOCOMO_ALS	0xc8	/* Adjust light cycle */
+#define LOCOMO_ALS_EN		0x8000
+#define LOCOMO_ALD	0xcc	/* Adjust light duty */
+
+/* PCM audio interface */
+#define LOCOMO_PAIF	0xd0	/* PCM audio interface */
+#define	LOCOMO_PAIF_SCINV	0x20
+#define	LOCOMO_PAIF_SCEN	0x10
+#define	LOCOMO_PAIF_LRCRST	0x08
+#define	LOCOMO_PAIF_LRCEVE	0x04
+#define	LOCOMO_PAIF_LRCINV	0x02
+#define	LOCOMO_PAIF_LRCEN	0x01
+
+/* Long time timer */
+#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
+#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
+
+/* DAC control signal for LCD (COMADJ ) */
+#define LOCOMO_DAC	0xe0
+/* DAC control */
+#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
+#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
+#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
+#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
+
+/* LED controller */
+#define LOCOMO_LPT0	0xe8
+#define LOCOMO_LPT1	0xec
+#define LOCOMO_LPT_TOFH		0x80
+#define LOCOMO_LPT_TOFL		0x08
+#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
+#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
+
+struct locomo_gpio_platform_data {
+	unsigned int gpio_base;
+};
+
+struct locomo_lcd_platform_data {
+	u8 comadj;
+};
+
+struct locomo_platform_data {
+	unsigned int gpio_base;
+	u8 comadj;
+};
+
+#endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Adapt locomo leds driver to new locomo core setup.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/leds/Kconfig       |   1 -
 drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
 2 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 966b960..4b4650b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -79,7 +79,6 @@ config LEDS_LM3642
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS
-	depends on SHARP_LOCOMO
 	help
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 80ba048..7fde812 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -9,89 +9,92 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
 #include <linux/leds.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_led {
+	struct led_classdev led;
+	struct regmap *regmap;
+	unsigned int reg;
+};
 
 static void locomoled_brightness_set(struct led_classdev *led_cdev,
-				enum led_brightness value, int offset)
+				enum led_brightness value)
 {
-	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
-	unsigned long flags;
+	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
 
-	local_irq_save(flags);
-	if (value)
-		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
-	else
-		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
-	local_irq_restore(flags);
+	regmap_write(led->regmap, led->reg,
+			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
 }
 
-static void locomoled_brightness_set0(struct led_classdev *led_cdev,
-				enum led_brightness value)
+static int locomo_led_register(
+		struct device *dev,
+		struct locomo_led *led,
+		const char *name,
+		const char *trigger,
+		struct regmap *regmap,
+		unsigned int reg)
 {
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
+	led->led.name = name;
+	led->led.flags = LED_CORE_SUSPENDRESUME;
+	led->led.default_trigger = trigger;
+	led->led.brightness_set = locomoled_brightness_set;
+	led->regmap = regmap;
+	led->reg = reg;
+
+	return devm_led_classdev_register(dev, &led->led);
 }
 
-static void locomoled_brightness_set1(struct led_classdev *led_cdev,
-				enum led_brightness value)
-{
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
-}
-
-static struct led_classdev locomo_led0 = {
-	.name			= "locomo:amber:charge",
-	.default_trigger	= "main-battery-charging",
-	.brightness_set		= locomoled_brightness_set0,
-};
-
-static struct led_classdev locomo_led1 = {
-	.name			= "locomo:green:mail",
-	.default_trigger	= "nand-disk",
-	.brightness_set		= locomoled_brightness_set1,
-};
-
-static int locomoled_probe(struct locomo_dev *ldev)
+static int locomoled_probe(struct platform_device *pdev)
 {
 	int ret;
-
-	ret = led_classdev_register(&ldev->dev, &locomo_led0);
+	struct locomo_led *leds;
+	struct regmap *regmap;
+
+	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
+	if (!leds)
+		return -ENOMEM;
+
+	regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds,
+			"locomo:amber:charge",
+			"main-battery-charging",
+			regmap,
+			LOCOMO_LPT0);
 	if (ret < 0)
 		return ret;
 
-	ret = led_classdev_register(&ldev->dev, &locomo_led1);
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds + 1,
+			"locomo:green:mail",
+			"mmc0",
+			regmap,
+			LOCOMO_LPT1);
 	if (ret < 0)
-		led_classdev_unregister(&locomo_led0);
-
-	return ret;
-}
+		return ret;
 
-static int locomoled_remove(struct locomo_dev *dev)
-{
-	led_classdev_unregister(&locomo_led0);
-	led_classdev_unregister(&locomo_led1);
 	return 0;
 }
 
-static struct locomo_driver locomoled_driver = {
-	.drv = {
-		.name = "locomoled"
+static struct platform_driver locomoled_driver = {
+	.driver = {
+		.name = "locomo-led"
 	},
-	.devid	= LOCOMO_DEVID_LED,
 	.probe	= locomoled_probe,
-	.remove	= locomoled_remove,
 };
 
-static int __init locomoled_init(void)
-{
-	return locomo_driver_register(&locomoled_driver);
-}
-module_init(locomoled_init);
+module_platform_driver(locomoled_driver);
 
 MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
 MODULE_DESCRIPTION("Locomo LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-led");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Adapt locomo leds driver to new locomo core setup.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/leds/Kconfig       |   1 -
 drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
 2 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 966b960..4b4650b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -79,7 +79,6 @@ config LEDS_LM3642
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS
-	depends on SHARP_LOCOMO
 	help
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 80ba048..7fde812 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -9,89 +9,92 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
 #include <linux/leds.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_led {
+	struct led_classdev led;
+	struct regmap *regmap;
+	unsigned int reg;
+};
 
 static void locomoled_brightness_set(struct led_classdev *led_cdev,
-				enum led_brightness value, int offset)
+				enum led_brightness value)
 {
-	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
-	unsigned long flags;
+	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
 
-	local_irq_save(flags);
-	if (value)
-		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
-	else
-		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
-	local_irq_restore(flags);
+	regmap_write(led->regmap, led->reg,
+			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
 }
 
-static void locomoled_brightness_set0(struct led_classdev *led_cdev,
-				enum led_brightness value)
+static int locomo_led_register(
+		struct device *dev,
+		struct locomo_led *led,
+		const char *name,
+		const char *trigger,
+		struct regmap *regmap,
+		unsigned int reg)
 {
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
+	led->led.name = name;
+	led->led.flags = LED_CORE_SUSPENDRESUME;
+	led->led.default_trigger = trigger;
+	led->led.brightness_set = locomoled_brightness_set;
+	led->regmap = regmap;
+	led->reg = reg;
+
+	return devm_led_classdev_register(dev, &led->led);
 }
 
-static void locomoled_brightness_set1(struct led_classdev *led_cdev,
-				enum led_brightness value)
-{
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
-}
-
-static struct led_classdev locomo_led0 = {
-	.name			= "locomo:amber:charge",
-	.default_trigger	= "main-battery-charging",
-	.brightness_set		= locomoled_brightness_set0,
-};
-
-static struct led_classdev locomo_led1 = {
-	.name			= "locomo:green:mail",
-	.default_trigger	= "nand-disk",
-	.brightness_set		= locomoled_brightness_set1,
-};
-
-static int locomoled_probe(struct locomo_dev *ldev)
+static int locomoled_probe(struct platform_device *pdev)
 {
 	int ret;
-
-	ret = led_classdev_register(&ldev->dev, &locomo_led0);
+	struct locomo_led *leds;
+	struct regmap *regmap;
+
+	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
+	if (!leds)
+		return -ENOMEM;
+
+	regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds,
+			"locomo:amber:charge",
+			"main-battery-charging",
+			regmap,
+			LOCOMO_LPT0);
 	if (ret < 0)
 		return ret;
 
-	ret = led_classdev_register(&ldev->dev, &locomo_led1);
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds + 1,
+			"locomo:green:mail",
+			"mmc0",
+			regmap,
+			LOCOMO_LPT1);
 	if (ret < 0)
-		led_classdev_unregister(&locomo_led0);
-
-	return ret;
-}
+		return ret;
 
-static int locomoled_remove(struct locomo_dev *dev)
-{
-	led_classdev_unregister(&locomo_led0);
-	led_classdev_unregister(&locomo_led1);
 	return 0;
 }
 
-static struct locomo_driver locomoled_driver = {
-	.drv = {
-		.name = "locomoled"
+static struct platform_driver locomoled_driver = {
+	.driver = {
+		.name = "locomo-led"
 	},
-	.devid	= LOCOMO_DEVID_LED,
 	.probe	= locomoled_probe,
-	.remove	= locomoled_remove,
 };
 
-static int __init locomoled_init(void)
-{
-	return locomo_driver_register(&locomoled_driver);
-}
-module_init(locomoled_init);
+module_platform_driver(locomoled_driver);
 
 MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
 MODULE_DESCRIPTION("Locomo LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-led");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Adapt locomo leds driver to new locomo core setup.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/leds/Kconfig       |   1 -
 drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
 2 files changed, 61 insertions(+), 59 deletions(-)

diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 966b960..4b4650b 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -79,7 +79,6 @@ config LEDS_LM3642
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS
-	depends on SHARP_LOCOMO
 	help
 	  This option enables support for the LEDs on Sharp Locomo.
 	  Zaurus models SL-5500 and SL-5600.
diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
index 80ba048..7fde812 100644
--- a/drivers/leds/leds-locomo.c
+++ b/drivers/leds/leds-locomo.c
@@ -9,89 +9,92 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
 #include <linux/leds.h>
-
-#include <mach/hardware.h>
-#include <asm/hardware/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_led {
+	struct led_classdev led;
+	struct regmap *regmap;
+	unsigned int reg;
+};
 
 static void locomoled_brightness_set(struct led_classdev *led_cdev,
-				enum led_brightness value, int offset)
+				enum led_brightness value)
 {
-	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
-	unsigned long flags;
+	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
 
-	local_irq_save(flags);
-	if (value)
-		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
-	else
-		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
-	local_irq_restore(flags);
+	regmap_write(led->regmap, led->reg,
+			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
 }
 
-static void locomoled_brightness_set0(struct led_classdev *led_cdev,
-				enum led_brightness value)
+static int locomo_led_register(
+		struct device *dev,
+		struct locomo_led *led,
+		const char *name,
+		const char *trigger,
+		struct regmap *regmap,
+		unsigned int reg)
 {
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
+	led->led.name = name;
+	led->led.flags = LED_CORE_SUSPENDRESUME;
+	led->led.default_trigger = trigger;
+	led->led.brightness_set = locomoled_brightness_set;
+	led->regmap = regmap;
+	led->reg = reg;
+
+	return devm_led_classdev_register(dev, &led->led);
 }
 
-static void locomoled_brightness_set1(struct led_classdev *led_cdev,
-				enum led_brightness value)
-{
-	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
-}
-
-static struct led_classdev locomo_led0 = {
-	.name			= "locomo:amber:charge",
-	.default_trigger	= "main-battery-charging",
-	.brightness_set		= locomoled_brightness_set0,
-};
-
-static struct led_classdev locomo_led1 = {
-	.name			= "locomo:green:mail",
-	.default_trigger	= "nand-disk",
-	.brightness_set		= locomoled_brightness_set1,
-};
-
-static int locomoled_probe(struct locomo_dev *ldev)
+static int locomoled_probe(struct platform_device *pdev)
 {
 	int ret;
-
-	ret = led_classdev_register(&ldev->dev, &locomo_led0);
+	struct locomo_led *leds;
+	struct regmap *regmap;
+
+	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
+	if (!leds)
+		return -ENOMEM;
+
+	regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds,
+			"locomo:amber:charge",
+			"main-battery-charging",
+			regmap,
+			LOCOMO_LPT0);
 	if (ret < 0)
 		return ret;
 
-	ret = led_classdev_register(&ldev->dev, &locomo_led1);
+	ret = locomo_led_register(
+			&pdev->dev,
+			leds + 1,
+			"locomo:green:mail",
+			"mmc0",
+			regmap,
+			LOCOMO_LPT1);
 	if (ret < 0)
-		led_classdev_unregister(&locomo_led0);
-
-	return ret;
-}
+		return ret;
 
-static int locomoled_remove(struct locomo_dev *dev)
-{
-	led_classdev_unregister(&locomo_led0);
-	led_classdev_unregister(&locomo_led1);
 	return 0;
 }
 
-static struct locomo_driver locomoled_driver = {
-	.drv = {
-		.name = "locomoled"
+static struct platform_driver locomoled_driver = {
+	.driver = {
+		.name = "locomo-led"
 	},
-	.devid	= LOCOMO_DEVID_LED,
 	.probe	= locomoled_probe,
-	.remove	= locomoled_remove,
 };
 
-static int __init locomoled_init(void)
-{
-	return locomo_driver_register(&locomoled_driver);
-}
-module_init(locomoled_init);
+module_platform_driver(locomoled_driver);
 
 MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
 MODULE_DESCRIPTION("Locomo LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-led");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
       [not found] ` <1430178954-11138-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

As LoCoMo is switching to new device model, adapt keyboard driver to
support new locomo core driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/input/keyboard/Kconfig     |   1 -
 drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
 2 files changed, 143 insertions(+), 129 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac..0a3d875 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -337,7 +337,6 @@ config KEYBOARD_LM8333
 
 config KEYBOARD_LOCOMO
 	tristate "LoCoMo Keyboard Support"
-	depends on SHARP_LOCOMO
 	help
 	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
 
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index c94d610..eed0a94 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -23,37 +23,37 @@
  *
  */
 
-#include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("John Lenz <lenz-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>");
-MODULE_DESCRIPTION("LoCoMo keyboard driver");
-MODULE_LICENSE("GPL");
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
 
-#define LOCOMOKBD_NUMKEYS	128
+/* There is one minor difference between mappings on poodle and collie */
+#include <asm/mach-types.h>
 
 #define KEY_ACTIVITY		KEY_F16
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#define KB_ROWS			16
+#define KB_COLS			8
+#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
+#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
+
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
 	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
-	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
+	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
 	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
 	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
 	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
@@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
 };
 
-#define KB_ROWS			16
-#define KB_COLS			8
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
-
 #define KB_DELAY		8
-#define SCAN_INTERVAL		(HZ/10)
 
 struct locomokbd {
 	unsigned char keycode[LOCOMOKBD_NUMKEYS];
 	struct input_dev *input;
-	char phys[32];
 
-	unsigned long base;
+	struct regmap *regmap;
+	int irq;
 	spinlock_t lock;
 
 	struct timer_list timer;
@@ -84,37 +78,33 @@ struct locomokbd {
 };
 
 /* helper functions for reading the keyboard matrix */
-static inline void locomokbd_charge_all(unsigned long membase)
+static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
 {
-	locomo_writel(0x00FF, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
 }
 
-static inline void locomokbd_activate_all(unsigned long membase)
+static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
 {
-	unsigned long r;
-
-	locomo_writel(0, membase + LOCOMO_KSC);
-	r = locomo_readl(membase + LOCOMO_KIC);
-	r &= 0xFEFF;
-	locomo_writel(r, membase + LOCOMO_KIC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
 }
 
-static inline void locomokbd_activate_col(unsigned long membase, int col)
+static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nset;
 	unsigned short nbset;
 
-	nset = 0xFF & ~(1 << col);
+	nset = 0xFF & ~BIT(col);
 	nbset = (nset << 8) + nset;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
-static inline void locomokbd_reset_col(unsigned long membase, int col)
+static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nbset;
 
-	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
 /*
@@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 	unsigned int row, col, rowd;
 	unsigned long flags;
 	unsigned int num_pressed;
-	unsigned long membase = locomokbd->base;
+	bool esc_pressed = false;
 
 	spin_lock_irqsave(&locomokbd->lock, flags);
 
-	locomokbd_charge_all(membase);
+	locomokbd_charge_all(locomokbd);
 
 	num_pressed = 0;
 	for (col = 0; col < KB_COLS; col++) {
-
-		locomokbd_activate_col(membase, col);
+		udelay(KB_DELAY);
+		locomokbd_activate_col(locomokbd, col);
 		udelay(KB_DELAY);
 
-		rowd = ~locomo_readl(membase + LOCOMO_KIB);
+		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
+		rowd = ~rowd;
 		for (row = 0; row < KB_ROWS; row++) {
 			unsigned int scancode, pressed, key;
 
 			scancode = SCANCODE(col, row);
-			pressed = rowd & KB_ROWMASK(row);
+			pressed = rowd & BIT(row);
 			key = locomokbd->keycode[scancode];
 
 			input_report_key(locomokbd->input, key, pressed);
@@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 			/* The "Cancel/ESC" key is labeled "On/Off" on
 			 * Collie and Poodle and should suspend the device
 			 * if it was pressed for more than a second. */
-			if (unlikely(key == KEY_ESC)) {
-				if (!time_after(jiffies,
-					locomokbd->suspend_jiffies + HZ))
-					continue;
-				if (locomokbd->count_cancel++
-					!= (HZ/SCAN_INTERVAL + 1))
-					continue;
-				input_event(locomokbd->input, EV_PWR,
-					KEY_SUSPEND, 1);
-				locomokbd->suspend_jiffies = jiffies;
-			} else
-				locomokbd->count_cancel = 0;
+			if (unlikely(key == KEY_ESC))
+				esc_pressed = true;
 		}
-		locomokbd_reset_col(membase, col);
+		locomokbd_reset_col(locomokbd, col);
 	}
-	locomokbd_activate_all(membase);
+	locomokbd_activate_all(locomokbd);
 
 	input_sync(locomokbd->input);
 
 	/* if any keys are pressed, enable the timer */
 	if (num_pressed)
-		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
+		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
 	else
+		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+
+	if (esc_pressed && time_after(jiffies,
+		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
+		if (locomokbd->count_cancel++ > (20)) {
+			input_event(locomokbd->input, EV_PWR,
+					KEY_SUSPEND, 1);
+			locomokbd->suspend_jiffies = jiffies;
+		}
+	} else
 		locomokbd->count_cancel = 0;
 
 	spin_unlock_irqrestore(&locomokbd->lock, flags);
@@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 {
 	struct locomokbd *locomokbd = dev_id;
-	u16 r;
+	unsigned int r;
 
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+
+	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
 	if ((r & 0x0001) == 0)
 		return IRQ_HANDLED;
 
-	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+	/* Mask and Ack */
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
 
-	/** wait chattering delay **/
-	udelay(100);
+	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
 
-	locomokbd_scankeyboard(locomokbd);
 	return IRQ_HANDLED;
 }
 
@@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
 static int locomokbd_open(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
-	return 0;
+
+	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
 }
 
 static void locomokbd_close(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 }
 
-static int locomokbd_probe(struct locomo_dev *dev)
+static int locomokbd_probe(struct platform_device *dev)
 {
 	struct locomokbd *locomokbd;
 	struct input_dev *input_dev;
 	int i, err;
 
-	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!locomokbd || !input_dev) {
-		err = -ENOMEM;
-		goto err_free_mem;
-	}
+	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
+			GFP_KERNEL);
+	if (!locomokbd)
+		return -ENOMEM;
 
-	/* try and claim memory region */
-	if (!request_mem_region((unsigned long) dev->mapbase,
-				dev->length,
-				LOCOMO_DRIVER_NAME(dev))) {
-		err = -EBUSY;
-		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
-		goto err_free_mem;
-	}
+	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!locomokbd->regmap)
+		return -EINVAL;
 
-	locomo_set_drvdata(dev, locomokbd);
+	locomokbd->irq = platform_get_irq(dev, 0);
+	if (locomokbd->irq < 0)
+		return -ENXIO;
 
-	locomokbd->base = (unsigned long) dev->mapbase;
+	platform_set_drvdata(dev, locomokbd);
 
 	spin_lock_init(&locomokbd->lock);
 
@@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	locomokbd->suspend_jiffies = jiffies;
 
-	locomokbd->input = input_dev;
-	strcpy(locomokbd->phys, "locomokbd/input0");
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
+	locomokbd->input = input_dev;
 	input_dev->name = "LoCoMo keyboard";
-	input_dev->phys = locomokbd->phys;
+	input_dev->phys = "locomokbd/input0";
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0001;
@@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	input_set_drvdata(input_dev, locomokbd);
 
-	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
+	memcpy(locomokbd->keycode,
+			locomokbd_keycode,
+			sizeof(locomokbd->keycode));
+
+	if (machine_is_collie())
+		locomokbd->keycode[18] = KEY_HOME;
+	else
+		locomokbd->keycode[3] = KEY_HOME;
+
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
-		set_bit(locomokbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
+	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
+	__set_bit(EV_REP, input_dev->evbit);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
 
 	/* attempt to get the interrupt */
-	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
+	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
+			"locomokbd", locomokbd);
 	if (err) {
-		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
-		goto err_release_region;
+		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
+		goto err_free_mem;
 	}
 
 	err = input_register_device(locomokbd->input);
@@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	return 0;
 
- err_free_irq:
-	free_irq(dev->irq[0], locomokbd);
- err_release_region:
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
-	locomo_set_drvdata(dev, NULL);
- err_free_mem:
+err_free_irq:
+	free_irq(locomokbd->irq, locomokbd);
+err_free_mem:
 	input_free_device(input_dev);
-	kfree(locomokbd);
 
 	return err;
 }
 
-static int locomokbd_remove(struct locomo_dev *dev)
+static int locomokbd_remove(struct platform_device *dev)
 {
-	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
+	struct locomokbd *locomokbd = platform_get_drvdata(dev);
 
-	free_irq(dev->irq[0], locomokbd);
+	free_irq(locomokbd->irq, locomokbd);
 
 	del_timer_sync(&locomokbd->timer);
 
 	input_unregister_device(locomokbd->input);
-	locomo_set_drvdata(dev, NULL);
 
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomokbd_suspend(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 
-	kfree(locomokbd);
+	del_timer_sync(&locomokbd->timer);
 
 	return 0;
 }
 
-static struct locomo_driver keyboard_driver = {
-	.drv = {
-		.name = "locomokbd"
+static int locomokbd_resume(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+	locomokbd_scankeyboard(locomokbd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
+#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
+#else
+#define LOCOMO_KBD_PM	NULL
+#endif
+
+static struct platform_driver locomokbd_driver = {
+	.driver = {
+		.name	= "locomo-kbd",
+		.pm	= LOCOMO_KBD_PM,
 	},
-	.devid	= LOCOMO_DEVID_KEYBOARD,
 	.probe	= locomokbd_probe,
 	.remove	= locomokbd_remove,
 };
 
-static int __init locomokbd_init(void)
-{
-	return locomo_driver_register(&keyboard_driver);
-}
-
-static void __exit locomokbd_exit(void)
-{
-	locomo_driver_unregister(&keyboard_driver);
-}
+module_platform_driver(locomokbd_driver);
 
-module_init(locomokbd_init);
-module_exit(locomokbd_exit);
+MODULE_AUTHOR("John Lenz <lenz-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>");
+MODULE_DESCRIPTION("LoCoMo keyboard driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-kbd");
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

As LoCoMo is switching to new device model, adapt keyboard driver to
support new locomo core driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/input/keyboard/Kconfig     |   1 -
 drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
 2 files changed, 143 insertions(+), 129 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac..0a3d875 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -337,7 +337,6 @@ config KEYBOARD_LM8333
 
 config KEYBOARD_LOCOMO
 	tristate "LoCoMo Keyboard Support"
-	depends on SHARP_LOCOMO
 	help
 	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
 
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index c94d610..eed0a94 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -23,37 +23,37 @@
  *
  */
 
-#include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
-MODULE_DESCRIPTION("LoCoMo keyboard driver");
-MODULE_LICENSE("GPL");
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
 
-#define LOCOMOKBD_NUMKEYS	128
+/* There is one minor difference between mappings on poodle and collie */
+#include <asm/mach-types.h>
 
 #define KEY_ACTIVITY		KEY_F16
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#define KB_ROWS			16
+#define KB_COLS			8
+#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
+#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
+
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
 	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
-	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
+	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
 	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
 	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
 	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
@@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
 };
 
-#define KB_ROWS			16
-#define KB_COLS			8
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
-
 #define KB_DELAY		8
-#define SCAN_INTERVAL		(HZ/10)
 
 struct locomokbd {
 	unsigned char keycode[LOCOMOKBD_NUMKEYS];
 	struct input_dev *input;
-	char phys[32];
 
-	unsigned long base;
+	struct regmap *regmap;
+	int irq;
 	spinlock_t lock;
 
 	struct timer_list timer;
@@ -84,37 +78,33 @@ struct locomokbd {
 };
 
 /* helper functions for reading the keyboard matrix */
-static inline void locomokbd_charge_all(unsigned long membase)
+static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
 {
-	locomo_writel(0x00FF, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
 }
 
-static inline void locomokbd_activate_all(unsigned long membase)
+static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
 {
-	unsigned long r;
-
-	locomo_writel(0, membase + LOCOMO_KSC);
-	r = locomo_readl(membase + LOCOMO_KIC);
-	r &= 0xFEFF;
-	locomo_writel(r, membase + LOCOMO_KIC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
 }
 
-static inline void locomokbd_activate_col(unsigned long membase, int col)
+static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nset;
 	unsigned short nbset;
 
-	nset = 0xFF & ~(1 << col);
+	nset = 0xFF & ~BIT(col);
 	nbset = (nset << 8) + nset;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
-static inline void locomokbd_reset_col(unsigned long membase, int col)
+static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nbset;
 
-	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
 /*
@@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 	unsigned int row, col, rowd;
 	unsigned long flags;
 	unsigned int num_pressed;
-	unsigned long membase = locomokbd->base;
+	bool esc_pressed = false;
 
 	spin_lock_irqsave(&locomokbd->lock, flags);
 
-	locomokbd_charge_all(membase);
+	locomokbd_charge_all(locomokbd);
 
 	num_pressed = 0;
 	for (col = 0; col < KB_COLS; col++) {
-
-		locomokbd_activate_col(membase, col);
+		udelay(KB_DELAY);
+		locomokbd_activate_col(locomokbd, col);
 		udelay(KB_DELAY);
 
-		rowd = ~locomo_readl(membase + LOCOMO_KIB);
+		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
+		rowd = ~rowd;
 		for (row = 0; row < KB_ROWS; row++) {
 			unsigned int scancode, pressed, key;
 
 			scancode = SCANCODE(col, row);
-			pressed = rowd & KB_ROWMASK(row);
+			pressed = rowd & BIT(row);
 			key = locomokbd->keycode[scancode];
 
 			input_report_key(locomokbd->input, key, pressed);
@@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 			/* The "Cancel/ESC" key is labeled "On/Off" on
 			 * Collie and Poodle and should suspend the device
 			 * if it was pressed for more than a second. */
-			if (unlikely(key = KEY_ESC)) {
-				if (!time_after(jiffies,
-					locomokbd->suspend_jiffies + HZ))
-					continue;
-				if (locomokbd->count_cancel++
-					!= (HZ/SCAN_INTERVAL + 1))
-					continue;
-				input_event(locomokbd->input, EV_PWR,
-					KEY_SUSPEND, 1);
-				locomokbd->suspend_jiffies = jiffies;
-			} else
-				locomokbd->count_cancel = 0;
+			if (unlikely(key = KEY_ESC))
+				esc_pressed = true;
 		}
-		locomokbd_reset_col(membase, col);
+		locomokbd_reset_col(locomokbd, col);
 	}
-	locomokbd_activate_all(membase);
+	locomokbd_activate_all(locomokbd);
 
 	input_sync(locomokbd->input);
 
 	/* if any keys are pressed, enable the timer */
 	if (num_pressed)
-		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
+		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
 	else
+		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+
+	if (esc_pressed && time_after(jiffies,
+		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
+		if (locomokbd->count_cancel++ > (20)) {
+			input_event(locomokbd->input, EV_PWR,
+					KEY_SUSPEND, 1);
+			locomokbd->suspend_jiffies = jiffies;
+		}
+	} else
 		locomokbd->count_cancel = 0;
 
 	spin_unlock_irqrestore(&locomokbd->lock, flags);
@@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 {
 	struct locomokbd *locomokbd = dev_id;
-	u16 r;
+	unsigned int r;
 
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+
+	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
 	if ((r & 0x0001) = 0)
 		return IRQ_HANDLED;
 
-	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+	/* Mask and Ack */
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
 
-	/** wait chattering delay **/
-	udelay(100);
+	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
 
-	locomokbd_scankeyboard(locomokbd);
 	return IRQ_HANDLED;
 }
 
@@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
 static int locomokbd_open(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
-	return 0;
+
+	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
 }
 
 static void locomokbd_close(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 }
 
-static int locomokbd_probe(struct locomo_dev *dev)
+static int locomokbd_probe(struct platform_device *dev)
 {
 	struct locomokbd *locomokbd;
 	struct input_dev *input_dev;
 	int i, err;
 
-	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!locomokbd || !input_dev) {
-		err = -ENOMEM;
-		goto err_free_mem;
-	}
+	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
+			GFP_KERNEL);
+	if (!locomokbd)
+		return -ENOMEM;
 
-	/* try and claim memory region */
-	if (!request_mem_region((unsigned long) dev->mapbase,
-				dev->length,
-				LOCOMO_DRIVER_NAME(dev))) {
-		err = -EBUSY;
-		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
-		goto err_free_mem;
-	}
+	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!locomokbd->regmap)
+		return -EINVAL;
 
-	locomo_set_drvdata(dev, locomokbd);
+	locomokbd->irq = platform_get_irq(dev, 0);
+	if (locomokbd->irq < 0)
+		return -ENXIO;
 
-	locomokbd->base = (unsigned long) dev->mapbase;
+	platform_set_drvdata(dev, locomokbd);
 
 	spin_lock_init(&locomokbd->lock);
 
@@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	locomokbd->suspend_jiffies = jiffies;
 
-	locomokbd->input = input_dev;
-	strcpy(locomokbd->phys, "locomokbd/input0");
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
+	locomokbd->input = input_dev;
 	input_dev->name = "LoCoMo keyboard";
-	input_dev->phys = locomokbd->phys;
+	input_dev->phys = "locomokbd/input0";
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0001;
@@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	input_set_drvdata(input_dev, locomokbd);
 
-	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
+	memcpy(locomokbd->keycode,
+			locomokbd_keycode,
+			sizeof(locomokbd->keycode));
+
+	if (machine_is_collie())
+		locomokbd->keycode[18] = KEY_HOME;
+	else
+		locomokbd->keycode[3] = KEY_HOME;
+
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
-		set_bit(locomokbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
+	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
+	__set_bit(EV_REP, input_dev->evbit);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
 
 	/* attempt to get the interrupt */
-	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
+	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
+			"locomokbd", locomokbd);
 	if (err) {
-		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
-		goto err_release_region;
+		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
+		goto err_free_mem;
 	}
 
 	err = input_register_device(locomokbd->input);
@@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	return 0;
 
- err_free_irq:
-	free_irq(dev->irq[0], locomokbd);
- err_release_region:
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
-	locomo_set_drvdata(dev, NULL);
- err_free_mem:
+err_free_irq:
+	free_irq(locomokbd->irq, locomokbd);
+err_free_mem:
 	input_free_device(input_dev);
-	kfree(locomokbd);
 
 	return err;
 }
 
-static int locomokbd_remove(struct locomo_dev *dev)
+static int locomokbd_remove(struct platform_device *dev)
 {
-	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
+	struct locomokbd *locomokbd = platform_get_drvdata(dev);
 
-	free_irq(dev->irq[0], locomokbd);
+	free_irq(locomokbd->irq, locomokbd);
 
 	del_timer_sync(&locomokbd->timer);
 
 	input_unregister_device(locomokbd->input);
-	locomo_set_drvdata(dev, NULL);
 
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomokbd_suspend(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 
-	kfree(locomokbd);
+	del_timer_sync(&locomokbd->timer);
 
 	return 0;
 }
 
-static struct locomo_driver keyboard_driver = {
-	.drv = {
-		.name = "locomokbd"
+static int locomokbd_resume(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+	locomokbd_scankeyboard(locomokbd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
+#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
+#else
+#define LOCOMO_KBD_PM	NULL
+#endif
+
+static struct platform_driver locomokbd_driver = {
+	.driver = {
+		.name	= "locomo-kbd",
+		.pm	= LOCOMO_KBD_PM,
 	},
-	.devid	= LOCOMO_DEVID_KEYBOARD,
 	.probe	= locomokbd_probe,
 	.remove	= locomokbd_remove,
 };
 
-static int __init locomokbd_init(void)
-{
-	return locomo_driver_register(&keyboard_driver);
-}
-
-static void __exit locomokbd_exit(void)
-{
-	locomo_driver_unregister(&keyboard_driver);
-}
+module_platform_driver(locomokbd_driver);
 
-module_init(locomokbd_init);
-module_exit(locomokbd_exit);
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_DESCRIPTION("LoCoMo keyboard driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-kbd");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

As LoCoMo is switching to new device model, adapt keyboard driver to
support new locomo core driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/input/keyboard/Kconfig     |   1 -
 drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
 2 files changed, 143 insertions(+), 129 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 106fbac..0a3d875 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -337,7 +337,6 @@ config KEYBOARD_LM8333
 
 config KEYBOARD_LOCOMO
 	tristate "LoCoMo Keyboard Support"
-	depends on SHARP_LOCOMO
 	help
 	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
 
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index c94d610..eed0a94 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -23,37 +23,37 @@
  *
  */
 
-#include <linux/slab.h>
-#include <linux/module.h>
+#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/input.h>
-#include <linux/delay.h>
-#include <linux/device.h>
 #include <linux/interrupt.h>
-#include <linux/ioport.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
-MODULE_DESCRIPTION("LoCoMo keyboard driver");
-MODULE_LICENSE("GPL");
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
 
-#define LOCOMOKBD_NUMKEYS	128
+/* There is one minor difference between mappings on poodle and collie */
+#include <asm/mach-types.h>
 
 #define KEY_ACTIVITY		KEY_F16
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#define KB_ROWS			16
+#define KB_COLS			8
+#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
+#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
+
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
 	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
-	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
+	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
 	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
 	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
 	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
@@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
 };
 
-#define KB_ROWS			16
-#define KB_COLS			8
-#define KB_ROWMASK(r)		(1 << (r))
-#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
-
 #define KB_DELAY		8
-#define SCAN_INTERVAL		(HZ/10)
 
 struct locomokbd {
 	unsigned char keycode[LOCOMOKBD_NUMKEYS];
 	struct input_dev *input;
-	char phys[32];
 
-	unsigned long base;
+	struct regmap *regmap;
+	int irq;
 	spinlock_t lock;
 
 	struct timer_list timer;
@@ -84,37 +78,33 @@ struct locomokbd {
 };
 
 /* helper functions for reading the keyboard matrix */
-static inline void locomokbd_charge_all(unsigned long membase)
+static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
 {
-	locomo_writel(0x00FF, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
 }
 
-static inline void locomokbd_activate_all(unsigned long membase)
+static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
 {
-	unsigned long r;
-
-	locomo_writel(0, membase + LOCOMO_KSC);
-	r = locomo_readl(membase + LOCOMO_KIC);
-	r &= 0xFEFF;
-	locomo_writel(r, membase + LOCOMO_KIC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
 }
 
-static inline void locomokbd_activate_col(unsigned long membase, int col)
+static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nset;
 	unsigned short nbset;
 
-	nset = 0xFF & ~(1 << col);
+	nset = 0xFF & ~BIT(col);
 	nbset = (nset << 8) + nset;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
-static inline void locomokbd_reset_col(unsigned long membase, int col)
+static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
 {
 	unsigned short nbset;
 
-	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
-	locomo_writel(nbset, membase + LOCOMO_KSC);
+	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
 }
 
 /*
@@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 	unsigned int row, col, rowd;
 	unsigned long flags;
 	unsigned int num_pressed;
-	unsigned long membase = locomokbd->base;
+	bool esc_pressed = false;
 
 	spin_lock_irqsave(&locomokbd->lock, flags);
 
-	locomokbd_charge_all(membase);
+	locomokbd_charge_all(locomokbd);
 
 	num_pressed = 0;
 	for (col = 0; col < KB_COLS; col++) {
-
-		locomokbd_activate_col(membase, col);
+		udelay(KB_DELAY);
+		locomokbd_activate_col(locomokbd, col);
 		udelay(KB_DELAY);
 
-		rowd = ~locomo_readl(membase + LOCOMO_KIB);
+		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
+		rowd = ~rowd;
 		for (row = 0; row < KB_ROWS; row++) {
 			unsigned int scancode, pressed, key;
 
 			scancode = SCANCODE(col, row);
-			pressed = rowd & KB_ROWMASK(row);
+			pressed = rowd & BIT(row);
 			key = locomokbd->keycode[scancode];
 
 			input_report_key(locomokbd->input, key, pressed);
@@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 			/* The "Cancel/ESC" key is labeled "On/Off" on
 			 * Collie and Poodle and should suspend the device
 			 * if it was pressed for more than a second. */
-			if (unlikely(key == KEY_ESC)) {
-				if (!time_after(jiffies,
-					locomokbd->suspend_jiffies + HZ))
-					continue;
-				if (locomokbd->count_cancel++
-					!= (HZ/SCAN_INTERVAL + 1))
-					continue;
-				input_event(locomokbd->input, EV_PWR,
-					KEY_SUSPEND, 1);
-				locomokbd->suspend_jiffies = jiffies;
-			} else
-				locomokbd->count_cancel = 0;
+			if (unlikely(key == KEY_ESC))
+				esc_pressed = true;
 		}
-		locomokbd_reset_col(membase, col);
+		locomokbd_reset_col(locomokbd, col);
 	}
-	locomokbd_activate_all(membase);
+	locomokbd_activate_all(locomokbd);
 
 	input_sync(locomokbd->input);
 
 	/* if any keys are pressed, enable the timer */
 	if (num_pressed)
-		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
+		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
 	else
+		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+
+	if (esc_pressed && time_after(jiffies,
+		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
+		if (locomokbd->count_cancel++ > (20)) {
+			input_event(locomokbd->input, EV_PWR,
+					KEY_SUSPEND, 1);
+			locomokbd->suspend_jiffies = jiffies;
+		}
+	} else
 		locomokbd->count_cancel = 0;
 
 	spin_unlock_irqrestore(&locomokbd->lock, flags);
@@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
 static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
 {
 	struct locomokbd *locomokbd = dev_id;
-	u16 r;
+	unsigned int r;
 
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
+
+	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
 	if ((r & 0x0001) == 0)
 		return IRQ_HANDLED;
 
-	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
+	/* Mask and Ack */
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
 
-	/** wait chattering delay **/
-	udelay(100);
+	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
 
-	locomokbd_scankeyboard(locomokbd);
 	return IRQ_HANDLED;
 }
 
@@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
 static int locomokbd_open(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
-	return 0;
+
+	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
 }
 
 static void locomokbd_close(struct input_dev *dev)
 {
 	struct locomokbd *locomokbd = input_get_drvdata(dev);
-	u16 r;
-	
-	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
-	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 }
 
-static int locomokbd_probe(struct locomo_dev *dev)
+static int locomokbd_probe(struct platform_device *dev)
 {
 	struct locomokbd *locomokbd;
 	struct input_dev *input_dev;
 	int i, err;
 
-	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
-	input_dev = input_allocate_device();
-	if (!locomokbd || !input_dev) {
-		err = -ENOMEM;
-		goto err_free_mem;
-	}
+	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
+			GFP_KERNEL);
+	if (!locomokbd)
+		return -ENOMEM;
 
-	/* try and claim memory region */
-	if (!request_mem_region((unsigned long) dev->mapbase,
-				dev->length,
-				LOCOMO_DRIVER_NAME(dev))) {
-		err = -EBUSY;
-		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
-		goto err_free_mem;
-	}
+	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!locomokbd->regmap)
+		return -EINVAL;
 
-	locomo_set_drvdata(dev, locomokbd);
+	locomokbd->irq = platform_get_irq(dev, 0);
+	if (locomokbd->irq < 0)
+		return -ENXIO;
 
-	locomokbd->base = (unsigned long) dev->mapbase;
+	platform_set_drvdata(dev, locomokbd);
 
 	spin_lock_init(&locomokbd->lock);
 
@@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	locomokbd->suspend_jiffies = jiffies;
 
-	locomokbd->input = input_dev;
-	strcpy(locomokbd->phys, "locomokbd/input0");
+	input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
+	locomokbd->input = input_dev;
 	input_dev->name = "LoCoMo keyboard";
-	input_dev->phys = locomokbd->phys;
+	input_dev->phys = "locomokbd/input0";
 	input_dev->id.bustype = BUS_HOST;
 	input_dev->id.vendor = 0x0001;
 	input_dev->id.product = 0x0001;
@@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	input_set_drvdata(input_dev, locomokbd);
 
-	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
+	memcpy(locomokbd->keycode,
+			locomokbd_keycode,
+			sizeof(locomokbd->keycode));
+
+	if (machine_is_collie())
+		locomokbd->keycode[18] = KEY_HOME;
+	else
+		locomokbd->keycode[3] = KEY_HOME;
+
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
-		set_bit(locomokbd->keycode[i], input_dev->keybit);
-	clear_bit(0, input_dev->keybit);
+		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
+	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
+	__set_bit(EV_REP, input_dev->evbit);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
+	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
 
 	/* attempt to get the interrupt */
-	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
+	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
+			"locomokbd", locomokbd);
 	if (err) {
-		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
-		goto err_release_region;
+		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
+		goto err_free_mem;
 	}
 
 	err = input_register_device(locomokbd->input);
@@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
 
 	return 0;
 
- err_free_irq:
-	free_irq(dev->irq[0], locomokbd);
- err_release_region:
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
-	locomo_set_drvdata(dev, NULL);
- err_free_mem:
+err_free_irq:
+	free_irq(locomokbd->irq, locomokbd);
+err_free_mem:
 	input_free_device(input_dev);
-	kfree(locomokbd);
 
 	return err;
 }
 
-static int locomokbd_remove(struct locomo_dev *dev)
+static int locomokbd_remove(struct platform_device *dev)
 {
-	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
+	struct locomokbd *locomokbd = platform_get_drvdata(dev);
 
-	free_irq(dev->irq[0], locomokbd);
+	free_irq(locomokbd->irq, locomokbd);
 
 	del_timer_sync(&locomokbd->timer);
 
 	input_unregister_device(locomokbd->input);
-	locomo_set_drvdata(dev, NULL);
 
-	release_mem_region((unsigned long) dev->mapbase, dev->length);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomokbd_suspend(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
 
-	kfree(locomokbd);
+	del_timer_sync(&locomokbd->timer);
 
 	return 0;
 }
 
-static struct locomo_driver keyboard_driver = {
-	.drv = {
-		.name = "locomokbd"
+static int locomokbd_resume(struct device *dev)
+{
+	struct locomokbd *locomokbd = dev_get_drvdata(dev);
+
+	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
+	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
+	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
+
+	locomokbd_scankeyboard(locomokbd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
+#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
+#else
+#define LOCOMO_KBD_PM	NULL
+#endif
+
+static struct platform_driver locomokbd_driver = {
+	.driver = {
+		.name	= "locomo-kbd",
+		.pm	= LOCOMO_KBD_PM,
 	},
-	.devid	= LOCOMO_DEVID_KEYBOARD,
 	.probe	= locomokbd_probe,
 	.remove	= locomokbd_remove,
 };
 
-static int __init locomokbd_init(void)
-{
-	return locomo_driver_register(&keyboard_driver);
-}
-
-static void __exit locomokbd_exit(void)
-{
-	locomo_driver_unregister(&keyboard_driver);
-}
+module_platform_driver(locomokbd_driver);
 
-module_init(locomokbd_init);
-module_exit(locomokbd_exit);
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_DESCRIPTION("LoCoMo keyboard driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-kbd");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
       [not found] ` <1430178954-11138-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
able to trigger sysrq functions directly. Add an option providing sysrq
mapping for Contact-Home keys.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/input/keyboard/Kconfig     |  7 +++++++
 drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0a3d875..eb8b11b 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
 	  To compile this driver as a module, choose M here: the
 	  module will be called locomokbd.
 
+config KEYBOARD_LOCOMO_SYSRQ
+	bool "Provide SysRQ key on LoCoMo keyboard"
+	depends on KEYBOARD_LOCOMO
+	help
+	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
+	  Say N if you want to use them as usual keys.
+
 config KEYBOARD_LPC32XX
 	tristate "LPC32XX matrix key scanner support"
 	depends on ARCH_LPC32XX && OF
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index eed0a94..eb8dbe2 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -40,6 +40,14 @@
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
+#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
+#define LOCOMO_KEY_HOME		KEY_SYSRQ
+#else
+#define LOCOMO_KEY_CONTACT	KEY_CONTACT
+#define LOCOMO_KEY_HOME		KEY_HOME
+#endif
+
 #define KB_ROWS			16
 #define KB_COLS			8
 #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
@@ -48,7 +56,7 @@
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
@@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
 			sizeof(locomokbd->keycode));
 
 	if (machine_is_collie())
-		locomokbd->keycode[18] = KEY_HOME;
+		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
 	else
-		locomokbd->keycode[3] = KEY_HOME;
+		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
 
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
 		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
able to trigger sysrq functions directly. Add an option providing sysrq
mapping for Contact-Home keys.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/input/keyboard/Kconfig     |  7 +++++++
 drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0a3d875..eb8b11b 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
 	  To compile this driver as a module, choose M here: the
 	  module will be called locomokbd.
 
+config KEYBOARD_LOCOMO_SYSRQ
+	bool "Provide SysRQ key on LoCoMo keyboard"
+	depends on KEYBOARD_LOCOMO
+	help
+	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
+	  Say N if you want to use them as usual keys.
+
 config KEYBOARD_LPC32XX
 	tristate "LPC32XX matrix key scanner support"
 	depends on ARCH_LPC32XX && OF
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index eed0a94..eb8dbe2 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -40,6 +40,14 @@
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
+#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
+#define LOCOMO_KEY_HOME		KEY_SYSRQ
+#else
+#define LOCOMO_KEY_CONTACT	KEY_CONTACT
+#define LOCOMO_KEY_HOME		KEY_HOME
+#endif
+
 #define KB_ROWS			16
 #define KB_COLS			8
 #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
@@ -48,7 +56,7 @@
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
@@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
 			sizeof(locomokbd->keycode));
 
 	if (machine_is_collie())
-		locomokbd->keycode[18] = KEY_HOME;
+		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
 	else
-		locomokbd->keycode[3] = KEY_HOME;
+		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
 
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
 		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
able to trigger sysrq functions directly. Add an option providing sysrq
mapping for Contact-Home keys.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/input/keyboard/Kconfig     |  7 +++++++
 drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0a3d875..eb8b11b 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
 	  To compile this driver as a module, choose M here: the
 	  module will be called locomokbd.
 
+config KEYBOARD_LOCOMO_SYSRQ
+	bool "Provide SysRQ key on LoCoMo keyboard"
+	depends on KEYBOARD_LOCOMO
+	help
+	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
+	  Say N if you want to use them as usual keys.
+
 config KEYBOARD_LPC32XX
 	tristate "LPC32XX matrix key scanner support"
 	depends on ARCH_LPC32XX && OF
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index eed0a94..eb8dbe2 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -40,6 +40,14 @@
 #define KEY_CONTACT		KEY_F18
 #define KEY_CENTER		KEY_F15
 
+#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
+#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
+#define LOCOMO_KEY_HOME		KEY_SYSRQ
+#else
+#define LOCOMO_KEY_CONTACT	KEY_CONTACT
+#define LOCOMO_KEY_HOME		KEY_HOME
+#endif
+
 #define KB_ROWS			16
 #define KB_COLS			8
 #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
@@ -48,7 +56,7 @@
 static const unsigned char
 locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
 	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
-	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
+	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
 	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
 	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
@@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
 			sizeof(locomokbd->keycode));
 
 	if (machine_is_collie())
-		locomokbd->keycode[18] = KEY_HOME;
+		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
 	else
-		locomokbd->keycode[3] = KEY_HOME;
+		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
 
 	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
 		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 05/17] video: backlight: add new locomo backlight driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Add new simple backlight driver - it cares only about PWM/frontlight
part of LoCoMo, it does not touch TFT settings and does not export TFT
power control.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/Kconfig     |   6 +-
 drivers/video/backlight/Makefile    |   2 +-
 drivers/video/backlight/locomo_bl.c | 153 ++++++++++++++++++++++++++++++++++++
 3 files changed, 157 insertions(+), 4 deletions(-)
 create mode 100644 drivers/video/backlight/locomo_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2d9923a..6c093e2 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -217,12 +217,12 @@ config BACKLIGHT_LM3533
 	  levels.
 
 config BACKLIGHT_LOCOMO
-	tristate "Sharp LOCOMO LCD/Backlight Driver"
-	depends on SHARP_LOCOMO
+	tristate "Sharp LOCOMO Backlight Driver"
+	depends on MFD_LOCOMO
 	default y
 	help
 	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
-	  enable the LCD/backlight driver.
+	  enable the backlight driver.
 
 config BACKLIGHT_OMAP1
 	tristate "OMAP1 PWL-based LCD Backlight"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index d67073f..2de73d2 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO)	+= ipaq_micro_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3533)		+= lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)		+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639)		+= lm3639_bl.o
-obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomo_bl.o
 obj-$(CONFIG_BACKLIGHT_LP855X)		+= lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_LP8788)		+= lp8788_bl.o
 obj-$(CONFIG_BACKLIGHT_LV5207LP)	+= lv5207lp.o
diff --git a/drivers/video/backlight/locomo_bl.c b/drivers/video/backlight/locomo_bl.c
new file mode 100644
index 0000000..cc60022
--- /dev/null
+++ b/drivers/video/backlight/locomo_bl.c
@@ -0,0 +1,153 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_bl {
+	struct regmap *regmap;
+	int current_intensity;
+	struct gpio_desc *fl_vr;
+};
+
+static const struct {
+	u16 duty, bpwf;
+	bool vr;
+} locomo_bl_pwm[] = {
+	{ 0, 161, false },
+	{ 117, 161, false },
+	{ 163, 148, false },
+	{ 194, 161, false },
+	{ 194, 161, true },
+};
+
+static int locomo_bl_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		intensity = 0;
+
+	gpiod_set_value(bl->fl_vr, locomo_bl_pwm[intensity].vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALD, locomo_bl_pwm[intensity].duty);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf |
+			LOCOMO_ALS_EN);
+
+	bl->current_intensity = intensity;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		regmap_write(bl->regmap, LOCOMO_ALS, 0x00);
+
+	return 0;
+}
+
+static int locomo_bl_get_intensity(struct backlight_device *bd)
+{
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	return bl->current_intensity;
+}
+
+static const struct backlight_ops locomo_bl_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.get_brightness = locomo_bl_get_intensity,
+	.update_status  = locomo_bl_set_intensity,
+};
+
+static int locomo_bl_probe(struct platform_device *dev)
+{
+	struct backlight_properties props;
+	struct locomo_bl *bl;
+	struct backlight_device *locomo_bl_device;
+
+	bl = devm_kmalloc(&dev->dev, sizeof(struct locomo_bl), GFP_KERNEL);
+	if (!bl)
+		return -ENOMEM;
+
+	bl->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!bl->regmap)
+		return -ENODEV;
+
+	bl->fl_vr = devm_gpiod_get(&dev->dev, "flvr", GPIOD_OUT_LOW);
+	if (IS_ERR(bl->fl_vr))
+		return PTR_ERR(bl->fl_vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, 0);
+	regmap_write(bl->regmap, LOCOMO_ALD, 0);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = ARRAY_SIZE(locomo_bl_pwm) - 1;
+	props.brightness = props.max_brightness / 2;
+	locomo_bl_device = devm_backlight_device_register(&dev->dev,
+						"locomo-bl",
+						&dev->dev, bl,
+						&locomo_bl_ops, &props);
+
+	if (IS_ERR(locomo_bl_device))
+		return PTR_ERR(locomo_bl_device);
+
+	platform_set_drvdata(dev, locomo_bl_device);
+
+	/* Set up frontlight so that screen is readable */
+	backlight_update_status(locomo_bl_device);
+
+	return 0;
+}
+
+static void locomo_bl_shutdown(struct platform_device *dev)
+{
+	struct backlight_device *locomo_bl_device = platform_get_drvdata(dev);
+
+	locomo_bl_device->props.brightness = 0;
+	locomo_bl_device->props.power = 0;
+	locomo_bl_set_intensity(locomo_bl_device);
+}
+
+static int locomo_bl_remove(struct platform_device *dev)
+{
+	locomo_bl_shutdown(dev);
+
+	return 0;
+}
+
+static struct platform_driver locomo_bl_driver = {
+	.driver = {
+		.name	= "locomo-backlight",
+	},
+	.probe	= locomo_bl_probe,
+	.remove	= locomo_bl_remove,
+	/* Turn off bl on power off/reboot */
+	.shutdown = locomo_bl_shutdown,
+};
+
+module_platform_driver(locomo_bl_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_AUTHOR("Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("LoCoMo Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-backlight");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 05/17] video: backlight: add new locomo backlight driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Add new simple backlight driver - it cares only about PWM/frontlight
part of LoCoMo, it does not touch TFT settings and does not export TFT
power control.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/Kconfig     |   6 +-
 drivers/video/backlight/Makefile    |   2 +-
 drivers/video/backlight/locomo_bl.c | 153 ++++++++++++++++++++++++++++++++++++
 3 files changed, 157 insertions(+), 4 deletions(-)
 create mode 100644 drivers/video/backlight/locomo_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2d9923a..6c093e2 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -217,12 +217,12 @@ config BACKLIGHT_LM3533
 	  levels.
 
 config BACKLIGHT_LOCOMO
-	tristate "Sharp LOCOMO LCD/Backlight Driver"
-	depends on SHARP_LOCOMO
+	tristate "Sharp LOCOMO Backlight Driver"
+	depends on MFD_LOCOMO
 	default y
 	help
 	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
-	  enable the LCD/backlight driver.
+	  enable the backlight driver.
 
 config BACKLIGHT_OMAP1
 	tristate "OMAP1 PWL-based LCD Backlight"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index d67073f..2de73d2 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO)	+= ipaq_micro_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3533)		+= lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)		+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639)		+= lm3639_bl.o
-obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomo_bl.o
 obj-$(CONFIG_BACKLIGHT_LP855X)		+= lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_LP8788)		+= lp8788_bl.o
 obj-$(CONFIG_BACKLIGHT_LV5207LP)	+= lv5207lp.o
diff --git a/drivers/video/backlight/locomo_bl.c b/drivers/video/backlight/locomo_bl.c
new file mode 100644
index 0000000..cc60022
--- /dev/null
+++ b/drivers/video/backlight/locomo_bl.c
@@ -0,0 +1,153 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_bl {
+	struct regmap *regmap;
+	int current_intensity;
+	struct gpio_desc *fl_vr;
+};
+
+static const struct {
+	u16 duty, bpwf;
+	bool vr;
+} locomo_bl_pwm[] = {
+	{ 0, 161, false },
+	{ 117, 161, false },
+	{ 163, 148, false },
+	{ 194, 161, false },
+	{ 194, 161, true },
+};
+
+static int locomo_bl_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		intensity = 0;
+
+	gpiod_set_value(bl->fl_vr, locomo_bl_pwm[intensity].vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALD, locomo_bl_pwm[intensity].duty);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf |
+			LOCOMO_ALS_EN);
+
+	bl->current_intensity = intensity;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		regmap_write(bl->regmap, LOCOMO_ALS, 0x00);
+
+	return 0;
+}
+
+static int locomo_bl_get_intensity(struct backlight_device *bd)
+{
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	return bl->current_intensity;
+}
+
+static const struct backlight_ops locomo_bl_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.get_brightness = locomo_bl_get_intensity,
+	.update_status  = locomo_bl_set_intensity,
+};
+
+static int locomo_bl_probe(struct platform_device *dev)
+{
+	struct backlight_properties props;
+	struct locomo_bl *bl;
+	struct backlight_device *locomo_bl_device;
+
+	bl = devm_kmalloc(&dev->dev, sizeof(struct locomo_bl), GFP_KERNEL);
+	if (!bl)
+		return -ENOMEM;
+
+	bl->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!bl->regmap)
+		return -ENODEV;
+
+	bl->fl_vr = devm_gpiod_get(&dev->dev, "flvr", GPIOD_OUT_LOW);
+	if (IS_ERR(bl->fl_vr))
+		return PTR_ERR(bl->fl_vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, 0);
+	regmap_write(bl->regmap, LOCOMO_ALD, 0);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = ARRAY_SIZE(locomo_bl_pwm) - 1;
+	props.brightness = props.max_brightness / 2;
+	locomo_bl_device = devm_backlight_device_register(&dev->dev,
+						"locomo-bl",
+						&dev->dev, bl,
+						&locomo_bl_ops, &props);
+
+	if (IS_ERR(locomo_bl_device))
+		return PTR_ERR(locomo_bl_device);
+
+	platform_set_drvdata(dev, locomo_bl_device);
+
+	/* Set up frontlight so that screen is readable */
+	backlight_update_status(locomo_bl_device);
+
+	return 0;
+}
+
+static void locomo_bl_shutdown(struct platform_device *dev)
+{
+	struct backlight_device *locomo_bl_device = platform_get_drvdata(dev);
+
+	locomo_bl_device->props.brightness = 0;
+	locomo_bl_device->props.power = 0;
+	locomo_bl_set_intensity(locomo_bl_device);
+}
+
+static int locomo_bl_remove(struct platform_device *dev)
+{
+	locomo_bl_shutdown(dev);
+
+	return 0;
+}
+
+static struct platform_driver locomo_bl_driver = {
+	.driver = {
+		.name	= "locomo-backlight",
+	},
+	.probe	= locomo_bl_probe,
+	.remove	= locomo_bl_remove,
+	/* Turn off bl on power off/reboot */
+	.shutdown = locomo_bl_shutdown,
+};
+
+module_platform_driver(locomo_bl_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_AUTHOR("Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("LoCoMo Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-backlight");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 05/17] video: backlight: add new locomo backlight driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Add new simple backlight driver - it cares only about PWM/frontlight
part of LoCoMo, it does not touch TFT settings and does not export TFT
power control.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/Kconfig     |   6 +-
 drivers/video/backlight/Makefile    |   2 +-
 drivers/video/backlight/locomo_bl.c | 153 ++++++++++++++++++++++++++++++++++++
 3 files changed, 157 insertions(+), 4 deletions(-)
 create mode 100644 drivers/video/backlight/locomo_bl.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 2d9923a..6c093e2 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -217,12 +217,12 @@ config BACKLIGHT_LM3533
 	  levels.
 
 config BACKLIGHT_LOCOMO
-	tristate "Sharp LOCOMO LCD/Backlight Driver"
-	depends on SHARP_LOCOMO
+	tristate "Sharp LOCOMO Backlight Driver"
+	depends on MFD_LOCOMO
 	default y
 	help
 	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
-	  enable the LCD/backlight driver.
+	  enable the backlight driver.
 
 config BACKLIGHT_OMAP1
 	tristate "OMAP1 PWL-based LCD Backlight"
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index d67073f..2de73d2 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -39,7 +39,7 @@ obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO)	+= ipaq_micro_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3533)		+= lm3533_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3630A)		+= lm3630a_bl.o
 obj-$(CONFIG_BACKLIGHT_LM3639)		+= lm3639_bl.o
-obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomo_bl.o
 obj-$(CONFIG_BACKLIGHT_LP855X)		+= lp855x_bl.o
 obj-$(CONFIG_BACKLIGHT_LP8788)		+= lp8788_bl.o
 obj-$(CONFIG_BACKLIGHT_LV5207LP)	+= lv5207lp.o
diff --git a/drivers/video/backlight/locomo_bl.c b/drivers/video/backlight/locomo_bl.c
new file mode 100644
index 0000000..cc60022
--- /dev/null
+++ b/drivers/video/backlight/locomo_bl.c
@@ -0,0 +1,153 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_bl {
+	struct regmap *regmap;
+	int current_intensity;
+	struct gpio_desc *fl_vr;
+};
+
+static const struct {
+	u16 duty, bpwf;
+	bool vr;
+} locomo_bl_pwm[] = {
+	{ 0, 161, false },
+	{ 117, 161, false },
+	{ 163, 148, false },
+	{ 194, 161, false },
+	{ 194, 161, true },
+};
+
+static int locomo_bl_set_intensity(struct backlight_device *bd)
+{
+	int intensity = bd->props.brightness;
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	if (bd->props.power != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
+		intensity = 0;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		intensity = 0;
+
+	gpiod_set_value(bl->fl_vr, locomo_bl_pwm[intensity].vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALD, locomo_bl_pwm[intensity].duty);
+	usleep_range(100, 200);
+	regmap_write(bl->regmap, LOCOMO_ALS, locomo_bl_pwm[intensity].bpwf |
+			LOCOMO_ALS_EN);
+
+	bl->current_intensity = intensity;
+	if (bd->props.state & BL_CORE_SUSPENDED)
+		regmap_write(bl->regmap, LOCOMO_ALS, 0x00);
+
+	return 0;
+}
+
+static int locomo_bl_get_intensity(struct backlight_device *bd)
+{
+	struct locomo_bl *bl = dev_get_drvdata(&bd->dev);
+
+	return bl->current_intensity;
+}
+
+static const struct backlight_ops locomo_bl_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.get_brightness = locomo_bl_get_intensity,
+	.update_status  = locomo_bl_set_intensity,
+};
+
+static int locomo_bl_probe(struct platform_device *dev)
+{
+	struct backlight_properties props;
+	struct locomo_bl *bl;
+	struct backlight_device *locomo_bl_device;
+
+	bl = devm_kmalloc(&dev->dev, sizeof(struct locomo_bl), GFP_KERNEL);
+	if (!bl)
+		return -ENOMEM;
+
+	bl->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!bl->regmap)
+		return -ENODEV;
+
+	bl->fl_vr = devm_gpiod_get(&dev->dev, "flvr", GPIOD_OUT_LOW);
+	if (IS_ERR(bl->fl_vr))
+		return PTR_ERR(bl->fl_vr);
+
+	regmap_write(bl->regmap, LOCOMO_ALS, 0);
+	regmap_write(bl->regmap, LOCOMO_ALD, 0);
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_RAW;
+	props.max_brightness = ARRAY_SIZE(locomo_bl_pwm) - 1;
+	props.brightness = props.max_brightness / 2;
+	locomo_bl_device = devm_backlight_device_register(&dev->dev,
+						"locomo-bl",
+						&dev->dev, bl,
+						&locomo_bl_ops, &props);
+
+	if (IS_ERR(locomo_bl_device))
+		return PTR_ERR(locomo_bl_device);
+
+	platform_set_drvdata(dev, locomo_bl_device);
+
+	/* Set up frontlight so that screen is readable */
+	backlight_update_status(locomo_bl_device);
+
+	return 0;
+}
+
+static void locomo_bl_shutdown(struct platform_device *dev)
+{
+	struct backlight_device *locomo_bl_device = platform_get_drvdata(dev);
+
+	locomo_bl_device->props.brightness = 0;
+	locomo_bl_device->props.power = 0;
+	locomo_bl_set_intensity(locomo_bl_device);
+}
+
+static int locomo_bl_remove(struct platform_device *dev)
+{
+	locomo_bl_shutdown(dev);
+
+	return 0;
+}
+
+static struct platform_driver locomo_bl_driver = {
+	.driver = {
+		.name	= "locomo-backlight",
+	},
+	.probe	= locomo_bl_probe,
+	.remove	= locomo_bl_remove,
+	/* Turn off bl on power off/reboot */
+	.shutdown = locomo_bl_shutdown,
+};
+
+module_platform_driver(locomo_bl_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_AUTHOR("Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("LoCoMo Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-backlight");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 06/17] video: lcd: add LoCoMo LCD driver
       [not found] ` <1430178954-11138-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

LoCoMo has some special handling for TFT screens attached to Collie and
Poodle. Implement that as a separate driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/video/backlight/Kconfig      |  10 ++
 drivers/video/backlight/Makefile     |   1 +
 drivers/video/backlight/locomo_lcd.c | 285 +++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/video/backlight/locomo_lcd.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 6c093e2..b2f995c 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -48,6 +48,16 @@ config LCD_LMS283GF05
 	  SPI driver for Samsung LMS283GF05. This provides basic support
 	  for powering the LCD up/down through a sysfs interface.
 
+config LCD_LOCOMO
+	tristate "Sharp LOCOMO LCD Driver"
+	depends on MFD_LOCOMO
+	select IIO
+	help
+	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
+	  enable the LCD driver.  The panel starts up in power
+	  off state, so you need this driver in order to see any
+	  output.
+
 config LCD_LTV350QV
 	tristate "Samsung LTV350QV LCD Panel"
 	depends on SPI_MASTER
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 2de73d2..686cf1a 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LCD_L4F00242T03)		+= l4f00242t03.o
 obj-$(CONFIG_LCD_LD9040)		+= ld9040.o
 obj-$(CONFIG_LCD_LMS283GF05)		+= lms283gf05.o
 obj-$(CONFIG_LCD_LMS501KF03)		+= lms501kf03.o
+obj-$(CONFIG_LCD_LOCOMO)		+= locomo_lcd.o
 obj-$(CONFIG_LCD_LTV350QV)		+= ltv350qv.o
 obj-$(CONFIG_LCD_PLATFORM)		+= platform_lcd.o
 obj-$(CONFIG_LCD_S6E63M0)		+= s6e63m0.o
diff --git a/drivers/video/backlight/locomo_lcd.c b/drivers/video/backlight/locomo_lcd.c
new file mode 100644
index 0000000..dc316cb
--- /dev/null
+++ b/drivers/video/backlight/locomo_lcd.c
@@ -0,0 +1,285 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>
+ * Maintainer: Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/consumer.h>
+#include <linux/lcd.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_lcd {
+	struct regmap *regmap;
+	struct platform_device *dev;
+	struct locomo_lcd_platform_data *data;
+	int power;
+	struct iio_channel *comadj;
+	struct gpio_desc *vsha, *vshd, *vee, *mod;
+};
+
+static void locomo_lcd_on(struct locomo_lcd *lcd)
+{
+	gpiod_set_value(lcd->vsha, 1);
+	usleep_range(2000, 3000);
+
+	gpiod_set_value(lcd->vshd, 1);
+	usleep_range(2000, 3000);
+
+	iio_write_channel_raw(lcd->comadj, lcd->data->comadj);
+	usleep_range(5000, 6000);
+
+	gpiod_set_value(lcd->vee, 1);
+	usleep_range(10000, 11000);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x01);
+
+	/* Set CPSD */
+	regmap_write(lcd->regmap, LOCOMO_CPSD, 6);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x04 | 0x01);
+	usleep_range(10000, 11000);
+
+	gpiod_set_value(lcd->mod, 1);
+}
+
+static void locomo_lcd_off(struct locomo_lcd *lcd)
+{
+	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x06);
+	usleep_range(1000, 2000);
+
+	gpiod_set_value(lcd->vsha, 0);
+	msleep(110);
+
+	gpiod_set_value(lcd->vee, 0);
+	msleep(700);
+
+	iio_write_channel_raw(lcd->comadj, 0);
+	usleep_range(5000, 6000);
+
+	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0);
+	gpiod_set_value(lcd->mod, 0);
+	gpiod_set_value(lcd->vshd, 0);
+}
+
+static void locomo_lcd_program_adsync(struct locomo_lcd *lcd)
+{
+	regmap_write(lcd->regmap, LOCOMO_ASD,
+			6 + 8 + 320 + 30 - 10);
+	regmap_update_bits(lcd->regmap, LOCOMO_ASD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSD,
+			6 + 8 + 320 + 30 - 10 - 128 + 4);
+	regmap_update_bits(lcd->regmap, LOCOMO_HSD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSC, 128 / 8);
+
+	/* XON */
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x80);
+	usleep_range(1000, 1100);
+
+	/* CLK9MEN */
+	regmap_update_bits(lcd->regmap, LOCOMO_TADC,
+		0x10,
+		0x10);
+	usleep_range(100, 200);
+}
+
+static void locomo_lcd_disable_adsync(struct locomo_lcd *lcd)
+{
+	/* ADSTART */
+	regmap_write(lcd->regmap, LOCOMO_ASD, 0x00);
+
+	/* 18MHz clock off*/
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x00);
+}
+
+int locomo_lcd_set_power(struct lcd_device *ldev, int power)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	dev_dbg(&ldev->dev, "LCD power %d (is %d)\n", power, lcd->power);
+
+	if (!power && lcd->power)
+		locomo_lcd_on(lcd);
+
+	if (power && !lcd->power)
+		locomo_lcd_off(lcd);
+
+	lcd->power = power;
+
+	return 0;
+}
+
+static int locomo_lcd_get_power(struct lcd_device *ldev)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	return lcd->power;
+}
+
+static struct lcd_ops locomo_lcd_ops = {
+	.set_power = locomo_lcd_set_power,
+	.get_power = locomo_lcd_get_power,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_lcd_suspend(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	return 0;
+}
+
+static int locomo_lcd_resume(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_program_adsync(lcd);
+
+	if (!lcd->power)
+		locomo_lcd_on(lcd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_lcd_pm, locomo_lcd_suspend, locomo_lcd_resume);
+#define LOCOMOLCD_PM	(&locomo_lcd_pm)
+#else
+#define LOCOMOLCD_PM	NULL
+#endif
+
+static int locomo_lcd_probe(struct platform_device *dev)
+{
+	struct lcd_device *lcd_dev;
+	struct locomo_lcd *lcd;
+	int rc;
+
+	lcd = devm_kmalloc(&dev->dev, sizeof(struct locomo_lcd), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->dev = dev;
+	lcd->power = FB_BLANK_NORMAL;
+
+	lcd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!lcd->regmap)
+		return -ENODEV;
+
+	lcd->data = dev_get_platdata(&dev->dev);
+	if (!lcd->data)
+		return -EINVAL;
+
+	lcd->vsha = devm_gpiod_get(&dev->dev, "VSHA", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vsha))
+		return PTR_ERR(lcd->vsha);
+
+	lcd->vshd = devm_gpiod_get(&dev->dev, "VSHD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vshd))
+		return PTR_ERR(lcd->vshd);
+
+	lcd->vee = devm_gpiod_get(&dev->dev, "Vee", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vee))
+		return PTR_ERR(lcd->vee);
+
+	lcd->mod = devm_gpiod_get(&dev->dev, "MOD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->mod))
+		return PTR_ERR(lcd->mod);
+
+	lcd->comadj = iio_channel_get(&dev->dev, "comadj");
+	if (IS_ERR(lcd->comadj)) {
+		rc = PTR_ERR(lcd->comadj);
+		if (rc == -ENODEV)
+			rc = -EPROBE_DEFER;
+
+		return rc;
+	}
+
+	locomo_lcd_program_adsync(lcd);
+
+	lcd_dev = devm_lcd_device_register(&dev->dev, "locomo", &dev->dev, lcd,
+			&locomo_lcd_ops);
+	if (IS_ERR(lcd_dev)) {
+		rc = PTR_ERR(lcd_dev);
+		goto err;
+	}
+
+	platform_set_drvdata(dev, lcd_dev);
+
+	lcd_set_power(lcd_dev, FB_BLANK_UNBLANK);
+
+	return 0;
+
+err:
+	locomo_lcd_disable_adsync(lcd);
+	iio_channel_release(lcd->comadj);
+
+	return rc;
+}
+
+static int locomo_lcd_remove(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	iio_channel_release(lcd->comadj);
+
+	return 0;
+}
+
+static void locomo_lcd_shutdown(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+}
+
+static struct platform_driver locomo_lcd_driver = {
+	.driver = {
+		.name	= "locomo-lcd",
+		.pm	= LOCOMOLCD_PM,
+	},
+	.probe	= locomo_lcd_probe,
+	.remove	= locomo_lcd_remove,
+	.shutdown = locomo_lcd_shutdown,
+};
+
+module_platform_driver(locomo_lcd_driver);
+
+MODULE_AUTHOR("John Lenz <lenz-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>");
+MODULE_AUTHOR("Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>");
+MODULE_DESCRIPTION("LoCoMo LCD driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-lcd");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 06/17] video: lcd: add LoCoMo LCD driver
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

LoCoMo has some special handling for TFT screens attached to Collie and
Poodle. Implement that as a separate driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/Kconfig      |  10 ++
 drivers/video/backlight/Makefile     |   1 +
 drivers/video/backlight/locomo_lcd.c | 285 +++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/video/backlight/locomo_lcd.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 6c093e2..b2f995c 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -48,6 +48,16 @@ config LCD_LMS283GF05
 	  SPI driver for Samsung LMS283GF05. This provides basic support
 	  for powering the LCD up/down through a sysfs interface.
 
+config LCD_LOCOMO
+	tristate "Sharp LOCOMO LCD Driver"
+	depends on MFD_LOCOMO
+	select IIO
+	help
+	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
+	  enable the LCD driver.  The panel starts up in power
+	  off state, so you need this driver in order to see any
+	  output.
+
 config LCD_LTV350QV
 	tristate "Samsung LTV350QV LCD Panel"
 	depends on SPI_MASTER
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 2de73d2..686cf1a 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LCD_L4F00242T03)		+= l4f00242t03.o
 obj-$(CONFIG_LCD_LD9040)		+= ld9040.o
 obj-$(CONFIG_LCD_LMS283GF05)		+= lms283gf05.o
 obj-$(CONFIG_LCD_LMS501KF03)		+= lms501kf03.o
+obj-$(CONFIG_LCD_LOCOMO)		+= locomo_lcd.o
 obj-$(CONFIG_LCD_LTV350QV)		+= ltv350qv.o
 obj-$(CONFIG_LCD_PLATFORM)		+= platform_lcd.o
 obj-$(CONFIG_LCD_S6E63M0)		+= s6e63m0.o
diff --git a/drivers/video/backlight/locomo_lcd.c b/drivers/video/backlight/locomo_lcd.c
new file mode 100644
index 0000000..dc316cb
--- /dev/null
+++ b/drivers/video/backlight/locomo_lcd.c
@@ -0,0 +1,285 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/consumer.h>
+#include <linux/lcd.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_lcd {
+	struct regmap *regmap;
+	struct platform_device *dev;
+	struct locomo_lcd_platform_data *data;
+	int power;
+	struct iio_channel *comadj;
+	struct gpio_desc *vsha, *vshd, *vee, *mod;
+};
+
+static void locomo_lcd_on(struct locomo_lcd *lcd)
+{
+	gpiod_set_value(lcd->vsha, 1);
+	usleep_range(2000, 3000);
+
+	gpiod_set_value(lcd->vshd, 1);
+	usleep_range(2000, 3000);
+
+	iio_write_channel_raw(lcd->comadj, lcd->data->comadj);
+	usleep_range(5000, 6000);
+
+	gpiod_set_value(lcd->vee, 1);
+	usleep_range(10000, 11000);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x01);
+
+	/* Set CPSD */
+	regmap_write(lcd->regmap, LOCOMO_CPSD, 6);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x04 | 0x01);
+	usleep_range(10000, 11000);
+
+	gpiod_set_value(lcd->mod, 1);
+}
+
+static void locomo_lcd_off(struct locomo_lcd *lcd)
+{
+	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x06);
+	usleep_range(1000, 2000);
+
+	gpiod_set_value(lcd->vsha, 0);
+	msleep(110);
+
+	gpiod_set_value(lcd->vee, 0);
+	msleep(700);
+
+	iio_write_channel_raw(lcd->comadj, 0);
+	usleep_range(5000, 6000);
+
+	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0);
+	gpiod_set_value(lcd->mod, 0);
+	gpiod_set_value(lcd->vshd, 0);
+}
+
+static void locomo_lcd_program_adsync(struct locomo_lcd *lcd)
+{
+	regmap_write(lcd->regmap, LOCOMO_ASD,
+			6 + 8 + 320 + 30 - 10);
+	regmap_update_bits(lcd->regmap, LOCOMO_ASD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSD,
+			6 + 8 + 320 + 30 - 10 - 128 + 4);
+	regmap_update_bits(lcd->regmap, LOCOMO_HSD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSC, 128 / 8);
+
+	/* XON */
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x80);
+	usleep_range(1000, 1100);
+
+	/* CLK9MEN */
+	regmap_update_bits(lcd->regmap, LOCOMO_TADC,
+		0x10,
+		0x10);
+	usleep_range(100, 200);
+}
+
+static void locomo_lcd_disable_adsync(struct locomo_lcd *lcd)
+{
+	/* ADSTART */
+	regmap_write(lcd->regmap, LOCOMO_ASD, 0x00);
+
+	/* 18MHz clock off*/
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x00);
+}
+
+int locomo_lcd_set_power(struct lcd_device *ldev, int power)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	dev_dbg(&ldev->dev, "LCD power %d (is %d)\n", power, lcd->power);
+
+	if (!power && lcd->power)
+		locomo_lcd_on(lcd);
+
+	if (power && !lcd->power)
+		locomo_lcd_off(lcd);
+
+	lcd->power = power;
+
+	return 0;
+}
+
+static int locomo_lcd_get_power(struct lcd_device *ldev)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	return lcd->power;
+}
+
+static struct lcd_ops locomo_lcd_ops = {
+	.set_power = locomo_lcd_set_power,
+	.get_power = locomo_lcd_get_power,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_lcd_suspend(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	return 0;
+}
+
+static int locomo_lcd_resume(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_program_adsync(lcd);
+
+	if (!lcd->power)
+		locomo_lcd_on(lcd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_lcd_pm, locomo_lcd_suspend, locomo_lcd_resume);
+#define LOCOMOLCD_PM	(&locomo_lcd_pm)
+#else
+#define LOCOMOLCD_PM	NULL
+#endif
+
+static int locomo_lcd_probe(struct platform_device *dev)
+{
+	struct lcd_device *lcd_dev;
+	struct locomo_lcd *lcd;
+	int rc;
+
+	lcd = devm_kmalloc(&dev->dev, sizeof(struct locomo_lcd), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->dev = dev;
+	lcd->power = FB_BLANK_NORMAL;
+
+	lcd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!lcd->regmap)
+		return -ENODEV;
+
+	lcd->data = dev_get_platdata(&dev->dev);
+	if (!lcd->data)
+		return -EINVAL;
+
+	lcd->vsha = devm_gpiod_get(&dev->dev, "VSHA", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vsha))
+		return PTR_ERR(lcd->vsha);
+
+	lcd->vshd = devm_gpiod_get(&dev->dev, "VSHD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vshd))
+		return PTR_ERR(lcd->vshd);
+
+	lcd->vee = devm_gpiod_get(&dev->dev, "Vee", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vee))
+		return PTR_ERR(lcd->vee);
+
+	lcd->mod = devm_gpiod_get(&dev->dev, "MOD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->mod))
+		return PTR_ERR(lcd->mod);
+
+	lcd->comadj = iio_channel_get(&dev->dev, "comadj");
+	if (IS_ERR(lcd->comadj)) {
+		rc = PTR_ERR(lcd->comadj);
+		if (rc = -ENODEV)
+			rc = -EPROBE_DEFER;
+
+		return rc;
+	}
+
+	locomo_lcd_program_adsync(lcd);
+
+	lcd_dev = devm_lcd_device_register(&dev->dev, "locomo", &dev->dev, lcd,
+			&locomo_lcd_ops);
+	if (IS_ERR(lcd_dev)) {
+		rc = PTR_ERR(lcd_dev);
+		goto err;
+	}
+
+	platform_set_drvdata(dev, lcd_dev);
+
+	lcd_set_power(lcd_dev, FB_BLANK_UNBLANK);
+
+	return 0;
+
+err:
+	locomo_lcd_disable_adsync(lcd);
+	iio_channel_release(lcd->comadj);
+
+	return rc;
+}
+
+static int locomo_lcd_remove(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	iio_channel_release(lcd->comadj);
+
+	return 0;
+}
+
+static void locomo_lcd_shutdown(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+}
+
+static struct platform_driver locomo_lcd_driver = {
+	.driver = {
+		.name	= "locomo-lcd",
+		.pm	= LOCOMOLCD_PM,
+	},
+	.probe	= locomo_lcd_probe,
+	.remove	= locomo_lcd_remove,
+	.shutdown = locomo_lcd_shutdown,
+};
+
+module_platform_driver(locomo_lcd_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_AUTHOR("Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("LoCoMo LCD driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-lcd");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 06/17] video: lcd: add LoCoMo LCD driver
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

LoCoMo has some special handling for TFT screens attached to Collie and
Poodle. Implement that as a separate driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/Kconfig      |  10 ++
 drivers/video/backlight/Makefile     |   1 +
 drivers/video/backlight/locomo_lcd.c | 285 +++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/video/backlight/locomo_lcd.c

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 6c093e2..b2f995c 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -48,6 +48,16 @@ config LCD_LMS283GF05
 	  SPI driver for Samsung LMS283GF05. This provides basic support
 	  for powering the LCD up/down through a sysfs interface.
 
+config LCD_LOCOMO
+	tristate "Sharp LOCOMO LCD Driver"
+	depends on MFD_LOCOMO
+	select IIO
+	help
+	  If you have a Sharp Zaurus SL-5500 (Collie) or SL-5600 (Poodle) say y to
+	  enable the LCD driver.  The panel starts up in power
+	  off state, so you need this driver in order to see any
+	  output.
+
 config LCD_LTV350QV
 	tristate "Samsung LTV350QV LCD Panel"
 	depends on SPI_MASTER
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 2de73d2..686cf1a 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_LCD_L4F00242T03)		+= l4f00242t03.o
 obj-$(CONFIG_LCD_LD9040)		+= ld9040.o
 obj-$(CONFIG_LCD_LMS283GF05)		+= lms283gf05.o
 obj-$(CONFIG_LCD_LMS501KF03)		+= lms501kf03.o
+obj-$(CONFIG_LCD_LOCOMO)		+= locomo_lcd.o
 obj-$(CONFIG_LCD_LTV350QV)		+= ltv350qv.o
 obj-$(CONFIG_LCD_PLATFORM)		+= platform_lcd.o
 obj-$(CONFIG_LCD_S6E63M0)		+= s6e63m0.o
diff --git a/drivers/video/backlight/locomo_lcd.c b/drivers/video/backlight/locomo_lcd.c
new file mode 100644
index 0000000..dc316cb
--- /dev/null
+++ b/drivers/video/backlight/locomo_lcd.c
@@ -0,0 +1,285 @@
+/*
+ * Backlight control code for Sharp Zaurus SL-5500
+ *
+ * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
+ * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
+ * GPL v2
+ *
+ * This driver assumes single CPU. That's okay, because collie is
+ * slightly old hardware, and no one is going to retrofit second CPU to
+ * old PDA.
+ */
+
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/gpio/consumer.h>
+#include <linux/iio/consumer.h>
+#include <linux/lcd.h>
+#include <linux/mfd/locomo.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+struct locomo_lcd {
+	struct regmap *regmap;
+	struct platform_device *dev;
+	struct locomo_lcd_platform_data *data;
+	int power;
+	struct iio_channel *comadj;
+	struct gpio_desc *vsha, *vshd, *vee, *mod;
+};
+
+static void locomo_lcd_on(struct locomo_lcd *lcd)
+{
+	gpiod_set_value(lcd->vsha, 1);
+	usleep_range(2000, 3000);
+
+	gpiod_set_value(lcd->vshd, 1);
+	usleep_range(2000, 3000);
+
+	iio_write_channel_raw(lcd->comadj, lcd->data->comadj);
+	usleep_range(5000, 6000);
+
+	gpiod_set_value(lcd->vee, 1);
+	usleep_range(10000, 11000);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x01);
+
+	/* Set CPSD */
+	regmap_write(lcd->regmap, LOCOMO_CPSD, 6);
+
+	/* TFTCRST | CPSOUT=0 | CPSEN */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x04 | 0x01);
+	usleep_range(10000, 11000);
+
+	gpiod_set_value(lcd->mod, 1);
+}
+
+static void locomo_lcd_off(struct locomo_lcd *lcd)
+{
+	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0x06);
+	usleep_range(1000, 2000);
+
+	gpiod_set_value(lcd->vsha, 0);
+	msleep(110);
+
+	gpiod_set_value(lcd->vee, 0);
+	msleep(700);
+
+	iio_write_channel_raw(lcd->comadj, 0);
+	usleep_range(5000, 6000);
+
+	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
+	regmap_write(lcd->regmap, LOCOMO_TC, 0);
+	gpiod_set_value(lcd->mod, 0);
+	gpiod_set_value(lcd->vshd, 0);
+}
+
+static void locomo_lcd_program_adsync(struct locomo_lcd *lcd)
+{
+	regmap_write(lcd->regmap, LOCOMO_ASD,
+			6 + 8 + 320 + 30 - 10);
+	regmap_update_bits(lcd->regmap, LOCOMO_ASD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSD,
+			6 + 8 + 320 + 30 - 10 - 128 + 4);
+	regmap_update_bits(lcd->regmap, LOCOMO_HSD,
+		0x8000,
+		0x8000);
+
+	regmap_write(lcd->regmap, LOCOMO_HSC, 128 / 8);
+
+	/* XON */
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x80);
+	usleep_range(1000, 1100);
+
+	/* CLK9MEN */
+	regmap_update_bits(lcd->regmap, LOCOMO_TADC,
+		0x10,
+		0x10);
+	usleep_range(100, 200);
+}
+
+static void locomo_lcd_disable_adsync(struct locomo_lcd *lcd)
+{
+	/* ADSTART */
+	regmap_write(lcd->regmap, LOCOMO_ASD, 0x00);
+
+	/* 18MHz clock off*/
+	regmap_write(lcd->regmap, LOCOMO_TADC, 0x00);
+}
+
+int locomo_lcd_set_power(struct lcd_device *ldev, int power)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	dev_dbg(&ldev->dev, "LCD power %d (is %d)\n", power, lcd->power);
+
+	if (!power && lcd->power)
+		locomo_lcd_on(lcd);
+
+	if (power && !lcd->power)
+		locomo_lcd_off(lcd);
+
+	lcd->power = power;
+
+	return 0;
+}
+
+static int locomo_lcd_get_power(struct lcd_device *ldev)
+{
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	return lcd->power;
+}
+
+static struct lcd_ops locomo_lcd_ops = {
+	.set_power = locomo_lcd_set_power,
+	.get_power = locomo_lcd_get_power,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_lcd_suspend(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	return 0;
+}
+
+static int locomo_lcd_resume(struct device *dev)
+{
+	struct lcd_device *ldev = dev_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_program_adsync(lcd);
+
+	if (!lcd->power)
+		locomo_lcd_on(lcd);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_lcd_pm, locomo_lcd_suspend, locomo_lcd_resume);
+#define LOCOMOLCD_PM	(&locomo_lcd_pm)
+#else
+#define LOCOMOLCD_PM	NULL
+#endif
+
+static int locomo_lcd_probe(struct platform_device *dev)
+{
+	struct lcd_device *lcd_dev;
+	struct locomo_lcd *lcd;
+	int rc;
+
+	lcd = devm_kmalloc(&dev->dev, sizeof(struct locomo_lcd), GFP_KERNEL);
+	if (!lcd)
+		return -ENOMEM;
+
+	lcd->dev = dev;
+	lcd->power = FB_BLANK_NORMAL;
+
+	lcd->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!lcd->regmap)
+		return -ENODEV;
+
+	lcd->data = dev_get_platdata(&dev->dev);
+	if (!lcd->data)
+		return -EINVAL;
+
+	lcd->vsha = devm_gpiod_get(&dev->dev, "VSHA", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vsha))
+		return PTR_ERR(lcd->vsha);
+
+	lcd->vshd = devm_gpiod_get(&dev->dev, "VSHD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vshd))
+		return PTR_ERR(lcd->vshd);
+
+	lcd->vee = devm_gpiod_get(&dev->dev, "Vee", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->vee))
+		return PTR_ERR(lcd->vee);
+
+	lcd->mod = devm_gpiod_get(&dev->dev, "MOD", GPIOD_OUT_LOW);
+	if (IS_ERR(lcd->mod))
+		return PTR_ERR(lcd->mod);
+
+	lcd->comadj = iio_channel_get(&dev->dev, "comadj");
+	if (IS_ERR(lcd->comadj)) {
+		rc = PTR_ERR(lcd->comadj);
+		if (rc == -ENODEV)
+			rc = -EPROBE_DEFER;
+
+		return rc;
+	}
+
+	locomo_lcd_program_adsync(lcd);
+
+	lcd_dev = devm_lcd_device_register(&dev->dev, "locomo", &dev->dev, lcd,
+			&locomo_lcd_ops);
+	if (IS_ERR(lcd_dev)) {
+		rc = PTR_ERR(lcd_dev);
+		goto err;
+	}
+
+	platform_set_drvdata(dev, lcd_dev);
+
+	lcd_set_power(lcd_dev, FB_BLANK_UNBLANK);
+
+	return 0;
+
+err:
+	locomo_lcd_disable_adsync(lcd);
+	iio_channel_release(lcd->comadj);
+
+	return rc;
+}
+
+static int locomo_lcd_remove(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+
+	iio_channel_release(lcd->comadj);
+
+	return 0;
+}
+
+static void locomo_lcd_shutdown(struct platform_device *dev)
+{
+	struct lcd_device *ldev = platform_get_drvdata(dev);
+	struct locomo_lcd *lcd = lcd_get_data(ldev);
+
+	locomo_lcd_off(lcd);
+
+	locomo_lcd_disable_adsync(lcd);
+}
+
+static struct platform_driver locomo_lcd_driver = {
+	.driver = {
+		.name	= "locomo-lcd",
+		.pm	= LOCOMOLCD_PM,
+	},
+	.probe	= locomo_lcd_probe,
+	.remove	= locomo_lcd_remove,
+	.shutdown = locomo_lcd_shutdown,
+};
+
+module_platform_driver(locomo_lcd_driver);
+
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_AUTHOR("Pavel Machek <pavel@ucw.cz>");
+MODULE_DESCRIPTION("LoCoMo LCD driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-lcd");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Add gpiolib driver for gpio pins placed on the LoCoMo GA.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |  12 ++++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-locomo.c | 170 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/gpio/gpio-locomo.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index caefe80..4542684 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -734,6 +734,18 @@ config GPIO_KEMPLD
 	  This driver can also be built as a module. If so, the module will be
 	  called gpio-kempld.
 
+config GPIO_LOCOMO
+	bool "Sharp LoCoMo GPIO support"
+	depends on MFD_LOCOMO
+	help
+	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
+	  in Sharp Zaurus collie and poodle models.
+
+	  Sat Yes if you have such PDA, say No otherwise.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called gpio-locomo.
+
 config GPIO_LP3943
 	tristate "TI/National Semiconductor LP3943 GPIO expander"
 	depends on MFD_LP3943
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f71bb97..98655ae 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)	+= gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)	+= gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)	+= gpio-ks8695.o
 obj-$(CONFIG_GPIO_INTEL_MID)	+= gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LOCOMO)	+= gpio-locomo.o
 obj-$(CONFIG_GPIO_LOONGSON)	+= gpio-loongson.o
 obj-$(CONFIG_GPIO_LP3943)	+= gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX)	+= gpio-lpc32xx.o
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
new file mode 100644
index 0000000..dd9a1ca
--- /dev/null
+++ b/drivers/gpio/gpio-locomo.c
@@ -0,0 +1,170 @@
+/*
+ * Sharp LoCoMo support for GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_gpio {
+	struct regmap *regmap;
+
+	struct gpio_chip gpio;
+
+	u16 rising_edge;
+	u16 falling_edge;
+
+	unsigned int save_gpo;
+	unsigned int save_gpe;
+};
+
+static int locomo_gpio_get(struct gpio_chip *chip,
+		unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int gpl;
+
+	regmap_read(lg->regmap, LOCOMO_GPL, &gpl);
+
+	return gpl & BIT(offset);
+}
+
+static void locomo_gpio_set(struct gpio_chip *chip,
+		unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+}
+
+static int locomo_gpio_direction_input(struct gpio_chip *chip,
+			unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), BIT(offset));
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), BIT(offset));
+
+	return 0;
+}
+
+static int locomo_gpio_direction_output(struct gpio_chip *chip,
+			unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), 0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_gpio_suspend(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_read(lg->regmap, LOCOMO_GPO, &lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_read(lg->regmap, LOCOMO_GPE, &lg->save_gpe);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+
+	return 0;
+}
+
+static int locomo_gpio_resume(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPE, lg->save_gpe);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_gpio_pm,
+		locomo_gpio_suspend, locomo_gpio_resume);
+#define LOCOMO_GPIO_PM	(&locomo_gpio_pm)
+#else
+#define LOCOMO_GPIO_PM	NULL
+#endif
+
+static int locomo_gpio_probe(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg;
+	int ret;
+	struct locomo_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+	lg = devm_kzalloc(&pdev->dev, sizeof(struct locomo_gpio),
+			GFP_KERNEL);
+	if (!lg)
+		return -ENOMEM;
+
+	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!lg->regmap)
+		return -EINVAL;
+
+	platform_set_drvdata(pdev, lg);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
+
+	lg->gpio.base = pdata ? pdata->gpio_base : -1;
+	lg->gpio.label = "locomo-gpio";
+	lg->gpio.ngpio = 16;
+	lg->gpio.set = locomo_gpio_set;
+	lg->gpio.get = locomo_gpio_get;
+	lg->gpio.direction_input = locomo_gpio_direction_input;
+	lg->gpio.direction_output = locomo_gpio_direction_output;
+
+	ret = gpiochip_add(&lg->gpio);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int locomo_gpio_remove(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&lg->gpio);
+
+	return 0;
+}
+
+static struct platform_driver locomo_gpio_driver = {
+	.probe		= locomo_gpio_probe,
+	.remove		= locomo_gpio_remove,
+	.driver		= {
+		.name	= "locomo-gpio",
+		.pm	= LOCOMO_GPIO_PM,
+	},
+};
+module_platform_driver(locomo_gpio_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo GPIO driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo-gpio");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Add gpiolib driver for gpio pins placed on the LoCoMo GA.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |  12 ++++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-locomo.c | 170 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/gpio/gpio-locomo.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index caefe80..4542684 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -734,6 +734,18 @@ config GPIO_KEMPLD
 	  This driver can also be built as a module. If so, the module will be
 	  called gpio-kempld.
 
+config GPIO_LOCOMO
+	bool "Sharp LoCoMo GPIO support"
+	depends on MFD_LOCOMO
+	help
+	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
+	  in Sharp Zaurus collie and poodle models.
+
+	  Sat Yes if you have such PDA, say No otherwise.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called gpio-locomo.
+
 config GPIO_LP3943
 	tristate "TI/National Semiconductor LP3943 GPIO expander"
 	depends on MFD_LP3943
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f71bb97..98655ae 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)	+= gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)	+= gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)	+= gpio-ks8695.o
 obj-$(CONFIG_GPIO_INTEL_MID)	+= gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LOCOMO)	+= gpio-locomo.o
 obj-$(CONFIG_GPIO_LOONGSON)	+= gpio-loongson.o
 obj-$(CONFIG_GPIO_LP3943)	+= gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX)	+= gpio-lpc32xx.o
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
new file mode 100644
index 0000000..dd9a1ca
--- /dev/null
+++ b/drivers/gpio/gpio-locomo.c
@@ -0,0 +1,170 @@
+/*
+ * Sharp LoCoMo support for GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_gpio {
+	struct regmap *regmap;
+
+	struct gpio_chip gpio;
+
+	u16 rising_edge;
+	u16 falling_edge;
+
+	unsigned int save_gpo;
+	unsigned int save_gpe;
+};
+
+static int locomo_gpio_get(struct gpio_chip *chip,
+		unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int gpl;
+
+	regmap_read(lg->regmap, LOCOMO_GPL, &gpl);
+
+	return gpl & BIT(offset);
+}
+
+static void locomo_gpio_set(struct gpio_chip *chip,
+		unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+}
+
+static int locomo_gpio_direction_input(struct gpio_chip *chip,
+			unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), BIT(offset));
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), BIT(offset));
+
+	return 0;
+}
+
+static int locomo_gpio_direction_output(struct gpio_chip *chip,
+			unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), 0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_gpio_suspend(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_read(lg->regmap, LOCOMO_GPO, &lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_read(lg->regmap, LOCOMO_GPE, &lg->save_gpe);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+
+	return 0;
+}
+
+static int locomo_gpio_resume(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPE, lg->save_gpe);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_gpio_pm,
+		locomo_gpio_suspend, locomo_gpio_resume);
+#define LOCOMO_GPIO_PM	(&locomo_gpio_pm)
+#else
+#define LOCOMO_GPIO_PM	NULL
+#endif
+
+static int locomo_gpio_probe(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg;
+	int ret;
+	struct locomo_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+	lg = devm_kzalloc(&pdev->dev, sizeof(struct locomo_gpio),
+			GFP_KERNEL);
+	if (!lg)
+		return -ENOMEM;
+
+	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!lg->regmap)
+		return -EINVAL;
+
+	platform_set_drvdata(pdev, lg);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
+
+	lg->gpio.base = pdata ? pdata->gpio_base : -1;
+	lg->gpio.label = "locomo-gpio";
+	lg->gpio.ngpio = 16;
+	lg->gpio.set = locomo_gpio_set;
+	lg->gpio.get = locomo_gpio_get;
+	lg->gpio.direction_input = locomo_gpio_direction_input;
+	lg->gpio.direction_output = locomo_gpio_direction_output;
+
+	ret = gpiochip_add(&lg->gpio);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int locomo_gpio_remove(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&lg->gpio);
+
+	return 0;
+}
+
+static struct platform_driver locomo_gpio_driver = {
+	.probe		= locomo_gpio_probe,
+	.remove		= locomo_gpio_remove,
+	.driver		= {
+		.name	= "locomo-gpio",
+		.pm	= LOCOMO_GPIO_PM,
+	},
+};
+module_platform_driver(locomo_gpio_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo GPIO driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo-gpio");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Add gpiolib driver for gpio pins placed on the LoCoMo GA.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |  12 ++++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-locomo.c | 170 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)
 create mode 100644 drivers/gpio/gpio-locomo.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index caefe80..4542684 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -734,6 +734,18 @@ config GPIO_KEMPLD
 	  This driver can also be built as a module. If so, the module will be
 	  called gpio-kempld.
 
+config GPIO_LOCOMO
+	bool "Sharp LoCoMo GPIO support"
+	depends on MFD_LOCOMO
+	help
+	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
+	  in Sharp Zaurus collie and poodle models.
+
+	  Sat Yes if you have such PDA, say No otherwise.
+
+	  This driver can also be built as a module. If so, the module will be
+	  called gpio-locomo.
+
 config GPIO_LP3943
 	tristate "TI/National Semiconductor LP3943 GPIO expander"
 	depends on MFD_LP3943
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f71bb97..98655ae 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL)	+= gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)	+= gpio-kempld.o
 obj-$(CONFIG_ARCH_KS8695)	+= gpio-ks8695.o
 obj-$(CONFIG_GPIO_INTEL_MID)	+= gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LOCOMO)	+= gpio-locomo.o
 obj-$(CONFIG_GPIO_LOONGSON)	+= gpio-loongson.o
 obj-$(CONFIG_GPIO_LP3943)	+= gpio-lp3943.o
 obj-$(CONFIG_ARCH_LPC32XX)	+= gpio-lpc32xx.o
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
new file mode 100644
index 0000000..dd9a1ca
--- /dev/null
+++ b/drivers/gpio/gpio-locomo.c
@@ -0,0 +1,170 @@
+/*
+ * Sharp LoCoMo support for GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains all generic LoCoMo support.
+ *
+ * All initialization functions provided here are intended to be called
+ * from machine specific code with proper arguments when required.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/locomo.h>
+
+struct locomo_gpio {
+	struct regmap *regmap;
+
+	struct gpio_chip gpio;
+
+	u16 rising_edge;
+	u16 falling_edge;
+
+	unsigned int save_gpo;
+	unsigned int save_gpe;
+};
+
+static int locomo_gpio_get(struct gpio_chip *chip,
+		unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int gpl;
+
+	regmap_read(lg->regmap, LOCOMO_GPL, &gpl);
+
+	return gpl & BIT(offset);
+}
+
+static void locomo_gpio_set(struct gpio_chip *chip,
+		unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+}
+
+static int locomo_gpio_direction_input(struct gpio_chip *chip,
+			unsigned offset)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), BIT(offset));
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), BIT(offset));
+
+	return 0;
+}
+
+static int locomo_gpio_direction_output(struct gpio_chip *chip,
+			unsigned offset, int value)
+{
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GPO,
+			BIT(offset),
+			value ? BIT(offset) : 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPD, BIT(offset), 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GPE, BIT(offset), 0);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_gpio_suspend(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_read(lg->regmap, LOCOMO_GPO, &lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_read(lg->regmap, LOCOMO_GPE, &lg->save_gpe);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+
+	return 0;
+}
+
+static int locomo_gpio_resume(struct device *dev)
+{
+	struct locomo_gpio *lg = dev_get_drvdata(dev);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, lg->save_gpo);
+	regmap_write(lg->regmap, LOCOMO_GPE, lg->save_gpe);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_gpio_pm,
+		locomo_gpio_suspend, locomo_gpio_resume);
+#define LOCOMO_GPIO_PM	(&locomo_gpio_pm)
+#else
+#define LOCOMO_GPIO_PM	NULL
+#endif
+
+static int locomo_gpio_probe(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg;
+	int ret;
+	struct locomo_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+
+	lg = devm_kzalloc(&pdev->dev, sizeof(struct locomo_gpio),
+			GFP_KERNEL);
+	if (!lg)
+		return -ENOMEM;
+
+	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!lg->regmap)
+		return -EINVAL;
+
+	platform_set_drvdata(pdev, lg);
+
+	regmap_write(lg->regmap, LOCOMO_GPO, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPE, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
+	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
+
+	lg->gpio.base = pdata ? pdata->gpio_base : -1;
+	lg->gpio.label = "locomo-gpio";
+	lg->gpio.ngpio = 16;
+	lg->gpio.set = locomo_gpio_set;
+	lg->gpio.get = locomo_gpio_get;
+	lg->gpio.direction_input = locomo_gpio_direction_input;
+	lg->gpio.direction_output = locomo_gpio_direction_output;
+
+	ret = gpiochip_add(&lg->gpio);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int locomo_gpio_remove(struct platform_device *pdev)
+{
+	struct locomo_gpio *lg = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&lg->gpio);
+
+	return 0;
+}
+
+static struct platform_driver locomo_gpio_driver = {
+	.probe		= locomo_gpio_probe,
+	.remove		= locomo_gpio_remove,
+	.driver		= {
+		.name	= "locomo-gpio",
+		.pm	= LOCOMO_GPIO_PM,
+	},
+};
+module_platform_driver(locomo_gpio_driver);
+
+MODULE_DESCRIPTION("Sharp LoCoMo GPIO driver");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
+MODULE_ALIAS("platform:locomo-gpio");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
that was there in old locomo driver, got 'cleaned up' during old driver
IRQ cascading cleanup and is now reimplemented. It is expected that
SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |   1 +
 drivers/gpio/gpio-locomo.c | 120 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4542684..6b77614 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -737,6 +737,7 @@ config GPIO_KEMPLD
 config GPIO_LOCOMO
 	bool "Sharp LoCoMo GPIO support"
 	depends on MFD_LOCOMO
+	select GPIOLIB_IRQCHIP
 	help
 	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
 	  in Sharp Zaurus collie and poodle models.
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
index dd9a1ca..d8e5880 100644
--- a/drivers/gpio/gpio-locomo.c
+++ b/drivers/gpio/gpio-locomo.c
@@ -16,13 +16,15 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/regmap.h>
 #include <linux/mfd/locomo.h>
 
 struct locomo_gpio {
 	struct regmap *regmap;
+	int irq;
 
 	struct gpio_chip gpio;
 
@@ -79,6 +81,99 @@ static int locomo_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
+static void
+locomo_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_get_handler_data(irq);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int gir;
+	unsigned int gpd;
+	unsigned int req;
+
+	chained_irq_enter(irqchip, desc);
+
+	while (1) {
+		regmap_read(lg->regmap, LOCOMO_GIR, &gir);
+		regmap_read(lg->regmap, LOCOMO_GPD, &gpd);
+		req = gir & gpd;
+
+		if (!req)
+			break;
+
+		generic_handle_irq(irq_find_mapping(lg->gpio.irqdomain,
+					ffs(req) - 1));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static void locomo_gpio_ack_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, mask);
+	regmap_update_bits(lg->regmap, LOCOMO_GIS, mask, 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, 0);
+}
+
+static void locomo_gpio_mask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, 0);
+}
+
+static void locomo_gpio_unmask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, mask);
+}
+
+static int locomo_gpio_type_irq(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask;
+
+	mask = BIT(d->hwirq);
+
+	if (type == IRQ_TYPE_PROBE) {
+		if ((lg->rising_edge | lg->falling_edge) & mask)
+			return 0;
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		lg->rising_edge |= mask;
+	else
+		lg->rising_edge &= ~mask;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		lg->falling_edge |= mask;
+	else
+		lg->falling_edge &= ~mask;
+
+	regmap_write(lg->regmap, LOCOMO_GRIE, lg->rising_edge);
+	regmap_write(lg->regmap, LOCOMO_GFIE, lg->falling_edge);
+
+	return 0;
+}
+
+static struct irq_chip locomo_gpio_irq_chip = {
+	.name		= "LOCOMO-g",
+	.irq_ack	= locomo_gpio_ack_irq,
+	.irq_mask	= locomo_gpio_mask_irq,
+	.irq_unmask	= locomo_gpio_unmask_irq,
+	.irq_set_type	= locomo_gpio_type_irq,
+};
+
 #ifdef CONFIG_PM_SLEEP
 static int locomo_gpio_suspend(struct device *dev)
 {
@@ -119,6 +214,10 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (!lg)
 		return -ENOMEM;
 
+	lg->irq = platform_get_irq(pdev, 0);
+	if (lg->irq < 0)
+		return -ENXIO;
+
 	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 	if (!lg->regmap)
 		return -EINVAL;
@@ -130,6 +229,7 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
 	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
 
+	lg->gpio.dev = &pdev->dev;
 	lg->gpio.base = pdata ? pdata->gpio_base : -1;
 	lg->gpio.label = "locomo-gpio";
 	lg->gpio.ngpio = 16;
@@ -142,7 +242,22 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = gpiochip_irqchip_add(&lg->gpio, &locomo_gpio_irq_chip, 0,
+				   handle_level_irq, IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add irq chip\n");
+		goto err_rm_gpiochip;
+	}
+
+	gpiochip_set_chained_irqchip(&lg->gpio, &locomo_gpio_irq_chip, lg->irq,
+				     locomo_gpio_irq_handler);
+
 	return 0;
+
+err_rm_gpiochip:
+	gpiochip_remove(&lg->gpio);
+
+	return ret;
 }
 
 static int locomo_gpio_remove(struct platform_device *pdev)
@@ -151,6 +266,9 @@ static int locomo_gpio_remove(struct platform_device *pdev)
 
 	gpiochip_remove(&lg->gpio);
 
+	irq_set_chained_handler(lg->irq, NULL);
+	irq_set_handler_data(lg->irq, NULL);
+
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
that was there in old locomo driver, got 'cleaned up' during old driver
IRQ cascading cleanup and is now reimplemented. It is expected that
SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |   1 +
 drivers/gpio/gpio-locomo.c | 120 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4542684..6b77614 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -737,6 +737,7 @@ config GPIO_KEMPLD
 config GPIO_LOCOMO
 	bool "Sharp LoCoMo GPIO support"
 	depends on MFD_LOCOMO
+	select GPIOLIB_IRQCHIP
 	help
 	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
 	  in Sharp Zaurus collie and poodle models.
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
index dd9a1ca..d8e5880 100644
--- a/drivers/gpio/gpio-locomo.c
+++ b/drivers/gpio/gpio-locomo.c
@@ -16,13 +16,15 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/regmap.h>
 #include <linux/mfd/locomo.h>
 
 struct locomo_gpio {
 	struct regmap *regmap;
+	int irq;
 
 	struct gpio_chip gpio;
 
@@ -79,6 +81,99 @@ static int locomo_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
+static void
+locomo_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_get_handler_data(irq);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int gir;
+	unsigned int gpd;
+	unsigned int req;
+
+	chained_irq_enter(irqchip, desc);
+
+	while (1) {
+		regmap_read(lg->regmap, LOCOMO_GIR, &gir);
+		regmap_read(lg->regmap, LOCOMO_GPD, &gpd);
+		req = gir & gpd;
+
+		if (!req)
+			break;
+
+		generic_handle_irq(irq_find_mapping(lg->gpio.irqdomain,
+					ffs(req) - 1));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static void locomo_gpio_ack_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, mask);
+	regmap_update_bits(lg->regmap, LOCOMO_GIS, mask, 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, 0);
+}
+
+static void locomo_gpio_mask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, 0);
+}
+
+static void locomo_gpio_unmask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, mask);
+}
+
+static int locomo_gpio_type_irq(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask;
+
+	mask = BIT(d->hwirq);
+
+	if (type = IRQ_TYPE_PROBE) {
+		if ((lg->rising_edge | lg->falling_edge) & mask)
+			return 0;
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		lg->rising_edge |= mask;
+	else
+		lg->rising_edge &= ~mask;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		lg->falling_edge |= mask;
+	else
+		lg->falling_edge &= ~mask;
+
+	regmap_write(lg->regmap, LOCOMO_GRIE, lg->rising_edge);
+	regmap_write(lg->regmap, LOCOMO_GFIE, lg->falling_edge);
+
+	return 0;
+}
+
+static struct irq_chip locomo_gpio_irq_chip = {
+	.name		= "LOCOMO-g",
+	.irq_ack	= locomo_gpio_ack_irq,
+	.irq_mask	= locomo_gpio_mask_irq,
+	.irq_unmask	= locomo_gpio_unmask_irq,
+	.irq_set_type	= locomo_gpio_type_irq,
+};
+
 #ifdef CONFIG_PM_SLEEP
 static int locomo_gpio_suspend(struct device *dev)
 {
@@ -119,6 +214,10 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (!lg)
 		return -ENOMEM;
 
+	lg->irq = platform_get_irq(pdev, 0);
+	if (lg->irq < 0)
+		return -ENXIO;
+
 	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 	if (!lg->regmap)
 		return -EINVAL;
@@ -130,6 +229,7 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
 	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
 
+	lg->gpio.dev = &pdev->dev;
 	lg->gpio.base = pdata ? pdata->gpio_base : -1;
 	lg->gpio.label = "locomo-gpio";
 	lg->gpio.ngpio = 16;
@@ -142,7 +242,22 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = gpiochip_irqchip_add(&lg->gpio, &locomo_gpio_irq_chip, 0,
+				   handle_level_irq, IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add irq chip\n");
+		goto err_rm_gpiochip;
+	}
+
+	gpiochip_set_chained_irqchip(&lg->gpio, &locomo_gpio_irq_chip, lg->irq,
+				     locomo_gpio_irq_handler);
+
 	return 0;
+
+err_rm_gpiochip:
+	gpiochip_remove(&lg->gpio);
+
+	return ret;
 }
 
 static int locomo_gpio_remove(struct platform_device *pdev)
@@ -151,6 +266,9 @@ static int locomo_gpio_remove(struct platform_device *pdev)
 
 	gpiochip_remove(&lg->gpio);
 
+	irq_set_chained_handler(lg->irq, NULL);
+	irq_set_handler_data(lg->irq, NULL);
+
 	return 0;
 }
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
that was there in old locomo driver, got 'cleaned up' during old driver
IRQ cascading cleanup and is now reimplemented. It is expected that
SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/gpio/Kconfig       |   1 +
 drivers/gpio/gpio-locomo.c | 120 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 4542684..6b77614 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -737,6 +737,7 @@ config GPIO_KEMPLD
 config GPIO_LOCOMO
 	bool "Sharp LoCoMo GPIO support"
 	depends on MFD_LOCOMO
+	select GPIOLIB_IRQCHIP
 	help
 	  Select this to support GPIO pins on Sharp LoCoMo Grid Array found
 	  in Sharp Zaurus collie and poodle models.
diff --git a/drivers/gpio/gpio-locomo.c b/drivers/gpio/gpio-locomo.c
index dd9a1ca..d8e5880 100644
--- a/drivers/gpio/gpio-locomo.c
+++ b/drivers/gpio/gpio-locomo.c
@@ -16,13 +16,15 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/io.h>
+#include <linux/irq.h>
 #include <linux/regmap.h>
 #include <linux/mfd/locomo.h>
 
 struct locomo_gpio {
 	struct regmap *regmap;
+	int irq;
 
 	struct gpio_chip gpio;
 
@@ -79,6 +81,99 @@ static int locomo_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
+static void
+locomo_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct gpio_chip *chip = irq_get_handler_data(irq);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	struct irq_chip *irqchip = irq_desc_get_chip(desc);
+	unsigned int gir;
+	unsigned int gpd;
+	unsigned int req;
+
+	chained_irq_enter(irqchip, desc);
+
+	while (1) {
+		regmap_read(lg->regmap, LOCOMO_GIR, &gir);
+		regmap_read(lg->regmap, LOCOMO_GPD, &gpd);
+		req = gir & gpd;
+
+		if (!req)
+			break;
+
+		generic_handle_irq(irq_find_mapping(lg->gpio.irqdomain,
+					ffs(req) - 1));
+	}
+
+	chained_irq_exit(irqchip, desc);
+}
+
+static void locomo_gpio_ack_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, mask);
+	regmap_update_bits(lg->regmap, LOCOMO_GIS, mask, 0);
+	regmap_update_bits(lg->regmap, LOCOMO_GWE, mask, 0);
+}
+
+static void locomo_gpio_mask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, 0);
+}
+
+static void locomo_gpio_unmask_irq(struct irq_data *d)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask = BIT(d->hwirq);
+
+	regmap_update_bits(lg->regmap, LOCOMO_GIE, mask, mask);
+}
+
+static int locomo_gpio_type_irq(struct irq_data *d, unsigned int type)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(d);
+	struct locomo_gpio *lg = container_of(chip, struct locomo_gpio, gpio);
+	unsigned int mask;
+
+	mask = BIT(d->hwirq);
+
+	if (type == IRQ_TYPE_PROBE) {
+		if ((lg->rising_edge | lg->falling_edge) & mask)
+			return 0;
+		type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	}
+
+	if (type & IRQ_TYPE_EDGE_RISING)
+		lg->rising_edge |= mask;
+	else
+		lg->rising_edge &= ~mask;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		lg->falling_edge |= mask;
+	else
+		lg->falling_edge &= ~mask;
+
+	regmap_write(lg->regmap, LOCOMO_GRIE, lg->rising_edge);
+	regmap_write(lg->regmap, LOCOMO_GFIE, lg->falling_edge);
+
+	return 0;
+}
+
+static struct irq_chip locomo_gpio_irq_chip = {
+	.name		= "LOCOMO-g",
+	.irq_ack	= locomo_gpio_ack_irq,
+	.irq_mask	= locomo_gpio_mask_irq,
+	.irq_unmask	= locomo_gpio_unmask_irq,
+	.irq_set_type	= locomo_gpio_type_irq,
+};
+
 #ifdef CONFIG_PM_SLEEP
 static int locomo_gpio_suspend(struct device *dev)
 {
@@ -119,6 +214,10 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (!lg)
 		return -ENOMEM;
 
+	lg->irq = platform_get_irq(pdev, 0);
+	if (lg->irq < 0)
+		return -ENXIO;
+
 	lg->regmap = dev_get_regmap(pdev->dev.parent, NULL);
 	if (!lg->regmap)
 		return -EINVAL;
@@ -130,6 +229,7 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	regmap_write(lg->regmap, LOCOMO_GPD, 0x00);
 	regmap_write(lg->regmap, LOCOMO_GIE, 0x00);
 
+	lg->gpio.dev = &pdev->dev;
 	lg->gpio.base = pdata ? pdata->gpio_base : -1;
 	lg->gpio.label = "locomo-gpio";
 	lg->gpio.ngpio = 16;
@@ -142,7 +242,22 @@ static int locomo_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
+	ret = gpiochip_irqchip_add(&lg->gpio, &locomo_gpio_irq_chip, 0,
+				   handle_level_irq, IRQ_TYPE_NONE);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to add irq chip\n");
+		goto err_rm_gpiochip;
+	}
+
+	gpiochip_set_chained_irqchip(&lg->gpio, &locomo_gpio_irq_chip, lg->irq,
+				     locomo_gpio_irq_handler);
+
 	return 0;
+
+err_rm_gpiochip:
+	gpiochip_remove(&lg->gpio);
+
+	return ret;
 }
 
 static int locomo_gpio_remove(struct platform_device *pdev)
@@ -151,6 +266,9 @@ static int locomo_gpio_remove(struct platform_device *pdev)
 
 	gpiochip_remove(&lg->gpio);
 
+	irq_set_chained_handler(lg->irq, NULL);
+	irq_set_handler_data(lg->irq, NULL);
+
 	return 0;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 09/17] spi: add locomo SPI driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

LoCoMo chip has a built-in simple SPI controller. On Sharp SL-5500 PDDAs
it is connected to external MMC slot.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/spi/Kconfig      |  10 ++
 drivers/spi/Makefile     |   1 +
 drivers/spi/spi-locomo.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+)
 create mode 100644 drivers/spi/spi-locomo.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 198f96b..c9e3176 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -258,6 +258,16 @@ config SPI_LM70_LLP
 	  which interfaces to an LM70 temperature sensor using
 	  a parallel port.
 
+config SPI_LOCOMO
+	tristate "Locomo SPI master"
+	depends on MFD_LOCOMO
+	help
+	  This enables using the SPI controller as present in the LoCoMo
+	  chips. It is probably only useful on the Sharp SL-5x00 PDA family.
+
+	  On SL-5500 and SL-5000 devices this controller is used for
+	  MMC/SD cards.
+
 config SPI_MPC52xx
 	tristate "Freescale MPC52xx SPI (non-PSC) controller support"
 	depends on PPC_MPC52xx
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d8cbf65..623c463 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o
 obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o
 obj-$(CONFIG_SPI_IMX)			+= spi-imx.o
 obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o
+obj-$(CONFIG_SPI_LOCOMO)		+= spi-locomo.o
 obj-$(CONFIG_SPI_MESON_SPIFC)		+= spi-meson-spifc.o
 obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
diff --git a/drivers/spi/spi-locomo.c b/drivers/spi/spi-locomo.c
new file mode 100644
index 0000000..71b36fd
--- /dev/null
+++ b/drivers/spi/spi-locomo.c
@@ -0,0 +1,363 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/locomo.h>
+
+struct locomospi_dev {
+	struct regmap *regmap;
+
+	int clock_base;
+	int clock_div;
+	unsigned nsecs;
+
+	unsigned int save_ct;
+	unsigned int save_md;
+};
+
+static int locomospi_reg_open(struct locomospi_dev *spidev)
+{
+	regmap_write(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_MSB1ST | LOCOMO_SPIMD_DOSTAT |
+			LOCOMO_SPIMD_RCPOL | LOCOMO_SPIMD_TCPOL |
+			(spidev->clock_base << 3) | spidev->clock_div);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			LOCOMO_SPIMD_XON);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN);
+
+	usleep_range(200, 300);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS, 0);
+
+	return 0;
+}
+
+static int locomospi_reg_release(struct locomospi_dev *spidev)
+{
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XON, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	return 0;
+}
+
+
+static void locomospi_chipselect(struct spi_device *spi, bool enable)
+{
+	struct locomospi_dev *spidev;
+
+	dev_dbg(&spi->dev, "SPI cs: %s\n", enable ? "enable" : "disable");
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS,
+			enable ? LOCOMO_SPICT_CS : 0);
+}
+
+static u32 locomospi_txrx_word(struct spi_device *spi,
+		unsigned nsecs,
+		u32 word)
+{
+	struct locomospi_dev *spidev;
+	int wait;
+	int j;
+	unsigned int rx;
+	unsigned int r;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	if (spidev->clock_div == DIV_64)
+		wait = 0x10000;
+	else
+		wait = 8;
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFW)
+			break;
+	}
+	if (j == wait)
+		dev_err(&spi->dev, "rfw timeout\n");
+
+	regmap_write(spidev->regmap, LOCOMO_SPITD, word);
+	ndelay(nsecs);
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFR)
+			break;
+	}
+	if (j == wait)
+		dev_err(&spi->dev, "rfr timeout\n");
+
+	regmap_read(spidev->regmap, LOCOMO_SPIRD, &rx);
+	ndelay(nsecs);
+
+	dev_dbg(&spi->dev, "SPI txrx: %02x/%02x\n", word, rx);
+
+	return rx;
+}
+
+static void locomo_spi_set_speed(struct locomospi_dev *spidev, u32 hz)
+{
+	spidev->nsecs = (1000000000/2) / hz;
+
+	if (hz >= 24576000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 22579200) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 18432000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 12288000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 11289600) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 9216000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 6144000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 5644800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 4608000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 3072000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2822400) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2304000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 384000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_64;
+	} else if (hz >= 352800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_64;
+	} else {		/* set to 288 Khz */
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_64;
+	}
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			spidev->clock_div | (spidev->clock_base << 3) |
+				LOCOMO_SPIMD_XEN);
+
+	usleep_range(300, 400);
+}
+
+static int locomo_spi_setup_transfer(struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev;
+	u32 hz = 0;
+
+	if (t)
+		hz = t->speed_hz;
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			hz ? LOCOMO_SPIMD_XON : 0);
+
+	if (hz != 0)
+		locomo_spi_set_speed(spidev, hz);
+
+	return 0;
+}
+
+static int locomospi_transfer_one(struct spi_master *master,
+		struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev = spi_master_get_devdata(spi->master);
+	int rc;
+	unsigned count;
+	const u8 *tx = t->tx_buf;
+	u8 *rx = t->rx_buf;
+
+	if (!tx && !rx && t->len)
+		return -EINVAL;
+
+	rc = locomo_spi_setup_transfer(spi, t);
+	if (rc < 0)
+		return rc;
+
+	if (!t->len)
+		return 0;
+
+	for (count = t->len; likely(count > 0); count--) {
+		u8 word = 0;
+
+		if (tx)
+			word = *tx++;
+		word = locomospi_txrx_word(spi, spidev->nsecs, word);
+
+		if (rx)
+			*rx++ = word;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_spi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	/* Stop the queue running */
+	ret = spi_master_suspend(master);
+	if (ret) {
+		dev_warn(dev, "cannot suspend master\n");
+		return ret;
+	}
+
+	regmap_read(spidev->regmap, LOCOMO_SPICT, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_read(spidev->regmap, LOCOMO_SPIMD, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, 0x3c14);
+
+
+	return 0;
+}
+
+static int locomo_spi_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, spidev->save_md);
+
+	/* Start the queue running */
+	ret = spi_master_resume(master);
+	if (ret)
+		dev_err(dev, "problem starting queue (%d)\n", ret);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_spi_pm_ops,
+		locomo_spi_suspend, locomo_spi_resume);
+
+#define LOCOMO_SPI_PM_OPS	(&locomo_spi_pm_ops)
+#else
+#define LOCOMO_SPI_PM_OPS	NULL
+#endif
+
+static int locomo_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct locomospi_dev *spidev;
+	int ret = -ENODEV;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct locomospi_dev));
+	if (!master)
+		return -ENOMEM;
+
+	master->bus_num = 0;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 8);
+	master->max_speed_hz = 24576000;
+	master->num_chipselect = 1;
+	master->set_cs = locomospi_chipselect;
+	master->transfer_one = locomospi_transfer_one;
+
+	spidev = spi_master_get_devdata(master);
+
+	spidev->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!spidev->regmap)
+		goto out_put;
+
+	spidev->clock_div = DIV_64;
+	spidev->clock_base = CLOCK_18MHZ;
+
+	platform_set_drvdata(pdev, master);
+
+	ret = locomospi_reg_open(spidev);
+	if (ret < 0)
+		goto out_put;
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
+		goto out_put;
+	}
+
+	return 0;
+
+out_put:
+	spi_master_put(master);
+	return ret;
+}
+
+static int locomo_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+
+	return locomospi_reg_release(spidev);
+}
+
+static struct platform_driver locomo_spi_driver = {
+	.probe = locomo_spi_probe,
+	.remove = locomo_spi_remove,
+	.driver = {
+		.name = "locomo-spi",
+		.pm = LOCOMO_SPI_PM_OPS,
+	},
+};
+module_platform_driver(locomo_spi_driver);
+
+MODULE_AUTHOR("Thomas Kunze thommy@tabao.de");
+MODULE_DESCRIPTION("LoCoMo SPI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-spi");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 09/17] spi: add locomo SPI driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

LoCoMo chip has a built-in simple SPI controller. On Sharp SL-5500 PDDAs
it is connected to external MMC slot.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/spi/Kconfig      |  10 ++
 drivers/spi/Makefile     |   1 +
 drivers/spi/spi-locomo.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+)
 create mode 100644 drivers/spi/spi-locomo.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 198f96b..c9e3176 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -258,6 +258,16 @@ config SPI_LM70_LLP
 	  which interfaces to an LM70 temperature sensor using
 	  a parallel port.
 
+config SPI_LOCOMO
+	tristate "Locomo SPI master"
+	depends on MFD_LOCOMO
+	help
+	  This enables using the SPI controller as present in the LoCoMo
+	  chips. It is probably only useful on the Sharp SL-5x00 PDA family.
+
+	  On SL-5500 and SL-5000 devices this controller is used for
+	  MMC/SD cards.
+
 config SPI_MPC52xx
 	tristate "Freescale MPC52xx SPI (non-PSC) controller support"
 	depends on PPC_MPC52xx
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d8cbf65..623c463 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o
 obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o
 obj-$(CONFIG_SPI_IMX)			+= spi-imx.o
 obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o
+obj-$(CONFIG_SPI_LOCOMO)		+= spi-locomo.o
 obj-$(CONFIG_SPI_MESON_SPIFC)		+= spi-meson-spifc.o
 obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
diff --git a/drivers/spi/spi-locomo.c b/drivers/spi/spi-locomo.c
new file mode 100644
index 0000000..71b36fd
--- /dev/null
+++ b/drivers/spi/spi-locomo.c
@@ -0,0 +1,363 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/locomo.h>
+
+struct locomospi_dev {
+	struct regmap *regmap;
+
+	int clock_base;
+	int clock_div;
+	unsigned nsecs;
+
+	unsigned int save_ct;
+	unsigned int save_md;
+};
+
+static int locomospi_reg_open(struct locomospi_dev *spidev)
+{
+	regmap_write(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_MSB1ST | LOCOMO_SPIMD_DOSTAT |
+			LOCOMO_SPIMD_RCPOL | LOCOMO_SPIMD_TCPOL |
+			(spidev->clock_base << 3) | spidev->clock_div);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			LOCOMO_SPIMD_XON);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN);
+
+	usleep_range(200, 300);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS, 0);
+
+	return 0;
+}
+
+static int locomospi_reg_release(struct locomospi_dev *spidev)
+{
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XON, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	return 0;
+}
+
+
+static void locomospi_chipselect(struct spi_device *spi, bool enable)
+{
+	struct locomospi_dev *spidev;
+
+	dev_dbg(&spi->dev, "SPI cs: %s\n", enable ? "enable" : "disable");
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS,
+			enable ? LOCOMO_SPICT_CS : 0);
+}
+
+static u32 locomospi_txrx_word(struct spi_device *spi,
+		unsigned nsecs,
+		u32 word)
+{
+	struct locomospi_dev *spidev;
+	int wait;
+	int j;
+	unsigned int rx;
+	unsigned int r;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	if (spidev->clock_div = DIV_64)
+		wait = 0x10000;
+	else
+		wait = 8;
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFW)
+			break;
+	}
+	if (j = wait)
+		dev_err(&spi->dev, "rfw timeout\n");
+
+	regmap_write(spidev->regmap, LOCOMO_SPITD, word);
+	ndelay(nsecs);
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFR)
+			break;
+	}
+	if (j = wait)
+		dev_err(&spi->dev, "rfr timeout\n");
+
+	regmap_read(spidev->regmap, LOCOMO_SPIRD, &rx);
+	ndelay(nsecs);
+
+	dev_dbg(&spi->dev, "SPI txrx: %02x/%02x\n", word, rx);
+
+	return rx;
+}
+
+static void locomo_spi_set_speed(struct locomospi_dev *spidev, u32 hz)
+{
+	spidev->nsecs = (1000000000/2) / hz;
+
+	if (hz >= 24576000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 22579200) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 18432000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 12288000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 11289600) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 9216000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 6144000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 5644800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 4608000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 3072000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2822400) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2304000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 384000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_64;
+	} else if (hz >= 352800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_64;
+	} else {		/* set to 288 Khz */
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_64;
+	}
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			spidev->clock_div | (spidev->clock_base << 3) |
+				LOCOMO_SPIMD_XEN);
+
+	usleep_range(300, 400);
+}
+
+static int locomo_spi_setup_transfer(struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev;
+	u32 hz = 0;
+
+	if (t)
+		hz = t->speed_hz;
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			hz ? LOCOMO_SPIMD_XON : 0);
+
+	if (hz != 0)
+		locomo_spi_set_speed(spidev, hz);
+
+	return 0;
+}
+
+static int locomospi_transfer_one(struct spi_master *master,
+		struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev = spi_master_get_devdata(spi->master);
+	int rc;
+	unsigned count;
+	const u8 *tx = t->tx_buf;
+	u8 *rx = t->rx_buf;
+
+	if (!tx && !rx && t->len)
+		return -EINVAL;
+
+	rc = locomo_spi_setup_transfer(spi, t);
+	if (rc < 0)
+		return rc;
+
+	if (!t->len)
+		return 0;
+
+	for (count = t->len; likely(count > 0); count--) {
+		u8 word = 0;
+
+		if (tx)
+			word = *tx++;
+		word = locomospi_txrx_word(spi, spidev->nsecs, word);
+
+		if (rx)
+			*rx++ = word;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_spi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	/* Stop the queue running */
+	ret = spi_master_suspend(master);
+	if (ret) {
+		dev_warn(dev, "cannot suspend master\n");
+		return ret;
+	}
+
+	regmap_read(spidev->regmap, LOCOMO_SPICT, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_read(spidev->regmap, LOCOMO_SPIMD, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, 0x3c14);
+
+
+	return 0;
+}
+
+static int locomo_spi_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, spidev->save_md);
+
+	/* Start the queue running */
+	ret = spi_master_resume(master);
+	if (ret)
+		dev_err(dev, "problem starting queue (%d)\n", ret);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_spi_pm_ops,
+		locomo_spi_suspend, locomo_spi_resume);
+
+#define LOCOMO_SPI_PM_OPS	(&locomo_spi_pm_ops)
+#else
+#define LOCOMO_SPI_PM_OPS	NULL
+#endif
+
+static int locomo_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct locomospi_dev *spidev;
+	int ret = -ENODEV;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct locomospi_dev));
+	if (!master)
+		return -ENOMEM;
+
+	master->bus_num = 0;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 8);
+	master->max_speed_hz = 24576000;
+	master->num_chipselect = 1;
+	master->set_cs = locomospi_chipselect;
+	master->transfer_one = locomospi_transfer_one;
+
+	spidev = spi_master_get_devdata(master);
+
+	spidev->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!spidev->regmap)
+		goto out_put;
+
+	spidev->clock_div = DIV_64;
+	spidev->clock_base = CLOCK_18MHZ;
+
+	platform_set_drvdata(pdev, master);
+
+	ret = locomospi_reg_open(spidev);
+	if (ret < 0)
+		goto out_put;
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
+		goto out_put;
+	}
+
+	return 0;
+
+out_put:
+	spi_master_put(master);
+	return ret;
+}
+
+static int locomo_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+
+	return locomospi_reg_release(spidev);
+}
+
+static struct platform_driver locomo_spi_driver = {
+	.probe = locomo_spi_probe,
+	.remove = locomo_spi_remove,
+	.driver = {
+		.name = "locomo-spi",
+		.pm = LOCOMO_SPI_PM_OPS,
+	},
+};
+module_platform_driver(locomo_spi_driver);
+
+MODULE_AUTHOR("Thomas Kunze thommy@tabao.de");
+MODULE_DESCRIPTION("LoCoMo SPI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-spi");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 09/17] spi: add locomo SPI driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

LoCoMo chip has a built-in simple SPI controller. On Sharp SL-5500 PDDAs
it is connected to external MMC slot.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/spi/Kconfig      |  10 ++
 drivers/spi/Makefile     |   1 +
 drivers/spi/spi-locomo.c | 363 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 374 insertions(+)
 create mode 100644 drivers/spi/spi-locomo.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 198f96b..c9e3176 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -258,6 +258,16 @@ config SPI_LM70_LLP
 	  which interfaces to an LM70 temperature sensor using
 	  a parallel port.
 
+config SPI_LOCOMO
+	tristate "Locomo SPI master"
+	depends on MFD_LOCOMO
+	help
+	  This enables using the SPI controller as present in the LoCoMo
+	  chips. It is probably only useful on the Sharp SL-5x00 PDA family.
+
+	  On SL-5500 and SL-5000 devices this controller is used for
+	  MMC/SD cards.
+
 config SPI_MPC52xx
 	tristate "Freescale MPC52xx SPI (non-PSC) controller support"
 	depends on PPC_MPC52xx
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d8cbf65..623c463 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o
 obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o
 obj-$(CONFIG_SPI_IMX)			+= spi-imx.o
 obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o
+obj-$(CONFIG_SPI_LOCOMO)		+= spi-locomo.o
 obj-$(CONFIG_SPI_MESON_SPIFC)		+= spi-meson-spifc.o
 obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
diff --git a/drivers/spi/spi-locomo.c b/drivers/spi/spi-locomo.c
new file mode 100644
index 0000000..71b36fd
--- /dev/null
+++ b/drivers/spi/spi-locomo.c
@@ -0,0 +1,363 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/mfd/locomo.h>
+
+struct locomospi_dev {
+	struct regmap *regmap;
+
+	int clock_base;
+	int clock_div;
+	unsigned nsecs;
+
+	unsigned int save_ct;
+	unsigned int save_md;
+};
+
+static int locomospi_reg_open(struct locomospi_dev *spidev)
+{
+	regmap_write(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_MSB1ST | LOCOMO_SPIMD_DOSTAT |
+			LOCOMO_SPIMD_RCPOL | LOCOMO_SPIMD_TCPOL |
+			(spidev->clock_base << 3) | spidev->clock_div);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			LOCOMO_SPIMD_XON);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN,
+			LOCOMO_SPICT_CEN | LOCOMO_SPICT_RXUEN |
+				LOCOMO_SPICT_ALIGNEN);
+
+	usleep_range(200, 300);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS, 0);
+
+	return 0;
+}
+
+static int locomospi_reg_release(struct locomospi_dev *spidev)
+{
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XEN, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD, LOCOMO_SPIMD_XON, 0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT,
+			LOCOMO_SPIMD_XEN,
+			LOCOMO_SPIMD_XEN);
+
+	return 0;
+}
+
+
+static void locomospi_chipselect(struct spi_device *spi, bool enable)
+{
+	struct locomospi_dev *spidev;
+
+	dev_dbg(&spi->dev, "SPI cs: %s\n", enable ? "enable" : "disable");
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS,
+			enable ? LOCOMO_SPICT_CS : 0);
+}
+
+static u32 locomospi_txrx_word(struct spi_device *spi,
+		unsigned nsecs,
+		u32 word)
+{
+	struct locomospi_dev *spidev;
+	int wait;
+	int j;
+	unsigned int rx;
+	unsigned int r;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	if (spidev->clock_div == DIV_64)
+		wait = 0x10000;
+	else
+		wait = 8;
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFW)
+			break;
+	}
+	if (j == wait)
+		dev_err(&spi->dev, "rfw timeout\n");
+
+	regmap_write(spidev->regmap, LOCOMO_SPITD, word);
+	ndelay(nsecs);
+
+	for (j = 0; j < wait; j++) {
+		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
+		if (r & LOCOMO_SPI_RFR)
+			break;
+	}
+	if (j == wait)
+		dev_err(&spi->dev, "rfr timeout\n");
+
+	regmap_read(spidev->regmap, LOCOMO_SPIRD, &rx);
+	ndelay(nsecs);
+
+	dev_dbg(&spi->dev, "SPI txrx: %02x/%02x\n", word, rx);
+
+	return rx;
+}
+
+static void locomo_spi_set_speed(struct locomospi_dev *spidev, u32 hz)
+{
+	spidev->nsecs = (1000000000/2) / hz;
+
+	if (hz >= 24576000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 22579200) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 18432000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_1;
+	} else if (hz >= 12288000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 11289600) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 9216000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_2;
+	} else if (hz >= 6144000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 5644800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 4608000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_4;
+	} else if (hz >= 3072000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2822400) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 2304000) {
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_8;
+	} else if (hz >= 384000) {
+		spidev->clock_base = CLOCK_25MHZ;
+		spidev->clock_div = DIV_64;
+	} else if (hz >= 352800) {
+		spidev->clock_base = CLOCK_22MHZ;
+		spidev->clock_div = DIV_64;
+	} else {		/* set to 288 Khz */
+		spidev->clock_base = CLOCK_18MHZ;
+		spidev->clock_div = DIV_64;
+	}
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			0);
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XSEL | LOCOMO_SPIMD_CLKSEL |
+				LOCOMO_SPIMD_XEN,
+			spidev->clock_div | (spidev->clock_base << 3) |
+				LOCOMO_SPIMD_XEN);
+
+	usleep_range(300, 400);
+}
+
+static int locomo_spi_setup_transfer(struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev;
+	u32 hz = 0;
+
+	if (t)
+		hz = t->speed_hz;
+	if (!hz)
+		hz = spi->max_speed_hz;
+
+	spidev = spi_master_get_devdata(spi->master);
+
+	regmap_update_bits(spidev->regmap, LOCOMO_SPIMD,
+			LOCOMO_SPIMD_XON,
+			hz ? LOCOMO_SPIMD_XON : 0);
+
+	if (hz != 0)
+		locomo_spi_set_speed(spidev, hz);
+
+	return 0;
+}
+
+static int locomospi_transfer_one(struct spi_master *master,
+		struct spi_device *spi,
+		struct spi_transfer *t)
+{
+	struct locomospi_dev *spidev = spi_master_get_devdata(spi->master);
+	int rc;
+	unsigned count;
+	const u8 *tx = t->tx_buf;
+	u8 *rx = t->rx_buf;
+
+	if (!tx && !rx && t->len)
+		return -EINVAL;
+
+	rc = locomo_spi_setup_transfer(spi, t);
+	if (rc < 0)
+		return rc;
+
+	if (!t->len)
+		return 0;
+
+	for (count = t->len; likely(count > 0); count--) {
+		u8 word = 0;
+
+		if (tx)
+			word = *tx++;
+		word = locomospi_txrx_word(spi, spidev->nsecs, word);
+
+		if (rx)
+			*rx++ = word;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_spi_suspend(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	/* Stop the queue running */
+	ret = spi_master_suspend(master);
+	if (ret) {
+		dev_warn(dev, "cannot suspend master\n");
+		return ret;
+	}
+
+	regmap_read(spidev->regmap, LOCOMO_SPICT, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPICT, LOCOMO_SPICT_CS);
+	regmap_read(spidev->regmap, LOCOMO_SPIMD, &spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, 0x3c14);
+
+
+	return 0;
+}
+
+static int locomo_spi_resume(struct device *dev)
+{
+	struct spi_master *master = dev_get_drvdata(dev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+	int ret;
+
+	regmap_write(spidev->regmap, LOCOMO_SPICT, spidev->save_ct);
+	regmap_write(spidev->regmap, LOCOMO_SPIMD, spidev->save_md);
+
+	/* Start the queue running */
+	ret = spi_master_resume(master);
+	if (ret)
+		dev_err(dev, "problem starting queue (%d)\n", ret);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(locomo_spi_pm_ops,
+		locomo_spi_suspend, locomo_spi_resume);
+
+#define LOCOMO_SPI_PM_OPS	(&locomo_spi_pm_ops)
+#else
+#define LOCOMO_SPI_PM_OPS	NULL
+#endif
+
+static int locomo_spi_probe(struct platform_device *pdev)
+{
+	struct spi_master *master;
+	struct locomospi_dev *spidev;
+	int ret = -ENODEV;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct locomospi_dev));
+	if (!master)
+		return -ENOMEM;
+
+	master->bus_num = 0;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 8);
+	master->max_speed_hz = 24576000;
+	master->num_chipselect = 1;
+	master->set_cs = locomospi_chipselect;
+	master->transfer_one = locomospi_transfer_one;
+
+	spidev = spi_master_get_devdata(master);
+
+	spidev->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!spidev->regmap)
+		goto out_put;
+
+	spidev->clock_div = DIV_64;
+	spidev->clock_base = CLOCK_18MHZ;
+
+	platform_set_drvdata(pdev, master);
+
+	ret = locomospi_reg_open(spidev);
+	if (ret < 0)
+		goto out_put;
+
+	ret = devm_spi_register_master(&pdev->dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
+		goto out_put;
+	}
+
+	return 0;
+
+out_put:
+	spi_master_put(master);
+	return ret;
+}
+
+static int locomo_spi_remove(struct platform_device *pdev)
+{
+	struct spi_master *master = platform_get_drvdata(pdev);
+	struct locomospi_dev *spidev = spi_master_get_devdata(master);
+
+	return locomospi_reg_release(spidev);
+}
+
+static struct platform_driver locomo_spi_driver = {
+	.probe = locomo_spi_probe,
+	.remove = locomo_spi_remove,
+	.driver = {
+		.name = "locomo-spi",
+		.pm = LOCOMO_SPI_PM_OPS,
+	},
+};
+module_platform_driver(locomo_spi_driver);
+
+MODULE_AUTHOR("Thomas Kunze thommy at tabao.de");
+MODULE_DESCRIPTION("LoCoMo SPI driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:locomo-spi");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
       [not found] ` <1430178954-11138-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

LoCoMo chip contains a tiny i2c controller destined to control
M62332 DAC. Provide a separate I2C driver for this cell.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/i2c/busses/Kconfig      |  12 ++++
 drivers/i2c/busses/Makefile     |   1 +
 drivers/i2c/busses/i2c-locomo.c | 136 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-locomo.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2255af2..114d9da 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -602,6 +602,18 @@ config I2C_KEMPLD
 	  This driver can also be built as a module. If so, the module
 	  will be called i2c-kempld.
 
+config I2C_LOCOMO
+	tristate "I2C bus support for LoCoMo chips"
+	depends on MFD_LOCOMO
+	select I2C_ALGOBIT
+	help
+	  Say yes if you will run the kernel on Sharp SL-5x00 family of devices.
+
+	  If you don't know what to do here, say N.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-locomo.
+
 config I2C_MESON
 	tristate "Amlogic Meson I2C controller"
 	depends on ARCH_MESON
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index cdf941d..e09dcf6 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
+obj-$(CONFIG_I2C_LOCOMO)	+= i2c-locomo.o
 obj-$(CONFIG_I2C_MESON)		+= i2c-meson.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
diff --git a/drivers/i2c/busses/i2c-locomo.c b/drivers/i2c/busses/i2c-locomo.c
new file mode 100644
index 0000000..640b46cd
--- /dev/null
+++ b/drivers/i2c/busses/i2c-locomo.c
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+struct locomo_i2c {
+	struct regmap		*regmap;
+	struct i2c_adapter	 adap;
+	struct i2c_algo_bit_data bit;
+};
+
+static void locomo_i2c_setsda(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB,
+			state ? LOCOMO_DAC_SDAOEB : 0);
+}
+
+static void locomo_i2c_setscl(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SCLOEB,
+			state ? LOCOMO_DAC_SCLOEB : 0);
+}
+
+static int locomo_i2c_getsda(void *data)
+{
+	struct locomo_i2c *li2c = data;
+	unsigned int r;
+
+	regmap_read(li2c->regmap, LOCOMO_DAC, &r);
+
+	return !!(r & LOCOMO_DAC_SDA);
+}
+
+static int locomo_i2c_probe(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c;
+	int ret;
+
+	li2c = devm_kzalloc(&dev->dev, sizeof(struct locomo_i2c), GFP_KERNEL);
+	if (li2c == NULL)
+		return -ENOMEM;
+
+	li2c->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!li2c->regmap)
+		return -ENODEV;
+
+	li2c->adap.owner = THIS_MODULE;
+	li2c->adap.dev.parent = &dev->dev;
+	li2c->adap.dev.of_node = dev->dev.of_node;
+	li2c->adap.algo_data = &li2c->bit;
+	li2c->adap.nr = 1; /* On poodle, 0 is pxa internal bus */
+
+	strlcpy(li2c->adap.name, "LoCoMo I2C", sizeof(li2c->adap.name));
+
+	li2c->bit.data = li2c;
+	li2c->bit.setsda = locomo_i2c_setsda;
+	li2c->bit.setscl = locomo_i2c_setscl;
+	li2c->bit.getsda = locomo_i2c_getsda;
+	li2c->bit.udelay = 6;
+	li2c->bit.timeout = HZ;
+
+	ret = i2c_bit_add_numbered_bus(&li2c->adap);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(dev, li2c);
+
+	return 0;
+}
+
+static int locomo_i2c_remove(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&li2c->adap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_i2c_suspend(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC, 0x00);
+
+	return 0;
+}
+
+static int locomo_i2c_resume(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB | LOCOMO_DAC_SCLOEB);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_i2c_pm, locomo_i2c_suspend, locomo_i2c_resume);
+#define LOCOMO_I2C_PM	(&locomo_i2c_pm)
+#else
+#define LOCOMO_I2C_PM	NULL
+#endif
+
+
+static struct platform_driver locomo_i2c_driver = {
+	.driver		= {
+		.name	= "locomo-i2c",
+		.pm	= LOCOMO_I2C_PM,
+	},
+	.probe		= locomo_i2c_probe,
+	.remove		= locomo_i2c_remove,
+};
+
+module_platform_driver(locomo_i2c_driver);
+
+MODULE_DESCRIPTION("LoCoMo i2c bus driver");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-i2c");
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

LoCoMo chip contains a tiny i2c controller destined to control
M62332 DAC. Provide a separate I2C driver for this cell.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/i2c/busses/Kconfig      |  12 ++++
 drivers/i2c/busses/Makefile     |   1 +
 drivers/i2c/busses/i2c-locomo.c | 136 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-locomo.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2255af2..114d9da 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -602,6 +602,18 @@ config I2C_KEMPLD
 	  This driver can also be built as a module. If so, the module
 	  will be called i2c-kempld.
 
+config I2C_LOCOMO
+	tristate "I2C bus support for LoCoMo chips"
+	depends on MFD_LOCOMO
+	select I2C_ALGOBIT
+	help
+	  Say yes if you will run the kernel on Sharp SL-5x00 family of devices.
+
+	  If you don't know what to do here, say N.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-locomo.
+
 config I2C_MESON
 	tristate "Amlogic Meson I2C controller"
 	depends on ARCH_MESON
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index cdf941d..e09dcf6 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
+obj-$(CONFIG_I2C_LOCOMO)	+= i2c-locomo.o
 obj-$(CONFIG_I2C_MESON)		+= i2c-meson.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
diff --git a/drivers/i2c/busses/i2c-locomo.c b/drivers/i2c/busses/i2c-locomo.c
new file mode 100644
index 0000000..640b46cd
--- /dev/null
+++ b/drivers/i2c/busses/i2c-locomo.c
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+struct locomo_i2c {
+	struct regmap		*regmap;
+	struct i2c_adapter	 adap;
+	struct i2c_algo_bit_data bit;
+};
+
+static void locomo_i2c_setsda(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB,
+			state ? LOCOMO_DAC_SDAOEB : 0);
+}
+
+static void locomo_i2c_setscl(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SCLOEB,
+			state ? LOCOMO_DAC_SCLOEB : 0);
+}
+
+static int locomo_i2c_getsda(void *data)
+{
+	struct locomo_i2c *li2c = data;
+	unsigned int r;
+
+	regmap_read(li2c->regmap, LOCOMO_DAC, &r);
+
+	return !!(r & LOCOMO_DAC_SDA);
+}
+
+static int locomo_i2c_probe(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c;
+	int ret;
+
+	li2c = devm_kzalloc(&dev->dev, sizeof(struct locomo_i2c), GFP_KERNEL);
+	if (li2c = NULL)
+		return -ENOMEM;
+
+	li2c->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!li2c->regmap)
+		return -ENODEV;
+
+	li2c->adap.owner = THIS_MODULE;
+	li2c->adap.dev.parent = &dev->dev;
+	li2c->adap.dev.of_node = dev->dev.of_node;
+	li2c->adap.algo_data = &li2c->bit;
+	li2c->adap.nr = 1; /* On poodle, 0 is pxa internal bus */
+
+	strlcpy(li2c->adap.name, "LoCoMo I2C", sizeof(li2c->adap.name));
+
+	li2c->bit.data = li2c;
+	li2c->bit.setsda = locomo_i2c_setsda;
+	li2c->bit.setscl = locomo_i2c_setscl;
+	li2c->bit.getsda = locomo_i2c_getsda;
+	li2c->bit.udelay = 6;
+	li2c->bit.timeout = HZ;
+
+	ret = i2c_bit_add_numbered_bus(&li2c->adap);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(dev, li2c);
+
+	return 0;
+}
+
+static int locomo_i2c_remove(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&li2c->adap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_i2c_suspend(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC, 0x00);
+
+	return 0;
+}
+
+static int locomo_i2c_resume(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB | LOCOMO_DAC_SCLOEB);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_i2c_pm, locomo_i2c_suspend, locomo_i2c_resume);
+#define LOCOMO_I2C_PM	(&locomo_i2c_pm)
+#else
+#define LOCOMO_I2C_PM	NULL
+#endif
+
+
+static struct platform_driver locomo_i2c_driver = {
+	.driver		= {
+		.name	= "locomo-i2c",
+		.pm	= LOCOMO_I2C_PM,
+	},
+	.probe		= locomo_i2c_probe,
+	.remove		= locomo_i2c_remove,
+};
+
+module_platform_driver(locomo_i2c_driver);
+
+MODULE_DESCRIPTION("LoCoMo i2c bus driver");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-i2c");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

LoCoMo chip contains a tiny i2c controller destined to control
M62332 DAC. Provide a separate I2C driver for this cell.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/i2c/busses/Kconfig      |  12 ++++
 drivers/i2c/busses/Makefile     |   1 +
 drivers/i2c/busses/i2c-locomo.c | 136 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-locomo.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 2255af2..114d9da 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -602,6 +602,18 @@ config I2C_KEMPLD
 	  This driver can also be built as a module. If so, the module
 	  will be called i2c-kempld.
 
+config I2C_LOCOMO
+	tristate "I2C bus support for LoCoMo chips"
+	depends on MFD_LOCOMO
+	select I2C_ALGOBIT
+	help
+	  Say yes if you will run the kernel on Sharp SL-5x00 family of devices.
+
+	  If you don't know what to do here, say N.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-locomo.
+
 config I2C_MESON
 	tristate "Amlogic Meson I2C controller"
 	depends on ARCH_MESON
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index cdf941d..e09dcf6 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_I2C_IMX)		+= i2c-imx.o
 obj-$(CONFIG_I2C_IOP3XX)	+= i2c-iop3xx.o
 obj-$(CONFIG_I2C_JZ4780)	+= i2c-jz4780.o
 obj-$(CONFIG_I2C_KEMPLD)	+= i2c-kempld.o
+obj-$(CONFIG_I2C_LOCOMO)	+= i2c-locomo.o
 obj-$(CONFIG_I2C_MESON)		+= i2c-meson.o
 obj-$(CONFIG_I2C_MPC)		+= i2c-mpc.o
 obj-$(CONFIG_I2C_MV64XXX)	+= i2c-mv64xxx.o
diff --git a/drivers/i2c/busses/i2c-locomo.c b/drivers/i2c/busses/i2c-locomo.c
new file mode 100644
index 0000000..640b46cd
--- /dev/null
+++ b/drivers/i2c/busses/i2c-locomo.c
@@ -0,0 +1,136 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/mfd/locomo.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+struct locomo_i2c {
+	struct regmap		*regmap;
+	struct i2c_adapter	 adap;
+	struct i2c_algo_bit_data bit;
+};
+
+static void locomo_i2c_setsda(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB,
+			state ? LOCOMO_DAC_SDAOEB : 0);
+}
+
+static void locomo_i2c_setscl(void *data, int state)
+{
+	struct locomo_i2c *li2c = data;
+
+	regmap_update_bits(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SCLOEB,
+			state ? LOCOMO_DAC_SCLOEB : 0);
+}
+
+static int locomo_i2c_getsda(void *data)
+{
+	struct locomo_i2c *li2c = data;
+	unsigned int r;
+
+	regmap_read(li2c->regmap, LOCOMO_DAC, &r);
+
+	return !!(r & LOCOMO_DAC_SDA);
+}
+
+static int locomo_i2c_probe(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c;
+	int ret;
+
+	li2c = devm_kzalloc(&dev->dev, sizeof(struct locomo_i2c), GFP_KERNEL);
+	if (li2c == NULL)
+		return -ENOMEM;
+
+	li2c->regmap = dev_get_regmap(dev->dev.parent, NULL);
+	if (!li2c->regmap)
+		return -ENODEV;
+
+	li2c->adap.owner = THIS_MODULE;
+	li2c->adap.dev.parent = &dev->dev;
+	li2c->adap.dev.of_node = dev->dev.of_node;
+	li2c->adap.algo_data = &li2c->bit;
+	li2c->adap.nr = 1; /* On poodle, 0 is pxa internal bus */
+
+	strlcpy(li2c->adap.name, "LoCoMo I2C", sizeof(li2c->adap.name));
+
+	li2c->bit.data = li2c;
+	li2c->bit.setsda = locomo_i2c_setsda;
+	li2c->bit.setscl = locomo_i2c_setscl;
+	li2c->bit.getsda = locomo_i2c_getsda;
+	li2c->bit.udelay = 6;
+	li2c->bit.timeout = HZ;
+
+	ret = i2c_bit_add_numbered_bus(&li2c->adap);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(dev, li2c);
+
+	return 0;
+}
+
+static int locomo_i2c_remove(struct platform_device *dev)
+{
+	struct locomo_i2c *li2c = platform_get_drvdata(dev);
+
+	i2c_del_adapter(&li2c->adap);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int locomo_i2c_suspend(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC, 0x00);
+
+	return 0;
+}
+
+static int locomo_i2c_resume(struct device *dev)
+{
+	struct locomo_i2c *li2c = dev_get_drvdata(dev);
+
+	regmap_write(li2c->regmap, LOCOMO_DAC,
+			LOCOMO_DAC_SDAOEB | LOCOMO_DAC_SCLOEB);
+
+	return 0;
+}
+static SIMPLE_DEV_PM_OPS(locomo_i2c_pm, locomo_i2c_suspend, locomo_i2c_resume);
+#define LOCOMO_I2C_PM	(&locomo_i2c_pm)
+#else
+#define LOCOMO_I2C_PM	NULL
+#endif
+
+
+static struct platform_driver locomo_i2c_driver = {
+	.driver		= {
+		.name	= "locomo-i2c",
+		.pm	= LOCOMO_I2C_PM,
+	},
+	.probe		= locomo_i2c_probe,
+	.remove		= locomo_i2c_remove,
+};
+
+module_platform_driver(locomo_i2c_driver);
+
+MODULE_DESCRIPTION("LoCoMo i2c bus driver");
+MODULE_AUTHOR("Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:locomo-i2c");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 11/17] ARM: sa1100: make collie use new locomo drivers
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Switch collie to new mfd-based locomo driver. Update platform data and
add necessary spi, i2c and regulator devices.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/Kconfig               |   1 -
 arch/arm/mach-sa1100/collie.c              | 213 ++++++++++++++++++++++-------
 arch/arm/mach-sa1100/include/mach/collie.h |  25 +++-
 3 files changed, 187 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index c6f6ed1..37af126 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -48,7 +48,6 @@ endchoice
 config SA1100_COLLIE
 	bool "Sharp Zaurus SL5500"
 	# FIXME: select ARM_SA11x0_CPUFREQ
-	select SHARP_LOCOMO
 	select SHARP_PARAM
 	select SHARP_SCOOP
 	help
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 3cc2b71..b6dda7a 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -24,13 +24,21 @@
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ucb1x00.h>
+#include <linux/mfd/locomo.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/power/gpio-charger.h>
+#include <linux/gpio/machine.h>
+#include <linux/iio/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/mmc_spi.h>
 
 #include <video/sa1100fb.h>
 
@@ -47,7 +55,6 @@
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
-#include <asm/hardware/locomo.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
 #include <mach/irqs.h>
 
@@ -151,36 +158,54 @@ static struct platform_device collie_power_device = {
 	.dev.platform_data	= &collie_power_data,
 };
 
-#ifdef CONFIG_SHARP_LOCOMO
 /*
  * low-level UART features.
  */
-struct platform_device collie_locomo_device;
+static struct gpio collie_uart_gpio[] = {
+	{ COLLIE_GPIO_CTS, GPIOF_IN, "CTS" },
+	{ COLLIE_GPIO_RTS, GPIOF_OUT_INIT_LOW, "RTS" },
+	{ COLLIE_GPIO_DTR, GPIOF_OUT_INIT_LOW, "DTR" },
+	{ COLLIE_GPIO_DSR, GPIOF_IN, "DSR" },
+};
+
+static bool collie_uart_gpio_ok;
 
 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	if (mctrl & TIOCM_RTS)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
-
-	if (mctrl & TIOCM_DTR)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_set_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (collie_uart_gpio_ok) {
+		gpio_set_value(COLLIE_GPIO_RTS, !(mctrl & TIOCM_RTS));
+		gpio_set_value(COLLIE_GPIO_DTR, !(mctrl & TIOCM_DTR));
+	}
 }
 
 static u_int collie_uart_get_mctrl(struct uart_port *port)
 {
 	int ret = TIOCM_CD;
-	unsigned int r;
 
-	r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
-	if (r == -ENODEV)
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_get_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (!collie_uart_gpio_ok)
 		return ret;
-	if (r & LOCOMO_GPIO_CTS)
+
+	if (gpio_get_value(COLLIE_GPIO_CTS))
 		ret |= TIOCM_CTS;
-	if (r & LOCOMO_GPIO_DSR)
+	if (gpio_get_value(COLLIE_GPIO_DSR))
 		ret |= TIOCM_DSR;
 
 	return ret;
@@ -191,33 +216,35 @@ static struct sa1100_port_fns collie_port_fns __initdata = {
 	.get_mctrl	= collie_uart_get_mctrl,
 };
 
-static int collie_uart_probe(struct locomo_dev *dev)
-{
-	return 0;
-}
-
-static int collie_uart_remove(struct locomo_dev *dev)
-{
-	return 0;
-}
+static struct regulator_consumer_supply collie_amp_on_consumer_supplies[] = {
+	REGULATOR_SUPPLY("VCC", "1-004e"),
+};
 
-static struct locomo_driver collie_uart_driver = {
-	.drv = {
-		.name = "collie_uart",
+static struct regulator_init_data collie_amp_on_init_data = {
+	.constraints	= {
+		.name	= "AMP_ON",
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 	},
-	.devid	= LOCOMO_DEVID_UART,
-	.probe	= collie_uart_probe,
-	.remove	= collie_uart_remove,
+	.consumer_supplies = collie_amp_on_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(collie_amp_on_consumer_supplies),
 };
 
-static int __init collie_uart_init(void)
-{
-	return locomo_driver_register(&collie_uart_driver);
-}
-device_initcall(collie_uart_init);
-
-#endif
+static struct fixed_voltage_config collie_amp_on_data = {
+	.supply_name	= "amp_on",
+	.microvolts	= 3300000,
+	.gpio		= COLLIE_GPIO_AMP2_ON,
+	.startup_delay	= 5,
+	.enable_high	= 1,
+	.init_data	= &collie_amp_on_init_data,
+};
 
+static struct platform_device collie_amp_on_device = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.dev = {
+		.platform_data	= &collie_amp_on_data,
+	},
+};
 
 static struct resource locomo_resources[] = {
 	[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
@@ -225,14 +252,15 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base = COLLIE_LOCOMO_GPIO_BASE,
+	.comadj	          = 128,
 };
 
-struct platform_device collie_locomo_device = {
+static struct platform_device collie_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &locomo_info,
+		.platform_data  = &locomo_info,
 	},
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
@@ -270,7 +298,55 @@ static struct platform_device collie_gpio_keys_device = {
 	},
 };
 
+static int collie_mmc_init(struct device *dev,
+		irqreturn_t (*isr)(int, void*), void *mmc)
+{
+	int ret;
+
+	ret = gpio_request(COLLIE_GPIO_CARD_POWER, "MMC power");
+	if (!ret)
+		ret = gpio_direction_output(COLLIE_GPIO_CARD_POWER, 0);
+	if (ret)
+		gpio_free(COLLIE_GPIO_CARD_POWER);
+	return ret;
+}
+
+static void collie_mmc_exit(struct device *dev, void *mmc)
+{
+	gpio_free(COLLIE_GPIO_CARD_POWER);
+}
+
+static void collie_mmc_setpower(struct device *dev, unsigned int mask)
+{
+	gpio_set_value(COLLIE_GPIO_CARD_POWER, !!mask);
+}
+
+static struct mmc_spi_platform_data collie_mmc_data = {
+	.init		= collie_mmc_init,
+	.exit		= collie_mmc_exit,
+	.setpower	= collie_mmc_setpower,
+	.detect_delay	= 200,
+	.powerup_msecs  = 200,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.flags		= MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
+	.cd_gpio	= COLLIE_GPIO_CARD_DETECT,
+	.ro_gpio	= COLLIE_GPIO_CARD_RO,
+	.caps2		= MMC_CAP2_RO_ACTIVE_HIGH,
+};
+
+static struct spi_board_info collie_spi_board_info[] __initdata = {
+	{
+		.modalias	= "mmc_spi",
+		.platform_data	= &collie_mmc_data,
+		.max_speed_hz	= 25000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+	},
+};
+
 static struct platform_device *devices[] __initdata = {
+	&collie_amp_on_device,
 	&collie_locomo_device,
 	&colliescoop_device,
 	&collie_power_device,
@@ -347,10 +423,39 @@ static struct sa1100fb_mach_info collie_lcd_info = {
 
 	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
 	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+};
 
-#ifdef CONFIG_BACKLIGHT_LOCOMO
-	.lcd_power	= locomolcd_power
-#endif
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table collie_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, collie_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init collie_init(void)
@@ -381,11 +486,19 @@ static void __init collie_init(void)
 
 	GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
 
+	sharpsl_save_param();
+
 	sa11x0_ppc_configure_mcp();
 
 
 	platform_scoop_config = &collie_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&collie_bl_gpios_table);
+	gpiod_add_lookup_table(&collie_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret) {
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
@@ -397,7 +510,13 @@ static void __init collie_init(void)
 	sa11x0_register_mcp(&collie_mcp_data);
 	sa11x0_register_irda(&collie_ir_data);
 
-	sharpsl_save_param();
+	i2c_register_board_info(1,
+			locomo_i2c_devs, ARRAY_SIZE(locomo_i2c_devs));
+
+	spi_register_board_info(collie_spi_board_info,
+			ARRAY_SIZE(collie_spi_board_info));
+
+	regulator_has_full_constraints();
 }
 
 static struct map_desc collie_io_desc[] __initdata = {
@@ -419,9 +538,7 @@ static void __init collie_map_io(void)
 	sa1100_map_io();
 	iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
 
-#ifdef CONFIG_SHARP_LOCOMO
 	sa1100_register_uart_fns(&collie_port_fns);
-#endif
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 }
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index b478ca1..a66319a 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -24,12 +24,12 @@ extern void locomolcd_power(int on);
 #define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
 #define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
 #define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
-#define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
+#define COLLIE_GPIO_AMP2_ON	(COLLIE_SCOOP_GPIO_BASE + 6)
 #define COLLIE_GPIO_VPEN	(COLLIE_SCOOP_GPIO_BASE + 7)
 #define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19
 
 #define COLLIE_SCOOP_IO_DIR	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
-				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+				COLLIE_SCP_5VON | \
 				COLLIE_SCP_LB_VOL_CHG)
 #define COLLIE_SCOOP_IO_OUT	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
 
@@ -81,7 +81,7 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
 #define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
 #define COLLIE_GPIO_IR_ON		(COLLIE_TC35143_GPIO_BASE + 3)
-#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
+#define COLLIE_GPIO_AMP1_ON		(COLLIE_TC35143_GPIO_BASE + 4)
 #define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
 #define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
 #define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
@@ -92,4 +92,23 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_OUT		(UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
 						| UCB_IO_6)
 
+/* GPIOs on LoCoMo GA */
+#define COLLIE_LOCOMO_GPIO_BASE		(GPIO_MAX + 23)
+#define COLLIE_GPIO_RTS			(COLLIE_LOCOMO_GPIO_BASE + 0)
+#define COLLIE_GPIO_CTS			(COLLIE_LOCOMO_GPIO_BASE + 1)
+#define COLLIE_GPIO_DSR			(COLLIE_LOCOMO_GPIO_BASE + 2)
+#define COLLIE_GPIO_DTR			(COLLIE_LOCOMO_GPIO_BASE + 3)
+#define COLLIE_GPIO_LCD_VSHA_ON		(COLLIE_LOCOMO_GPIO_BASE + 4)
+#define COLLIE_GPIO_LCD_VSHD_ON		(COLLIE_LOCOMO_GPIO_BASE + 5)
+#define COLLIE_GPIO_LCD_VEE_ON		(COLLIE_LOCOMO_GPIO_BASE + 6)
+#define COLLIE_GPIO_LCD_MOD		(COLLIE_LOCOMO_GPIO_BASE + 7)
+#define COLLIE_LOCOMO_GPIO_DAC_ON	LOCOMO_GPIO(8)
+#define COLLIE_GPIO_FL_VR		(COLLIE_LOCOMO_GPIO_BASE + 9)
+#define COLLIE_LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
+#define COLLIE_LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
+#define COLLIE_LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
+#define COLLIE_GPIO_CARD_DETECT		(COLLIE_LOCOMO_GPIO_BASE + 13)
+#define COLLIE_GPIO_CARD_RO		(COLLIE_LOCOMO_GPIO_BASE + 14)
+#define COLLIE_GPIO_CARD_POWER		(COLLIE_LOCOMO_GPIO_BASE + 15)
+
 #endif
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 11/17] ARM: sa1100: make collie use new locomo drivers
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Switch collie to new mfd-based locomo driver. Update platform data and
add necessary spi, i2c and regulator devices.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/Kconfig               |   1 -
 arch/arm/mach-sa1100/collie.c              | 213 ++++++++++++++++++++++-------
 arch/arm/mach-sa1100/include/mach/collie.h |  25 +++-
 3 files changed, 187 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index c6f6ed1..37af126 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -48,7 +48,6 @@ endchoice
 config SA1100_COLLIE
 	bool "Sharp Zaurus SL5500"
 	# FIXME: select ARM_SA11x0_CPUFREQ
-	select SHARP_LOCOMO
 	select SHARP_PARAM
 	select SHARP_SCOOP
 	help
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 3cc2b71..b6dda7a 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -24,13 +24,21 @@
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ucb1x00.h>
+#include <linux/mfd/locomo.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/power/gpio-charger.h>
+#include <linux/gpio/machine.h>
+#include <linux/iio/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/mmc_spi.h>
 
 #include <video/sa1100fb.h>
 
@@ -47,7 +55,6 @@
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
-#include <asm/hardware/locomo.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
 #include <mach/irqs.h>
 
@@ -151,36 +158,54 @@ static struct platform_device collie_power_device = {
 	.dev.platform_data	= &collie_power_data,
 };
 
-#ifdef CONFIG_SHARP_LOCOMO
 /*
  * low-level UART features.
  */
-struct platform_device collie_locomo_device;
+static struct gpio collie_uart_gpio[] = {
+	{ COLLIE_GPIO_CTS, GPIOF_IN, "CTS" },
+	{ COLLIE_GPIO_RTS, GPIOF_OUT_INIT_LOW, "RTS" },
+	{ COLLIE_GPIO_DTR, GPIOF_OUT_INIT_LOW, "DTR" },
+	{ COLLIE_GPIO_DSR, GPIOF_IN, "DSR" },
+};
+
+static bool collie_uart_gpio_ok;
 
 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	if (mctrl & TIOCM_RTS)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
-
-	if (mctrl & TIOCM_DTR)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_set_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (collie_uart_gpio_ok) {
+		gpio_set_value(COLLIE_GPIO_RTS, !(mctrl & TIOCM_RTS));
+		gpio_set_value(COLLIE_GPIO_DTR, !(mctrl & TIOCM_DTR));
+	}
 }
 
 static u_int collie_uart_get_mctrl(struct uart_port *port)
 {
 	int ret = TIOCM_CD;
-	unsigned int r;
 
-	r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
-	if (r = -ENODEV)
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_get_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (!collie_uart_gpio_ok)
 		return ret;
-	if (r & LOCOMO_GPIO_CTS)
+
+	if (gpio_get_value(COLLIE_GPIO_CTS))
 		ret |= TIOCM_CTS;
-	if (r & LOCOMO_GPIO_DSR)
+	if (gpio_get_value(COLLIE_GPIO_DSR))
 		ret |= TIOCM_DSR;
 
 	return ret;
@@ -191,33 +216,35 @@ static struct sa1100_port_fns collie_port_fns __initdata = {
 	.get_mctrl	= collie_uart_get_mctrl,
 };
 
-static int collie_uart_probe(struct locomo_dev *dev)
-{
-	return 0;
-}
-
-static int collie_uart_remove(struct locomo_dev *dev)
-{
-	return 0;
-}
+static struct regulator_consumer_supply collie_amp_on_consumer_supplies[] = {
+	REGULATOR_SUPPLY("VCC", "1-004e"),
+};
 
-static struct locomo_driver collie_uart_driver = {
-	.drv = {
-		.name = "collie_uart",
+static struct regulator_init_data collie_amp_on_init_data = {
+	.constraints	= {
+		.name	= "AMP_ON",
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 	},
-	.devid	= LOCOMO_DEVID_UART,
-	.probe	= collie_uart_probe,
-	.remove	= collie_uart_remove,
+	.consumer_supplies = collie_amp_on_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(collie_amp_on_consumer_supplies),
 };
 
-static int __init collie_uart_init(void)
-{
-	return locomo_driver_register(&collie_uart_driver);
-}
-device_initcall(collie_uart_init);
-
-#endif
+static struct fixed_voltage_config collie_amp_on_data = {
+	.supply_name	= "amp_on",
+	.microvolts	= 3300000,
+	.gpio		= COLLIE_GPIO_AMP2_ON,
+	.startup_delay	= 5,
+	.enable_high	= 1,
+	.init_data	= &collie_amp_on_init_data,
+};
 
+static struct platform_device collie_amp_on_device = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.dev = {
+		.platform_data	= &collie_amp_on_data,
+	},
+};
 
 static struct resource locomo_resources[] = {
 	[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
@@ -225,14 +252,15 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base = COLLIE_LOCOMO_GPIO_BASE,
+	.comadj	          = 128,
 };
 
-struct platform_device collie_locomo_device = {
+static struct platform_device collie_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &locomo_info,
+		.platform_data  = &locomo_info,
 	},
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
@@ -270,7 +298,55 @@ static struct platform_device collie_gpio_keys_device = {
 	},
 };
 
+static int collie_mmc_init(struct device *dev,
+		irqreturn_t (*isr)(int, void*), void *mmc)
+{
+	int ret;
+
+	ret = gpio_request(COLLIE_GPIO_CARD_POWER, "MMC power");
+	if (!ret)
+		ret = gpio_direction_output(COLLIE_GPIO_CARD_POWER, 0);
+	if (ret)
+		gpio_free(COLLIE_GPIO_CARD_POWER);
+	return ret;
+}
+
+static void collie_mmc_exit(struct device *dev, void *mmc)
+{
+	gpio_free(COLLIE_GPIO_CARD_POWER);
+}
+
+static void collie_mmc_setpower(struct device *dev, unsigned int mask)
+{
+	gpio_set_value(COLLIE_GPIO_CARD_POWER, !!mask);
+}
+
+static struct mmc_spi_platform_data collie_mmc_data = {
+	.init		= collie_mmc_init,
+	.exit		= collie_mmc_exit,
+	.setpower	= collie_mmc_setpower,
+	.detect_delay	= 200,
+	.powerup_msecs  = 200,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.flags		= MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
+	.cd_gpio	= COLLIE_GPIO_CARD_DETECT,
+	.ro_gpio	= COLLIE_GPIO_CARD_RO,
+	.caps2		= MMC_CAP2_RO_ACTIVE_HIGH,
+};
+
+static struct spi_board_info collie_spi_board_info[] __initdata = {
+	{
+		.modalias	= "mmc_spi",
+		.platform_data	= &collie_mmc_data,
+		.max_speed_hz	= 25000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+	},
+};
+
 static struct platform_device *devices[] __initdata = {
+	&collie_amp_on_device,
 	&collie_locomo_device,
 	&colliescoop_device,
 	&collie_power_device,
@@ -347,10 +423,39 @@ static struct sa1100fb_mach_info collie_lcd_info = {
 
 	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
 	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+};
 
-#ifdef CONFIG_BACKLIGHT_LOCOMO
-	.lcd_power	= locomolcd_power
-#endif
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table collie_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, collie_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init collie_init(void)
@@ -381,11 +486,19 @@ static void __init collie_init(void)
 
 	GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
 
+	sharpsl_save_param();
+
 	sa11x0_ppc_configure_mcp();
 
 
 	platform_scoop_config = &collie_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&collie_bl_gpios_table);
+	gpiod_add_lookup_table(&collie_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret) {
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
@@ -397,7 +510,13 @@ static void __init collie_init(void)
 	sa11x0_register_mcp(&collie_mcp_data);
 	sa11x0_register_irda(&collie_ir_data);
 
-	sharpsl_save_param();
+	i2c_register_board_info(1,
+			locomo_i2c_devs, ARRAY_SIZE(locomo_i2c_devs));
+
+	spi_register_board_info(collie_spi_board_info,
+			ARRAY_SIZE(collie_spi_board_info));
+
+	regulator_has_full_constraints();
 }
 
 static struct map_desc collie_io_desc[] __initdata = {
@@ -419,9 +538,7 @@ static void __init collie_map_io(void)
 	sa1100_map_io();
 	iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
 
-#ifdef CONFIG_SHARP_LOCOMO
 	sa1100_register_uart_fns(&collie_port_fns);
-#endif
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 }
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index b478ca1..a66319a 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -24,12 +24,12 @@ extern void locomolcd_power(int on);
 #define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
 #define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
 #define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
-#define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
+#define COLLIE_GPIO_AMP2_ON	(COLLIE_SCOOP_GPIO_BASE + 6)
 #define COLLIE_GPIO_VPEN	(COLLIE_SCOOP_GPIO_BASE + 7)
 #define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19
 
 #define COLLIE_SCOOP_IO_DIR	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
-				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+				COLLIE_SCP_5VON | \
 				COLLIE_SCP_LB_VOL_CHG)
 #define COLLIE_SCOOP_IO_OUT	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
 
@@ -81,7 +81,7 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
 #define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
 #define COLLIE_GPIO_IR_ON		(COLLIE_TC35143_GPIO_BASE + 3)
-#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
+#define COLLIE_GPIO_AMP1_ON		(COLLIE_TC35143_GPIO_BASE + 4)
 #define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
 #define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
 #define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
@@ -92,4 +92,23 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_OUT		(UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
 						| UCB_IO_6)
 
+/* GPIOs on LoCoMo GA */
+#define COLLIE_LOCOMO_GPIO_BASE		(GPIO_MAX + 23)
+#define COLLIE_GPIO_RTS			(COLLIE_LOCOMO_GPIO_BASE + 0)
+#define COLLIE_GPIO_CTS			(COLLIE_LOCOMO_GPIO_BASE + 1)
+#define COLLIE_GPIO_DSR			(COLLIE_LOCOMO_GPIO_BASE + 2)
+#define COLLIE_GPIO_DTR			(COLLIE_LOCOMO_GPIO_BASE + 3)
+#define COLLIE_GPIO_LCD_VSHA_ON		(COLLIE_LOCOMO_GPIO_BASE + 4)
+#define COLLIE_GPIO_LCD_VSHD_ON		(COLLIE_LOCOMO_GPIO_BASE + 5)
+#define COLLIE_GPIO_LCD_VEE_ON		(COLLIE_LOCOMO_GPIO_BASE + 6)
+#define COLLIE_GPIO_LCD_MOD		(COLLIE_LOCOMO_GPIO_BASE + 7)
+#define COLLIE_LOCOMO_GPIO_DAC_ON	LOCOMO_GPIO(8)
+#define COLLIE_GPIO_FL_VR		(COLLIE_LOCOMO_GPIO_BASE + 9)
+#define COLLIE_LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
+#define COLLIE_LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
+#define COLLIE_LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
+#define COLLIE_GPIO_CARD_DETECT		(COLLIE_LOCOMO_GPIO_BASE + 13)
+#define COLLIE_GPIO_CARD_RO		(COLLIE_LOCOMO_GPIO_BASE + 14)
+#define COLLIE_GPIO_CARD_POWER		(COLLIE_LOCOMO_GPIO_BASE + 15)
+
 #endif
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 11/17] ARM: sa1100: make collie use new locomo drivers
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Switch collie to new mfd-based locomo driver. Update platform data and
add necessary spi, i2c and regulator devices.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/Kconfig               |   1 -
 arch/arm/mach-sa1100/collie.c              | 213 ++++++++++++++++++++++-------
 arch/arm/mach-sa1100/include/mach/collie.h |  25 +++-
 3 files changed, 187 insertions(+), 52 deletions(-)

diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index c6f6ed1..37af126 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -48,7 +48,6 @@ endchoice
 config SA1100_COLLIE
 	bool "Sharp Zaurus SL5500"
 	# FIXME: select ARM_SA11x0_CPUFREQ
-	select SHARP_LOCOMO
 	select SHARP_PARAM
 	select SHARP_SCOOP
 	help
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 3cc2b71..b6dda7a 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -24,13 +24,21 @@
 #include <linux/platform_data/sa11x0-serial.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ucb1x00.h>
+#include <linux/mfd/locomo.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/timer.h>
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
+#include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/power/gpio-charger.h>
+#include <linux/gpio/machine.h>
+#include <linux/iio/machine.h>
+#include <linux/mmc/host.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/spi/mmc_spi.h>
 
 #include <video/sa1100fb.h>
 
@@ -47,7 +55,6 @@
 
 #include <asm/hardware/scoop.h>
 #include <asm/mach/sharpsl_param.h>
-#include <asm/hardware/locomo.h>
 #include <linux/platform_data/mfd-mcp-sa11x0.h>
 #include <mach/irqs.h>
 
@@ -151,36 +158,54 @@ static struct platform_device collie_power_device = {
 	.dev.platform_data	= &collie_power_data,
 };
 
-#ifdef CONFIG_SHARP_LOCOMO
 /*
  * low-level UART features.
  */
-struct platform_device collie_locomo_device;
+static struct gpio collie_uart_gpio[] = {
+	{ COLLIE_GPIO_CTS, GPIOF_IN, "CTS" },
+	{ COLLIE_GPIO_RTS, GPIOF_OUT_INIT_LOW, "RTS" },
+	{ COLLIE_GPIO_DTR, GPIOF_OUT_INIT_LOW, "DTR" },
+	{ COLLIE_GPIO_DSR, GPIOF_IN, "DSR" },
+};
+
+static bool collie_uart_gpio_ok;
 
 static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
 {
-	if (mctrl & TIOCM_RTS)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
-
-	if (mctrl & TIOCM_DTR)
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
-	else
-		locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_set_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (collie_uart_gpio_ok) {
+		gpio_set_value(COLLIE_GPIO_RTS, !(mctrl & TIOCM_RTS));
+		gpio_set_value(COLLIE_GPIO_DTR, !(mctrl & TIOCM_DTR));
+	}
 }
 
 static u_int collie_uart_get_mctrl(struct uart_port *port)
 {
 	int ret = TIOCM_CD;
-	unsigned int r;
 
-	r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
-	if (r == -ENODEV)
+	if (!collie_uart_gpio_ok) {
+		int rc = gpio_request_array(collie_uart_gpio,
+				ARRAY_SIZE(collie_uart_gpio));
+		if (rc)
+			pr_err("collie_uart_get_mctrl: gpio request %d\n", rc);
+		else
+			collie_uart_gpio_ok = true;
+	}
+
+	if (!collie_uart_gpio_ok)
 		return ret;
-	if (r & LOCOMO_GPIO_CTS)
+
+	if (gpio_get_value(COLLIE_GPIO_CTS))
 		ret |= TIOCM_CTS;
-	if (r & LOCOMO_GPIO_DSR)
+	if (gpio_get_value(COLLIE_GPIO_DSR))
 		ret |= TIOCM_DSR;
 
 	return ret;
@@ -191,33 +216,35 @@ static struct sa1100_port_fns collie_port_fns __initdata = {
 	.get_mctrl	= collie_uart_get_mctrl,
 };
 
-static int collie_uart_probe(struct locomo_dev *dev)
-{
-	return 0;
-}
-
-static int collie_uart_remove(struct locomo_dev *dev)
-{
-	return 0;
-}
+static struct regulator_consumer_supply collie_amp_on_consumer_supplies[] = {
+	REGULATOR_SUPPLY("VCC", "1-004e"),
+};
 
-static struct locomo_driver collie_uart_driver = {
-	.drv = {
-		.name = "collie_uart",
+static struct regulator_init_data collie_amp_on_init_data = {
+	.constraints	= {
+		.name	= "AMP_ON",
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
 	},
-	.devid	= LOCOMO_DEVID_UART,
-	.probe	= collie_uart_probe,
-	.remove	= collie_uart_remove,
+	.consumer_supplies = collie_amp_on_consumer_supplies,
+	.num_consumer_supplies = ARRAY_SIZE(collie_amp_on_consumer_supplies),
 };
 
-static int __init collie_uart_init(void)
-{
-	return locomo_driver_register(&collie_uart_driver);
-}
-device_initcall(collie_uart_init);
-
-#endif
+static struct fixed_voltage_config collie_amp_on_data = {
+	.supply_name	= "amp_on",
+	.microvolts	= 3300000,
+	.gpio		= COLLIE_GPIO_AMP2_ON,
+	.startup_delay	= 5,
+	.enable_high	= 1,
+	.init_data	= &collie_amp_on_init_data,
+};
 
+static struct platform_device collie_amp_on_device = {
+	.name		= "reg-fixed-voltage",
+	.id		= -1,
+	.dev = {
+		.platform_data	= &collie_amp_on_data,
+	},
+};
 
 static struct resource locomo_resources[] = {
 	[0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
@@ -225,14 +252,15 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base = COLLIE_LOCOMO_GPIO_BASE,
+	.comadj	          = 128,
 };
 
-struct platform_device collie_locomo_device = {
+static struct platform_device collie_locomo_device = {
 	.name		= "locomo",
 	.id		= 0,
 	.dev		= {
-		.platform_data	= &locomo_info,
+		.platform_data  = &locomo_info,
 	},
 	.num_resources	= ARRAY_SIZE(locomo_resources),
 	.resource	= locomo_resources,
@@ -270,7 +298,55 @@ static struct platform_device collie_gpio_keys_device = {
 	},
 };
 
+static int collie_mmc_init(struct device *dev,
+		irqreturn_t (*isr)(int, void*), void *mmc)
+{
+	int ret;
+
+	ret = gpio_request(COLLIE_GPIO_CARD_POWER, "MMC power");
+	if (!ret)
+		ret = gpio_direction_output(COLLIE_GPIO_CARD_POWER, 0);
+	if (ret)
+		gpio_free(COLLIE_GPIO_CARD_POWER);
+	return ret;
+}
+
+static void collie_mmc_exit(struct device *dev, void *mmc)
+{
+	gpio_free(COLLIE_GPIO_CARD_POWER);
+}
+
+static void collie_mmc_setpower(struct device *dev, unsigned int mask)
+{
+	gpio_set_value(COLLIE_GPIO_CARD_POWER, !!mask);
+}
+
+static struct mmc_spi_platform_data collie_mmc_data = {
+	.init		= collie_mmc_init,
+	.exit		= collie_mmc_exit,
+	.setpower	= collie_mmc_setpower,
+	.detect_delay	= 200,
+	.powerup_msecs  = 200,
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.flags		= MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO,
+	.cd_gpio	= COLLIE_GPIO_CARD_DETECT,
+	.ro_gpio	= COLLIE_GPIO_CARD_RO,
+	.caps2		= MMC_CAP2_RO_ACTIVE_HIGH,
+};
+
+static struct spi_board_info collie_spi_board_info[] __initdata = {
+	{
+		.modalias	= "mmc_spi",
+		.platform_data	= &collie_mmc_data,
+		.max_speed_hz	= 25000000,
+		.bus_num	= 0,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+	},
+};
+
 static struct platform_device *devices[] __initdata = {
+	&collie_amp_on_device,
 	&collie_locomo_device,
 	&colliescoop_device,
 	&collie_power_device,
@@ -347,10 +423,39 @@ static struct sa1100fb_mach_info collie_lcd_info = {
 
 	.lccr0		= LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
 	.lccr3		= LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+};
 
-#ifdef CONFIG_BACKLIGHT_LOCOMO
-	.lcd_power	= locomolcd_power
-#endif
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table collie_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, collie_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
 };
 
 static void __init collie_init(void)
@@ -381,11 +486,19 @@ static void __init collie_init(void)
 
 	GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
 
+	sharpsl_save_param();
+
 	sa11x0_ppc_configure_mcp();
 
 
 	platform_scoop_config = &collie_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&collie_bl_gpios_table);
+	gpiod_add_lookup_table(&collie_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret) {
 		printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
@@ -397,7 +510,13 @@ static void __init collie_init(void)
 	sa11x0_register_mcp(&collie_mcp_data);
 	sa11x0_register_irda(&collie_ir_data);
 
-	sharpsl_save_param();
+	i2c_register_board_info(1,
+			locomo_i2c_devs, ARRAY_SIZE(locomo_i2c_devs));
+
+	spi_register_board_info(collie_spi_board_info,
+			ARRAY_SIZE(collie_spi_board_info));
+
+	regulator_has_full_constraints();
 }
 
 static struct map_desc collie_io_desc[] __initdata = {
@@ -419,9 +538,7 @@ static void __init collie_map_io(void)
 	sa1100_map_io();
 	iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
 
-#ifdef CONFIG_SHARP_LOCOMO
 	sa1100_register_uart_fns(&collie_port_fns);
-#endif
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 }
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
index b478ca1..a66319a 100644
--- a/arch/arm/mach-sa1100/include/mach/collie.h
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -24,12 +24,12 @@ extern void locomolcd_power(int on);
 #define COLLIE_SCP_MUTE_L	SCOOP_GPCR_PA14
 #define COLLIE_SCP_MUTE_R	SCOOP_GPCR_PA15
 #define COLLIE_SCP_5VON		SCOOP_GPCR_PA16
-#define COLLIE_SCP_AMP_ON	SCOOP_GPCR_PA17
+#define COLLIE_GPIO_AMP2_ON	(COLLIE_SCOOP_GPIO_BASE + 6)
 #define COLLIE_GPIO_VPEN	(COLLIE_SCOOP_GPIO_BASE + 7)
 #define COLLIE_SCP_LB_VOL_CHG	SCOOP_GPCR_PA19
 
 #define COLLIE_SCOOP_IO_DIR	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
-				COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+				COLLIE_SCP_5VON | \
 				COLLIE_SCP_LB_VOL_CHG)
 #define COLLIE_SCOOP_IO_OUT	(COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
 
@@ -81,7 +81,7 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_TBL_CHK     UCB_IO_1
 #define COLLIE_TC35143_GPIO_VPEN_ON     UCB_IO_2
 #define COLLIE_GPIO_IR_ON		(COLLIE_TC35143_GPIO_BASE + 3)
-#define COLLIE_TC35143_GPIO_AMP_ON      UCB_IO_4
+#define COLLIE_GPIO_AMP1_ON		(COLLIE_TC35143_GPIO_BASE + 4)
 #define COLLIE_TC35143_GPIO_VERSION1    UCB_IO_5
 #define COLLIE_TC35143_GPIO_FS8KLPF     UCB_IO_5
 #define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
@@ -92,4 +92,23 @@ extern void locomolcd_power(int on);
 #define COLLIE_TC35143_GPIO_OUT		(UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
 						| UCB_IO_6)
 
+/* GPIOs on LoCoMo GA */
+#define COLLIE_LOCOMO_GPIO_BASE		(GPIO_MAX + 23)
+#define COLLIE_GPIO_RTS			(COLLIE_LOCOMO_GPIO_BASE + 0)
+#define COLLIE_GPIO_CTS			(COLLIE_LOCOMO_GPIO_BASE + 1)
+#define COLLIE_GPIO_DSR			(COLLIE_LOCOMO_GPIO_BASE + 2)
+#define COLLIE_GPIO_DTR			(COLLIE_LOCOMO_GPIO_BASE + 3)
+#define COLLIE_GPIO_LCD_VSHA_ON		(COLLIE_LOCOMO_GPIO_BASE + 4)
+#define COLLIE_GPIO_LCD_VSHD_ON		(COLLIE_LOCOMO_GPIO_BASE + 5)
+#define COLLIE_GPIO_LCD_VEE_ON		(COLLIE_LOCOMO_GPIO_BASE + 6)
+#define COLLIE_GPIO_LCD_MOD		(COLLIE_LOCOMO_GPIO_BASE + 7)
+#define COLLIE_LOCOMO_GPIO_DAC_ON	LOCOMO_GPIO(8)
+#define COLLIE_GPIO_FL_VR		(COLLIE_LOCOMO_GPIO_BASE + 9)
+#define COLLIE_LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
+#define COLLIE_LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
+#define COLLIE_LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
+#define COLLIE_GPIO_CARD_DETECT		(COLLIE_LOCOMO_GPIO_BASE + 13)
+#define COLLIE_GPIO_CARD_RO		(COLLIE_LOCOMO_GPIO_BASE + 14)
+#define COLLIE_GPIO_CARD_POWER		(COLLIE_LOCOMO_GPIO_BASE + 15)
+
 #endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 12/17] ARM: sa1100: don't preallocate IRQ space for locomo
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

As new locomo driver properly supports SPARSE_IRQ, stop playing with
NR_IRQS on sa1100 (locomo was the last chip requiring NR_IRQ tricks).

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/include/mach/irqs.h | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 734e30e..b4b9608 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -79,22 +79,7 @@
 #define IRQ_BOARD_START		61
 #define IRQ_BOARD_END		77
 
-/*
- * Figure out the MAX IRQ number.
- *
- * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
- * allocate their IRQs above NR_IRQS.
- *
- * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
- * to be included in the NR_IRQS calculation.
- */
-#ifdef CONFIG_SHARP_LOCOMO
-#define NR_IRQS_LOCOMO		4
-#else
-#define NR_IRQS_LOCOMO		0
-#endif
-
 #ifndef NR_IRQS
-#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define NR_IRQS IRQ_BOARD_START
 #endif
-#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define SA1100_NR_IRQS IRQ_BOARD_START
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 12/17] ARM: sa1100: don't preallocate IRQ space for locomo
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

As new locomo driver properly supports SPARSE_IRQ, stop playing with
NR_IRQS on sa1100 (locomo was the last chip requiring NR_IRQ tricks).

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/include/mach/irqs.h | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 734e30e..b4b9608 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -79,22 +79,7 @@
 #define IRQ_BOARD_START		61
 #define IRQ_BOARD_END		77
 
-/*
- * Figure out the MAX IRQ number.
- *
- * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
- * allocate their IRQs above NR_IRQS.
- *
- * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
- * to be included in the NR_IRQS calculation.
- */
-#ifdef CONFIG_SHARP_LOCOMO
-#define NR_IRQS_LOCOMO		4
-#else
-#define NR_IRQS_LOCOMO		0
-#endif
-
 #ifndef NR_IRQS
-#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define NR_IRQS IRQ_BOARD_START
 #endif
-#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define SA1100_NR_IRQS IRQ_BOARD_START
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 12/17] ARM: sa1100: don't preallocate IRQ space for locomo
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

As new locomo driver properly supports SPARSE_IRQ, stop playing with
NR_IRQS on sa1100 (locomo was the last chip requiring NR_IRQ tricks).

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/include/mach/irqs.h | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 734e30e..b4b9608 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -79,22 +79,7 @@
 #define IRQ_BOARD_START		61
 #define IRQ_BOARD_END		77
 
-/*
- * Figure out the MAX IRQ number.
- *
- * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
- * allocate their IRQs above NR_IRQS.
- *
- * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
- * to be included in the NR_IRQS calculation.
- */
-#ifdef CONFIG_SHARP_LOCOMO
-#define NR_IRQS_LOCOMO		4
-#else
-#define NR_IRQS_LOCOMO		0
-#endif
-
 #ifndef NR_IRQS
-#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define NR_IRQS IRQ_BOARD_START
 #endif
-#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#define SA1100_NR_IRQS IRQ_BOARD_START
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Since LoCoMo driver has been converted to provide proper gpiolib
interface, make poodle ASoC platform driver use gpiolib API.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/pxa/poodle.c | 52 +++++++++++++++++++-------------------------------
 1 file changed, 20 insertions(+), 32 deletions(-)

diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 0fce8c4..c5b7c5e 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -20,15 +20,11 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 
-#include <asm/mach-types.h>
-#include <asm/hardware/locomo.h>
-#include <mach/poodle.h>
-#include <mach/audio.h>
-
 #include "../codecs/wm8731.h"
 #include "pxa2xx-i2s.h"
 
@@ -42,22 +38,18 @@
 
 static int poodle_jack_func;
 static int poodle_spk_func;
+static struct gpio_desc *poodle_mute_l, *poodle_mute_r, *poodle_amp_on;
 
 static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
 {
 	/* set up jack connection */
 	if (poodle_jack_func == POODLE_HP) {
-		/* set = unmute headphone */
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 1);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 1);
+		gpiod_set_value(poodle_mute_l, 0);
+		gpiod_set_value(poodle_mute_r, 0);
 		snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
 	} else {
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 0);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 0);
+		gpiod_set_value(poodle_mute_l, 1);
+		gpiod_set_value(poodle_mute_r, 1);
 		snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
 	}
 
@@ -84,11 +76,8 @@ static int poodle_startup(struct snd_pcm_substream *substream)
 /* we need to unmute the HP at shutdown as the mute burns power on poodle */
 static void poodle_shutdown(struct snd_pcm_substream *substream)
 {
-	/* set = unmute headphone */
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 1);
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 1);
+	gpiod_set_value(poodle_mute_l, 0);
+	gpiod_set_value(poodle_mute_r, 0);
 }
 
 static int poodle_hw_params(struct snd_pcm_substream *substream,
@@ -178,12 +167,7 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol,
 static int poodle_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	else
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 1);
+	gpiod_set_value(poodle_amp_on, (SND_SOC_DAPM_EVENT_ON(event)));
 
 	return 0;
 }
@@ -268,13 +252,17 @@ static int poodle_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &poodle;
 	int ret;
 
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	/* should we mute HP at startup - burning power ?*/
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 0);
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 0);
+	poodle_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_l))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_r))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_amp_on = devm_gpiod_get(&pdev->dev, "amp-on", GPIOD_OUT_LOW);
+	if (IS_ERR(poodle_amp_on))
+		return PTR_ERR(poodle_amp_on);
 
 	card->dev = &pdev->dev;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Since LoCoMo driver has been converted to provide proper gpiolib
interface, make poodle ASoC platform driver use gpiolib API.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/pxa/poodle.c | 52 +++++++++++++++++++-------------------------------
 1 file changed, 20 insertions(+), 32 deletions(-)

diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 0fce8c4..c5b7c5e 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -20,15 +20,11 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 
-#include <asm/mach-types.h>
-#include <asm/hardware/locomo.h>
-#include <mach/poodle.h>
-#include <mach/audio.h>
-
 #include "../codecs/wm8731.h"
 #include "pxa2xx-i2s.h"
 
@@ -42,22 +38,18 @@
 
 static int poodle_jack_func;
 static int poodle_spk_func;
+static struct gpio_desc *poodle_mute_l, *poodle_mute_r, *poodle_amp_on;
 
 static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
 {
 	/* set up jack connection */
 	if (poodle_jack_func = POODLE_HP) {
-		/* set = unmute headphone */
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 1);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 1);
+		gpiod_set_value(poodle_mute_l, 0);
+		gpiod_set_value(poodle_mute_r, 0);
 		snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
 	} else {
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 0);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 0);
+		gpiod_set_value(poodle_mute_l, 1);
+		gpiod_set_value(poodle_mute_r, 1);
 		snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
 	}
 
@@ -84,11 +76,8 @@ static int poodle_startup(struct snd_pcm_substream *substream)
 /* we need to unmute the HP at shutdown as the mute burns power on poodle */
 static void poodle_shutdown(struct snd_pcm_substream *substream)
 {
-	/* set = unmute headphone */
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 1);
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 1);
+	gpiod_set_value(poodle_mute_l, 0);
+	gpiod_set_value(poodle_mute_r, 0);
 }
 
 static int poodle_hw_params(struct snd_pcm_substream *substream,
@@ -178,12 +167,7 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol,
 static int poodle_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	else
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 1);
+	gpiod_set_value(poodle_amp_on, (SND_SOC_DAPM_EVENT_ON(event)));
 
 	return 0;
 }
@@ -268,13 +252,17 @@ static int poodle_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &poodle;
 	int ret;
 
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	/* should we mute HP at startup - burning power ?*/
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 0);
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 0);
+	poodle_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_l))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_r))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_amp_on = devm_gpiod_get(&pdev->dev, "amp-on", GPIOD_OUT_LOW);
+	if (IS_ERR(poodle_amp_on))
+		return PTR_ERR(poodle_amp_on);
 
 	card->dev = &pdev->dev;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Since LoCoMo driver has been converted to provide proper gpiolib
interface, make poodle ASoC platform driver use gpiolib API.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/pxa/poodle.c | 52 +++++++++++++++++++-------------------------------
 1 file changed, 20 insertions(+), 32 deletions(-)

diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 0fce8c4..c5b7c5e 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -20,15 +20,11 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio/consumer.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 
-#include <asm/mach-types.h>
-#include <asm/hardware/locomo.h>
-#include <mach/poodle.h>
-#include <mach/audio.h>
-
 #include "../codecs/wm8731.h"
 #include "pxa2xx-i2s.h"
 
@@ -42,22 +38,18 @@
 
 static int poodle_jack_func;
 static int poodle_spk_func;
+static struct gpio_desc *poodle_mute_l, *poodle_mute_r, *poodle_amp_on;
 
 static void poodle_ext_control(struct snd_soc_dapm_context *dapm)
 {
 	/* set up jack connection */
 	if (poodle_jack_func == POODLE_HP) {
-		/* set = unmute headphone */
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 1);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 1);
+		gpiod_set_value(poodle_mute_l, 0);
+		gpiod_set_value(poodle_mute_r, 0);
 		snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
 	} else {
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_L, 0);
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_MUTE_R, 0);
+		gpiod_set_value(poodle_mute_l, 1);
+		gpiod_set_value(poodle_mute_r, 1);
 		snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
 	}
 
@@ -84,11 +76,8 @@ static int poodle_startup(struct snd_pcm_substream *substream)
 /* we need to unmute the HP at shutdown as the mute burns power on poodle */
 static void poodle_shutdown(struct snd_pcm_substream *substream)
 {
-	/* set = unmute headphone */
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 1);
-	locomo_gpio_write(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 1);
+	gpiod_set_value(poodle_mute_l, 0);
+	gpiod_set_value(poodle_mute_r, 0);
 }
 
 static int poodle_hw_params(struct snd_pcm_substream *substream,
@@ -178,12 +167,7 @@ static int poodle_set_spk(struct snd_kcontrol *kcontrol,
 static int poodle_amp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	else
-		locomo_gpio_write(&poodle_locomo_device.dev,
-			POODLE_LOCOMO_GPIO_AMP_ON, 1);
+	gpiod_set_value(poodle_amp_on, (SND_SOC_DAPM_EVENT_ON(event)));
 
 	return 0;
 }
@@ -268,13 +252,17 @@ static int poodle_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &poodle;
 	int ret;
 
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_AMP_ON, 0);
-	/* should we mute HP at startup - burning power ?*/
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_L, 0);
-	locomo_gpio_set_dir(&poodle_locomo_device.dev,
-		POODLE_LOCOMO_GPIO_MUTE_R, 0);
+	poodle_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_l))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_HIGH);
+	if (IS_ERR(poodle_mute_r))
+		return PTR_ERR(poodle_mute_l);
+
+	poodle_amp_on = devm_gpiod_get(&pdev->dev, "amp-on", GPIOD_OUT_LOW);
+	if (IS_ERR(poodle_amp_on))
+		return PTR_ERR(poodle_amp_on);
 
 	card->dev = &pdev->dev;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Convert poodle to use new mfd-based LoCoMo driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/Kconfig               |  1 -
 arch/arm/mach-pxa/include/mach/poodle.h | 16 ++++++---
 arch/arm/mach-pxa/poodle.c              | 58 ++++++++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 8896e71..a2756b0 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -481,7 +481,6 @@ config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends on PXA_SHARPSL
 	select PXA25x
-	select SHARP_LOCOMO
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index b56b193..dd4afae 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -81,11 +81,17 @@
 #define POODLE_GPIO_L_LCLK	(POODLE_SCOOP_GPIO_BASE + 10)
 #define POODLE_GPIO_HS_OUT	(POODLE_SCOOP_GPIO_BASE + 11)
 
-#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
-#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
-#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
-#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
-#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
+#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
+#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
+#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
+#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
+#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
+#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
+#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
+#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
+#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
+#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
+#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
 #define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 195b112..a61e4b8 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/regulator/machine.h>
@@ -31,6 +32,8 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mtd/sharpsl.h>
 #include <linux/memblock.h>
+#include <linux/iio/machine.h>
+#include <linux/mfd/locomo.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -49,7 +52,6 @@
 #include <linux/platform_data/video-pxafb.h>
 
 #include <asm/hardware/scoop.h>
-#include <asm/hardware/locomo.h>
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
@@ -179,7 +181,8 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base	  = POODLE_LOCOMO_GPIO_BASE,
+	.comadj	          = 118,
 };
 
 struct platform_device poodle_locomo_device = {
@@ -192,8 +195,6 @@ struct platform_device poodle_locomo_device = {
 	},
 };
 
-EXPORT_SYMBOL(poodle_locomo_device);
-
 #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
 static struct pxa2xx_spi_master poodle_spi_info = {
 	.num_chipselect	= 1,
@@ -424,6 +425,47 @@ static struct i2c_board_info __initdata poodle_i2c_devices[] = {
 	{ I2C_BOARD_INFO("wm8731", 0x1b) },
 };
 
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table poodle_audio_gpios_table = {
+	.dev_id = "poodle-audio",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
+		{ },
+	},
+}, poodle_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, poodle_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void poodle_poweroff(void)
 {
 	pxa_restart(REBOOT_HARD, NULL);
@@ -445,6 +487,13 @@ static void __init poodle_init(void)
 
 	platform_scoop_config = &poodle_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&poodle_audio_gpios_table);
+	gpiod_add_lookup_table(&poodle_bl_gpios_table);
+	gpiod_add_lookup_table(&poodle_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret)
 		pr_warn("poodle: Unable to register LoCoMo device\n");
@@ -455,6 +504,7 @@ static void __init poodle_init(void)
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
+	i2c_register_board_info(1, ARRAY_AND_SIZE(locomo_i2c_devs));
 	poodle_init_spi();
 	regulator_has_full_constraints();
 }
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Convert poodle to use new mfd-based LoCoMo driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/Kconfig               |  1 -
 arch/arm/mach-pxa/include/mach/poodle.h | 16 ++++++---
 arch/arm/mach-pxa/poodle.c              | 58 ++++++++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 8896e71..a2756b0 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -481,7 +481,6 @@ config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends on PXA_SHARPSL
 	select PXA25x
-	select SHARP_LOCOMO
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index b56b193..dd4afae 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -81,11 +81,17 @@
 #define POODLE_GPIO_L_LCLK	(POODLE_SCOOP_GPIO_BASE + 10)
 #define POODLE_GPIO_HS_OUT	(POODLE_SCOOP_GPIO_BASE + 11)
 
-#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
-#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
-#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
-#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
-#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
+#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
+#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
+#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
+#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
+#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
+#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
+#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
+#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
+#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
+#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
+#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
 #define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 195b112..a61e4b8 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/regulator/machine.h>
@@ -31,6 +32,8 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mtd/sharpsl.h>
 #include <linux/memblock.h>
+#include <linux/iio/machine.h>
+#include <linux/mfd/locomo.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -49,7 +52,6 @@
 #include <linux/platform_data/video-pxafb.h>
 
 #include <asm/hardware/scoop.h>
-#include <asm/hardware/locomo.h>
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
@@ -179,7 +181,8 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base	  = POODLE_LOCOMO_GPIO_BASE,
+	.comadj	          = 118,
 };
 
 struct platform_device poodle_locomo_device = {
@@ -192,8 +195,6 @@ struct platform_device poodle_locomo_device = {
 	},
 };
 
-EXPORT_SYMBOL(poodle_locomo_device);
-
 #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
 static struct pxa2xx_spi_master poodle_spi_info = {
 	.num_chipselect	= 1,
@@ -424,6 +425,47 @@ static struct i2c_board_info __initdata poodle_i2c_devices[] = {
 	{ I2C_BOARD_INFO("wm8731", 0x1b) },
 };
 
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table poodle_audio_gpios_table = {
+	.dev_id = "poodle-audio",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
+		{ },
+	},
+}, poodle_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, poodle_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void poodle_poweroff(void)
 {
 	pxa_restart(REBOOT_HARD, NULL);
@@ -445,6 +487,13 @@ static void __init poodle_init(void)
 
 	platform_scoop_config = &poodle_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&poodle_audio_gpios_table);
+	gpiod_add_lookup_table(&poodle_bl_gpios_table);
+	gpiod_add_lookup_table(&poodle_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret)
 		pr_warn("poodle: Unable to register LoCoMo device\n");
@@ -455,6 +504,7 @@ static void __init poodle_init(void)
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
+	i2c_register_board_info(1, ARRAY_AND_SIZE(locomo_i2c_devs));
 	poodle_init_spi();
 	regulator_has_full_constraints();
 }
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Convert poodle to use new mfd-based LoCoMo driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/Kconfig               |  1 -
 arch/arm/mach-pxa/include/mach/poodle.h | 16 ++++++---
 arch/arm/mach-pxa/poodle.c              | 58 ++++++++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 8896e71..a2756b0 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -481,7 +481,6 @@ config MACH_POODLE
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends on PXA_SHARPSL
 	select PXA25x
-	select SHARP_LOCOMO
 
 config MACH_CORGI
 	bool "Enable Sharp SL-C700 (Corgi) Support"
diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index b56b193..dd4afae 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -81,11 +81,17 @@
 #define POODLE_GPIO_L_LCLK	(POODLE_SCOOP_GPIO_BASE + 10)
 #define POODLE_GPIO_HS_OUT	(POODLE_SCOOP_GPIO_BASE + 11)
 
-#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
-#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
-#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
-#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
-#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
+#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
+#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
+#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
+#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
+#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
+#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
+#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
+#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
+#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
+#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
+#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
 #define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 195b112..a61e4b8 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/physmap.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/regulator/machine.h>
@@ -31,6 +32,8 @@
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mtd/sharpsl.h>
 #include <linux/memblock.h>
+#include <linux/iio/machine.h>
+#include <linux/mfd/locomo.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -49,7 +52,6 @@
 #include <linux/platform_data/video-pxafb.h>
 
 #include <asm/hardware/scoop.h>
-#include <asm/hardware/locomo.h>
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
@@ -179,7 +181,8 @@ static struct resource locomo_resources[] = {
 };
 
 static struct locomo_platform_data locomo_info = {
-	.irq_base	= IRQ_BOARD_START,
+	.gpio_base	  = POODLE_LOCOMO_GPIO_BASE,
+	.comadj	          = 118,
 };
 
 struct platform_device poodle_locomo_device = {
@@ -192,8 +195,6 @@ struct platform_device poodle_locomo_device = {
 	},
 };
 
-EXPORT_SYMBOL(poodle_locomo_device);
-
 #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
 static struct pxa2xx_spi_master poodle_spi_info = {
 	.num_chipselect	= 1,
@@ -424,6 +425,47 @@ static struct i2c_board_info __initdata poodle_i2c_devices[] = {
 	{ I2C_BOARD_INFO("wm8731", 0x1b) },
 };
 
+static struct iio_map locomo_iio_map[] = {
+	{
+		.consumer_dev_name = "locomo-lcd.0",
+		.consumer_channel = "comadj",
+		.adc_channel_label = "CH0",
+	},
+	{ }
+};
+
+static struct i2c_board_info locomo_i2c_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("m62332", 0x4e),
+		.platform_data = locomo_iio_map,
+	},
+};
+
+static struct gpiod_lookup_table poodle_audio_gpios_table = {
+	.dev_id = "poodle-audio",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
+		{ },
+	},
+}, poodle_bl_gpios_table = {
+	.dev_id = "locomo-backlight.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 9, "flvr", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+}, poodle_lcd_gpios_table = {
+	.dev_id = "locomo-lcd.0",
+	.table = {
+		GPIO_LOOKUP("locomo-gpio", 4, "VSHA", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 5, "VSHD", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 6, "Vee", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("locomo-gpio", 7, "MOD", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
 static void poodle_poweroff(void)
 {
 	pxa_restart(REBOOT_HARD, NULL);
@@ -445,6 +487,13 @@ static void __init poodle_init(void)
 
 	platform_scoop_config = &poodle_pcmcia_config;
 
+	if (sharpsl_param.comadj != -1)
+		locomo_info.comadj = sharpsl_param.comadj;
+
+	gpiod_add_lookup_table(&poodle_audio_gpios_table);
+	gpiod_add_lookup_table(&poodle_bl_gpios_table);
+	gpiod_add_lookup_table(&poodle_lcd_gpios_table);
+
 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	if (ret)
 		pr_warn("poodle: Unable to register LoCoMo device\n");
@@ -455,6 +504,7 @@ static void __init poodle_init(void)
 	pxa_set_ficp_info(&poodle_ficp_platform_data);
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
+	i2c_register_board_info(1, ARRAY_AND_SIZE(locomo_i2c_devs));
 	poodle_init_spi();
 	regulator_has_full_constraints();
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
space for it on poodle.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/include/mach/poodle.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index dd4afae..1fdde6b 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -93,7 +93,7 @@
 #define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
 #define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
-#define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
+#define POODLE_NR_IRQS		IRQ_BOARD_START
 
 extern struct platform_device poodle_locomo_device;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
space for it on poodle.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/include/mach/poodle.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index dd4afae..1fdde6b 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -93,7 +93,7 @@
 #define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
 #define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
-#define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
+#define POODLE_NR_IRQS		IRQ_BOARD_START
 
 extern struct platform_device poodle_locomo_device;
 
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
space for it on poodle.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-pxa/include/mach/poodle.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-pxa/include/mach/poodle.h b/arch/arm/mach-pxa/include/mach/poodle.h
index dd4afae..1fdde6b 100644
--- a/arch/arm/mach-pxa/include/mach/poodle.h
+++ b/arch/arm/mach-pxa/include/mach/poodle.h
@@ -93,7 +93,7 @@
 #define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
 #define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
 
-#define POODLE_NR_IRQS		(IRQ_BOARD_START + 4)	/* 4 for LoCoMo */
+#define POODLE_NR_IRQS		IRQ_BOARD_START
 
 extern struct platform_device poodle_locomo_device;
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 16/17] video: backlight: drop old locomo bl/lcd driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Old locomolcd driver is now completely obsolete by new locomo_bl and
locomo_lcd drivers, so let's drop it.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/locomolcd.c | 255 ------------------------------------
 1 file changed, 255 deletions(-)
 delete mode 100644 drivers/video/backlight/locomolcd.c

diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
deleted file mode 100644
index 6c3ec42..0000000
--- a/drivers/video/backlight/locomolcd.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Backlight control code for Sharp Zaurus SL-5500
- *
- * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
- * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
- * GPL v2
- *
- * This driver assumes single CPU. That's okay, because collie is
- * slightly old hardware, and no one is going to retrofit second CPU to
- * old PDA.
- */
-
-/* LCD power functions */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-#include <asm/mach/sharpsl_param.h>
-#include <asm/mach-types.h>
-
-#include "../../../arch/arm/mach-sa1100/generic.h"
-
-static struct backlight_device *locomolcd_bl_device;
-static struct locomo_dev *locomolcd_dev;
-static unsigned long locomolcd_flags;
-#define LOCOMOLCD_SUSPENDED     0x01
-
-static void locomolcd_on(int comadj)
-{
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
-	mdelay(2);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
-	mdelay(2);
-
-	locomo_m62332_senddata(locomolcd_dev, comadj, 0);
-	mdelay(5);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
-	mdelay(10);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
-
-	/* Set CPSD */
-	locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(10);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
-}
-
-static void locomolcd_off(int comadj)
-{
-	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
-	locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(1);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	mdelay(110);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	mdelay(700);
-
-	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
-	locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-}
-
-void locomolcd_power(int on)
-{
-	int comadj = sharpsl_param.comadj;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	if (!locomolcd_dev) {
-		local_irq_restore(flags);
-		return;
-	}
-
-	/* read comadj */
-	if (comadj == -1 && machine_is_collie())
-		comadj = 128;
-	if (comadj == -1 && machine_is_poodle())
-		comadj = 118;
-
-	if (on)
-		locomolcd_on(comadj);
-	else
-		locomolcd_off(comadj);
-
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(locomolcd_power);
-
-static int current_intensity;
-
-static int locomolcd_set_intensity(struct backlight_device *bd)
-{
-	int intensity = bd->props.brightness;
-
-	if (bd->props.power != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
-		intensity = 0;
-
-	switch (intensity) {
-	/*
-	 * AC and non-AC are handled differently,
-	 * but produce same results in sharp code?
-	 */
-	case 0:
-		locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
-		break;
-	case 1:
-		locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
-		break;
-	case 2:
-		locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
-		break;
-	case 3:
-		locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
-		break;
-	case 4:
-		locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
-		break;
-	default:
-		return -ENODEV;
-	}
-	current_intensity = intensity;
-	return 0;
-}
-
-static int locomolcd_get_intensity(struct backlight_device *bd)
-{
-	return current_intensity;
-}
-
-static const struct backlight_ops locomobl_data = {
-	.get_brightness = locomolcd_get_intensity,
-	.update_status  = locomolcd_set_intensity,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int locomolcd_suspend(struct device *dev)
-{
-	locomolcd_flags |= LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-
-static int locomolcd_resume(struct device *dev)
-{
-	locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
-
-static int locomolcd_probe(struct locomo_dev *ldev)
-{
-	struct backlight_properties props;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	locomolcd_dev = ldev;
-
-	locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
-	/*
-	 * the poodle_lcd_power function is called for the first time
-	 * from fs_initcall, which is before locomo is activated.
-	 * We need to recall poodle_lcd_power here
-	 */
-	if (machine_is_poodle())
-		locomolcd_power(1);
-
-	local_irq_restore(flags);
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.type = BACKLIGHT_RAW;
-	props.max_brightness = 4;
-	locomolcd_bl_device = backlight_device_register("locomo-bl",
-							&ldev->dev, NULL,
-							&locomobl_data, &props);
-
-	if (IS_ERR(locomolcd_bl_device))
-		return PTR_ERR(locomolcd_bl_device);
-
-	/* Set up frontlight so that screen is readable */
-	locomolcd_bl_device->props.brightness = 2;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	return 0;
-}
-
-static int locomolcd_remove(struct locomo_dev *dev)
-{
-	unsigned long flags;
-
-	locomolcd_bl_device->props.brightness = 0;
-	locomolcd_bl_device->props.power = 0;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	backlight_device_unregister(locomolcd_bl_device);
-	local_irq_save(flags);
-	locomolcd_dev = NULL;
-	local_irq_restore(flags);
-	return 0;
-}
-
-static struct locomo_driver poodle_lcd_driver = {
-	.drv = {
-		.name	= "locomo-backlight",
-		.pm	= &locomolcd_pm_ops,
-	},
-	.devid	= LOCOMO_DEVID_BACKLIGHT,
-	.probe	= locomolcd_probe,
-	.remove	= locomolcd_remove,
-};
-
-static int __init locomolcd_init(void)
-{
-	return locomo_driver_register(&poodle_lcd_driver);
-}
-
-static void __exit locomolcd_exit(void)
-{
-	locomo_driver_unregister(&poodle_lcd_driver);
-}
-
-module_init(locomolcd_init);
-module_exit(locomolcd_exit);
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
-MODULE_DESCRIPTION("Collie LCD driver");
-MODULE_LICENSE("GPL");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 16/17] video: backlight: drop old locomo bl/lcd driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

Old locomolcd driver is now completely obsolete by new locomo_bl and
locomo_lcd drivers, so let's drop it.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/locomolcd.c | 255 ------------------------------------
 1 file changed, 255 deletions(-)
 delete mode 100644 drivers/video/backlight/locomolcd.c

diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
deleted file mode 100644
index 6c3ec42..0000000
--- a/drivers/video/backlight/locomolcd.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Backlight control code for Sharp Zaurus SL-5500
- *
- * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
- * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
- * GPL v2
- *
- * This driver assumes single CPU. That's okay, because collie is
- * slightly old hardware, and no one is going to retrofit second CPU to
- * old PDA.
- */
-
-/* LCD power functions */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-#include <asm/mach/sharpsl_param.h>
-#include <asm/mach-types.h>
-
-#include "../../../arch/arm/mach-sa1100/generic.h"
-
-static struct backlight_device *locomolcd_bl_device;
-static struct locomo_dev *locomolcd_dev;
-static unsigned long locomolcd_flags;
-#define LOCOMOLCD_SUSPENDED     0x01
-
-static void locomolcd_on(int comadj)
-{
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
-	mdelay(2);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
-	mdelay(2);
-
-	locomo_m62332_senddata(locomolcd_dev, comadj, 0);
-	mdelay(5);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
-	mdelay(10);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
-
-	/* Set CPSD */
-	locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(10);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
-}
-
-static void locomolcd_off(int comadj)
-{
-	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
-	locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(1);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	mdelay(110);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	mdelay(700);
-
-	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
-	locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-}
-
-void locomolcd_power(int on)
-{
-	int comadj = sharpsl_param.comadj;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	if (!locomolcd_dev) {
-		local_irq_restore(flags);
-		return;
-	}
-
-	/* read comadj */
-	if (comadj = -1 && machine_is_collie())
-		comadj = 128;
-	if (comadj = -1 && machine_is_poodle())
-		comadj = 118;
-
-	if (on)
-		locomolcd_on(comadj);
-	else
-		locomolcd_off(comadj);
-
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(locomolcd_power);
-
-static int current_intensity;
-
-static int locomolcd_set_intensity(struct backlight_device *bd)
-{
-	int intensity = bd->props.brightness;
-
-	if (bd->props.power != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
-		intensity = 0;
-
-	switch (intensity) {
-	/*
-	 * AC and non-AC are handled differently,
-	 * but produce same results in sharp code?
-	 */
-	case 0:
-		locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
-		break;
-	case 1:
-		locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
-		break;
-	case 2:
-		locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
-		break;
-	case 3:
-		locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
-		break;
-	case 4:
-		locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
-		break;
-	default:
-		return -ENODEV;
-	}
-	current_intensity = intensity;
-	return 0;
-}
-
-static int locomolcd_get_intensity(struct backlight_device *bd)
-{
-	return current_intensity;
-}
-
-static const struct backlight_ops locomobl_data = {
-	.get_brightness = locomolcd_get_intensity,
-	.update_status  = locomolcd_set_intensity,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int locomolcd_suspend(struct device *dev)
-{
-	locomolcd_flags |= LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-
-static int locomolcd_resume(struct device *dev)
-{
-	locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
-
-static int locomolcd_probe(struct locomo_dev *ldev)
-{
-	struct backlight_properties props;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	locomolcd_dev = ldev;
-
-	locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
-	/*
-	 * the poodle_lcd_power function is called for the first time
-	 * from fs_initcall, which is before locomo is activated.
-	 * We need to recall poodle_lcd_power here
-	 */
-	if (machine_is_poodle())
-		locomolcd_power(1);
-
-	local_irq_restore(flags);
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.type = BACKLIGHT_RAW;
-	props.max_brightness = 4;
-	locomolcd_bl_device = backlight_device_register("locomo-bl",
-							&ldev->dev, NULL,
-							&locomobl_data, &props);
-
-	if (IS_ERR(locomolcd_bl_device))
-		return PTR_ERR(locomolcd_bl_device);
-
-	/* Set up frontlight so that screen is readable */
-	locomolcd_bl_device->props.brightness = 2;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	return 0;
-}
-
-static int locomolcd_remove(struct locomo_dev *dev)
-{
-	unsigned long flags;
-
-	locomolcd_bl_device->props.brightness = 0;
-	locomolcd_bl_device->props.power = 0;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	backlight_device_unregister(locomolcd_bl_device);
-	local_irq_save(flags);
-	locomolcd_dev = NULL;
-	local_irq_restore(flags);
-	return 0;
-}
-
-static struct locomo_driver poodle_lcd_driver = {
-	.drv = {
-		.name	= "locomo-backlight",
-		.pm	= &locomolcd_pm_ops,
-	},
-	.devid	= LOCOMO_DEVID_BACKLIGHT,
-	.probe	= locomolcd_probe,
-	.remove	= locomolcd_remove,
-};
-
-static int __init locomolcd_init(void)
-{
-	return locomo_driver_register(&poodle_lcd_driver);
-}
-
-static void __exit locomolcd_exit(void)
-{
-	locomo_driver_unregister(&poodle_lcd_driver);
-}
-
-module_init(locomolcd_init);
-module_exit(locomolcd_exit);
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
-MODULE_DESCRIPTION("Collie LCD driver");
-MODULE_LICENSE("GPL");
-- 
2.1.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 16/17] video: backlight: drop old locomo bl/lcd driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

Old locomolcd driver is now completely obsolete by new locomo_bl and
locomo_lcd drivers, so let's drop it.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/video/backlight/locomolcd.c | 255 ------------------------------------
 1 file changed, 255 deletions(-)
 delete mode 100644 drivers/video/backlight/locomolcd.c

diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c
deleted file mode 100644
index 6c3ec42..0000000
--- a/drivers/video/backlight/locomolcd.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Backlight control code for Sharp Zaurus SL-5500
- *
- * Copyright 2005 John Lenz <lenz@cs.wisc.edu>
- * Maintainer: Pavel Machek <pavel@ucw.cz> (unless John wants to :-)
- * GPL v2
- *
- * This driver assumes single CPU. That's okay, because collie is
- * slightly old hardware, and no one is going to retrofit second CPU to
- * old PDA.
- */
-
-/* LCD power functions */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-
-#include <asm/hardware/locomo.h>
-#include <asm/irq.h>
-#include <asm/mach/sharpsl_param.h>
-#include <asm/mach-types.h>
-
-#include "../../../arch/arm/mach-sa1100/generic.h"
-
-static struct backlight_device *locomolcd_bl_device;
-static struct locomo_dev *locomolcd_dev;
-static unsigned long locomolcd_flags;
-#define LOCOMOLCD_SUSPENDED     0x01
-
-static void locomolcd_on(int comadj)
-{
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 1);
-	mdelay(2);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 1);
-	mdelay(2);
-
-	locomo_m62332_senddata(locomolcd_dev, comadj, 0);
-	mdelay(5);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 1);
-	mdelay(10);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel(0x01, locomolcd_dev->mapbase + LOCOMO_TC);
-
-	/* Set CPSD */
-	locomo_writel(6, locomolcd_dev->mapbase + LOCOMO_CPSD);
-
-	/* TFTCRST | CPSOUT=0 | CPSEN */
-	locomo_writel((0x04 | 0x01), locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(10);
-
-	locomo_gpio_set_dir(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 1);
-}
-
-static void locomolcd_off(int comadj)
-{
-	/* TFTCRST=1 | CPSOUT=1 | CPSEN = 0 */
-	locomo_writel(0x06, locomolcd_dev->mapbase + LOCOMO_TC);
-	mdelay(1);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHA_ON, 0);
-	mdelay(110);
-
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VEE_ON, 0);
-	mdelay(700);
-
-	/* TFTCRST=0 | CPSOUT=0 | CPSEN = 0 */
-	locomo_writel(0, locomolcd_dev->mapbase + LOCOMO_TC);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_MOD, 0);
-	locomo_gpio_write(locomolcd_dev->dev.parent, LOCOMO_GPIO_LCD_VSHD_ON, 0);
-}
-
-void locomolcd_power(int on)
-{
-	int comadj = sharpsl_param.comadj;
-	unsigned long flags;
-
-	local_irq_save(flags);
-
-	if (!locomolcd_dev) {
-		local_irq_restore(flags);
-		return;
-	}
-
-	/* read comadj */
-	if (comadj == -1 && machine_is_collie())
-		comadj = 128;
-	if (comadj == -1 && machine_is_poodle())
-		comadj = 118;
-
-	if (on)
-		locomolcd_on(comadj);
-	else
-		locomolcd_off(comadj);
-
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(locomolcd_power);
-
-static int current_intensity;
-
-static int locomolcd_set_intensity(struct backlight_device *bd)
-{
-	int intensity = bd->props.brightness;
-
-	if (bd->props.power != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
-		intensity = 0;
-	if (locomolcd_flags & LOCOMOLCD_SUSPENDED)
-		intensity = 0;
-
-	switch (intensity) {
-	/*
-	 * AC and non-AC are handled differently,
-	 * but produce same results in sharp code?
-	 */
-	case 0:
-		locomo_frontlight_set(locomolcd_dev, 0, 0, 161);
-		break;
-	case 1:
-		locomo_frontlight_set(locomolcd_dev, 117, 0, 161);
-		break;
-	case 2:
-		locomo_frontlight_set(locomolcd_dev, 163, 0, 148);
-		break;
-	case 3:
-		locomo_frontlight_set(locomolcd_dev, 194, 0, 161);
-		break;
-	case 4:
-		locomo_frontlight_set(locomolcd_dev, 194, 1, 161);
-		break;
-	default:
-		return -ENODEV;
-	}
-	current_intensity = intensity;
-	return 0;
-}
-
-static int locomolcd_get_intensity(struct backlight_device *bd)
-{
-	return current_intensity;
-}
-
-static const struct backlight_ops locomobl_data = {
-	.get_brightness = locomolcd_get_intensity,
-	.update_status  = locomolcd_set_intensity,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int locomolcd_suspend(struct device *dev)
-{
-	locomolcd_flags |= LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-
-static int locomolcd_resume(struct device *dev)
-{
-	locomolcd_flags &= ~LOCOMOLCD_SUSPENDED;
-	locomolcd_set_intensity(locomolcd_bl_device);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(locomolcd_pm_ops, locomolcd_suspend, locomolcd_resume);
-
-static int locomolcd_probe(struct locomo_dev *ldev)
-{
-	struct backlight_properties props;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	locomolcd_dev = ldev;
-
-	locomo_gpio_set_dir(ldev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
-	/*
-	 * the poodle_lcd_power function is called for the first time
-	 * from fs_initcall, which is before locomo is activated.
-	 * We need to recall poodle_lcd_power here
-	 */
-	if (machine_is_poodle())
-		locomolcd_power(1);
-
-	local_irq_restore(flags);
-
-	memset(&props, 0, sizeof(struct backlight_properties));
-	props.type = BACKLIGHT_RAW;
-	props.max_brightness = 4;
-	locomolcd_bl_device = backlight_device_register("locomo-bl",
-							&ldev->dev, NULL,
-							&locomobl_data, &props);
-
-	if (IS_ERR(locomolcd_bl_device))
-		return PTR_ERR(locomolcd_bl_device);
-
-	/* Set up frontlight so that screen is readable */
-	locomolcd_bl_device->props.brightness = 2;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	return 0;
-}
-
-static int locomolcd_remove(struct locomo_dev *dev)
-{
-	unsigned long flags;
-
-	locomolcd_bl_device->props.brightness = 0;
-	locomolcd_bl_device->props.power = 0;
-	locomolcd_set_intensity(locomolcd_bl_device);
-
-	backlight_device_unregister(locomolcd_bl_device);
-	local_irq_save(flags);
-	locomolcd_dev = NULL;
-	local_irq_restore(flags);
-	return 0;
-}
-
-static struct locomo_driver poodle_lcd_driver = {
-	.drv = {
-		.name	= "locomo-backlight",
-		.pm	= &locomolcd_pm_ops,
-	},
-	.devid	= LOCOMO_DEVID_BACKLIGHT,
-	.probe	= locomolcd_probe,
-	.remove	= locomolcd_remove,
-};
-
-static int __init locomolcd_init(void)
-{
-	return locomo_driver_register(&poodle_lcd_driver);
-}
-
-static void __exit locomolcd_exit(void)
-{
-	locomo_driver_unregister(&poodle_lcd_driver);
-}
-
-module_init(locomolcd_init);
-module_exit(locomolcd_exit);
-
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>, Pavel Machek <pavel@ucw.cz>");
-MODULE_DESCRIPTION("Collie LCD driver");
-MODULE_LICENSE("GPL");
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 17/17] ARM: drop old LoCoMo driver
  2015-04-27 23:55 ` Dmitry Eremin-Solenikov
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami
  Cc: linux-arm-kernel, linux-gpio, linux-i2c, linux-input, linux-leds,
	linux-spi, linux-fbdev, alsa-devel

As there are no in-kernel users of old locomo driver, drop all
alltogether. Remove Kconfig entry, driver and header.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/common/Kconfig                |   3 -
 arch/arm/common/Makefile               |   1 -
 arch/arm/common/locomo.c               | 914 ---------------------------------
 arch/arm/include/asm/hardware/locomo.h | 221 --------
 4 files changed, 1139 deletions(-)
 delete mode 100644 arch/arm/common/locomo.c
 delete mode 100644 arch/arm/include/asm/hardware/locomo.h

diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index c3a4e9c..76c9970 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -9,9 +9,6 @@ config DMABOUNCE
 	bool
 	select ZONE_DMA
 
-config SHARP_LOCOMO
-	bool
-
 config SHARP_PARAM
 	bool
 
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 70b1eff..437c79a 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -7,7 +7,6 @@ obj-y				+= firmware.o
 obj-$(CONFIG_ICST)		+= icst.o
 obj-$(CONFIG_SA1111)		+= sa1111.o
 obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
-obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
deleted file mode 100644
index b55c362..0000000
--- a/arch/arm/common/locomo.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * linux/arch/arm/common/locomo.c
- *
- * Sharp LoCoMo support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file contains all generic LoCoMo support.
- *
- * All initialization functions provided here are intended to be called
- * from machine specific code with proper arguments when required.
- *
- * Based on sa1111.c
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware/locomo.h>
-
-/* LoCoMo Interrupts */
-#define IRQ_LOCOMO_KEY		(0)
-#define IRQ_LOCOMO_GPIO		(1)
-#define IRQ_LOCOMO_LT		(2)
-#define IRQ_LOCOMO_SPI		(3)
-
-/* M62332 output channel selection */
-#define M62332_EVR_CH	1	/* M62332 volume channel number  */
-				/*   0 : CH.1 , 1 : CH. 2        */
-/* DAC send data */
-#define	M62332_SLAVE_ADDR	0x4e	/* Slave address  */
-#define	M62332_W_BIT		0x00	/* W bit (0 only) */
-#define	M62332_SUB_ADDR		0x00	/* Sub address    */
-#define	M62332_A_BIT		0x00	/* A bit (0 only) */
-
-/* DAC setup and hold times (expressed in us) */
-#define DAC_BUS_FREE_TIME	5	/*   4.7 us */
-#define DAC_START_SETUP_TIME	5	/*   4.7 us */
-#define DAC_STOP_SETUP_TIME	4	/*   4.0 us */
-#define DAC_START_HOLD_TIME	5	/*   4.7 us */
-#define DAC_SCL_LOW_HOLD_TIME	5	/*   4.7 us */
-#define DAC_SCL_HIGH_HOLD_TIME	4	/*   4.0 us */
-#define DAC_DATA_SETUP_TIME	1	/*   250 ns */
-#define DAC_DATA_HOLD_TIME	1	/*   300 ns */
-#define DAC_LOW_SETUP_TIME	1	/*   300 ns */
-#define DAC_HIGH_SETUP_TIME	1	/*  1000 ns */
-
-/* the following is the overall data for the locomo chip */
-struct locomo {
-	struct device *dev;
-	unsigned long phys;
-	unsigned int irq;
-	int irq_base;
-	spinlock_t lock;
-	void __iomem *base;
-#ifdef CONFIG_PM
-	void *saved_state;
-#endif
-};
-
-struct locomo_dev_info {
-	unsigned long	offset;
-	unsigned long	length;
-	unsigned int	devid;
-	unsigned int	irq[1];
-	const char *	name;
-};
-
-/* All the locomo devices.  If offset is non-zero, the mapbase for the
- * locomo_dev will be set to the chip base plus offset.  If offset is
- * zero, then the mapbase for the locomo_dev will be set to zero.  An
- * offset of zero means the device only uses GPIOs or other helper
- * functions inside this file */
-static struct locomo_dev_info locomo_devices[] = {
-	{
-		.devid 		= LOCOMO_DEVID_KEYBOARD,
-		.irq		= { IRQ_LOCOMO_KEY },
-		.name		= "locomo-keyboard",
-		.offset		= LOCOMO_KEYBOARD,
-		.length		= 16,
-	},
-	{
-		.devid		= LOCOMO_DEVID_FRONTLIGHT,
-		.irq		= {},
-		.name		= "locomo-frontlight",
-		.offset		= LOCOMO_FRONTLIGHT,
-		.length		= 8,
-
-	},
-	{
-		.devid		= LOCOMO_DEVID_BACKLIGHT,
-		.irq		= {},
-		.name		= "locomo-backlight",
-		.offset		= LOCOMO_BACKLIGHT,
-		.length		= 8,
-	},
-	{
-		.devid		= LOCOMO_DEVID_AUDIO,
-		.irq		= {},
-		.name		= "locomo-audio",
-		.offset		= LOCOMO_AUDIO,
-		.length		= 4,
-	},
-	{
-		.devid		= LOCOMO_DEVID_LED,
-		.irq 		= {},
-		.name		= "locomo-led",
-		.offset		= LOCOMO_LED,
-		.length		= 8,
-	},
-	{
-		.devid		= LOCOMO_DEVID_UART,
-		.irq		= {},
-		.name		= "locomo-uart",
-		.offset		= 0,
-		.length		= 0,
-	},
-	{
-		.devid		= LOCOMO_DEVID_SPI,
-		.irq		= {},
-		.name		= "locomo-spi",
-		.offset		= LOCOMO_SPI,
-		.length		= 0x30,
-	},
-};
-
-static void locomo_handler(unsigned int irq, struct irq_desc *desc)
-{
-	struct locomo *lchip = irq_get_chip_data(irq);
-	int req, i;
-
-	/* Acknowledge the parent IRQ */
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-	/* check why this interrupt was generated */
-	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
-
-	if (req) {
-		/* generate the next interrupt(s) */
-		irq = lchip->irq_base;
-		for (i = 0; i <= 3; i++, irq++) {
-			if (req & (0x0100 << i)) {
-				generic_handle_irq(irq);
-			}
-
-		}
-	}
-}
-
-static void locomo_ack_irq(struct irq_data *d)
-{
-}
-
-static void locomo_mask_irq(struct irq_data *d)
-{
-	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
-	r &= ~(0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
-}
-
-static void locomo_unmask_irq(struct irq_data *d)
-{
-	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
-	r |= (0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
-}
-
-static struct irq_chip locomo_chip = {
-	.name		= "LOCOMO",
-	.irq_ack	= locomo_ack_irq,
-	.irq_mask	= locomo_mask_irq,
-	.irq_unmask	= locomo_unmask_irq,
-};
-
-static void locomo_setup_irq(struct locomo *lchip)
-{
-	int irq = lchip->irq_base;
-
-	/*
-	 * Install handler for IRQ_LOCOMO_HW.
-	 */
-	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
-	irq_set_chip_data(lchip->irq, lchip);
-	irq_set_chained_handler(lchip->irq, locomo_handler);
-
-	/* Install handlers for IRQ_LOCOMO_* */
-	for ( ; irq <= lchip->irq_base + 3; irq++) {
-		irq_set_chip_and_handler(irq, &locomo_chip, handle_level_irq);
-		irq_set_chip_data(irq, lchip);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-}
-
-
-static void locomo_dev_release(struct device *_dev)
-{
-	struct locomo_dev *dev = LOCOMO_DEV(_dev);
-
-	kfree(dev);
-}
-
-static int
-locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
-{
-	struct locomo_dev *dev;
-	int ret;
-
-	dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL);
-	if (!dev) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	/*
-	 * If the parent device has a DMA mask associated with it,
-	 * propagate it down to the children.
-	 */
-	if (lchip->dev->dma_mask) {
-		dev->dma_mask = *lchip->dev->dma_mask;
-		dev->dev.dma_mask = &dev->dma_mask;
-	}
-
-	dev_set_name(&dev->dev, "%s", info->name);
-	dev->devid	 = info->devid;
-	dev->dev.parent  = lchip->dev;
-	dev->dev.bus     = &locomo_bus_type;
-	dev->dev.release = locomo_dev_release;
-	dev->dev.coherent_dma_mask = lchip->dev->coherent_dma_mask;
-
-	if (info->offset)
-		dev->mapbase = lchip->base + info->offset;
-	else
-		dev->mapbase = 0;
-	dev->length = info->length;
-
-	dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
-			NO_IRQ : lchip->irq_base + info->irq[0];
-
-	ret = device_register(&dev->dev);
-	if (ret) {
- out:
-		kfree(dev);
-	}
-	return ret;
-}
-
-#ifdef CONFIG_PM
-
-struct locomo_save_data {
-	u16	LCM_GPO;
-	u16	LCM_SPICT;
-	u16	LCM_GPE;
-	u16	LCM_ASD;
-	u16	LCM_SPIMD;
-};
-
-static int locomo_suspend(struct platform_device *dev, pm_message_t state)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-	struct locomo_save_data *save;
-	unsigned long flags;
-
-	save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
-	if (!save)
-		return -ENOMEM;
-
-	lchip->saved_state = save;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
-	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);	/* SPI */
-	locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPE);
-	save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);	/* ADSTART */
-	locomo_writel(0x00, lchip->base + LOCOMO_ASD);
-	save->LCM_SPIMD   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);	/* SPI */
-	locomo_writel(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
-
-	locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
-	locomo_writel(0x00, lchip->base + LOCOMO_DAC);
-	locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
-
-	if ((locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88))
-		locomo_writel(0x00, lchip->base + LOCOMO_C32K); 	/* CLK32 off */
-	else
-		/* 18MHz already enabled, so no wait */
-		locomo_writel(0xc1, lchip->base + LOCOMO_C32K); 	/* CLK32 on */
-
-	locomo_writel(0x00, lchip->base + LOCOMO_TADC);		/* 18MHz clock off*/
-	locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC);			/* 22MHz/24MHz clock off */
-	locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);			/* FL */
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	return 0;
-}
-
-static int locomo_resume(struct platform_device *dev)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-	struct locomo_save_data *save;
-	unsigned long r;
-	unsigned long flags;
-
-	save = lchip->saved_state;
-	if (!save)
-		return 0;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
-	locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
-	locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
-	locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
-
-	locomo_writel(0x00, lchip->base + LOCOMO_C32K);
-	locomo_writel(0x90, lchip->base + LOCOMO_TADC);
-
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
-	r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	r &= 0xFEFF;
-	locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	lchip->saved_state = NULL;
-	kfree(save);
-
-	return 0;
-}
-#endif
-
-
-/**
- *	locomo_probe - probe for a single LoCoMo chip.
- *	@phys_addr: physical address of device.
- *
- *	Probe for a LoCoMo chip.  This must be called
- *	before any other locomo-specific code.
- *
- *	Returns:
- *	%-ENODEV	device not found.
- *	%-EBUSY		physical address already marked in-use.
- *	%0		successful.
- */
-static int
-__locomo_probe(struct device *me, struct resource *mem, int irq)
-{
-	struct locomo_platform_data *pdata = me->platform_data;
-	struct locomo *lchip;
-	unsigned long r;
-	int i, ret = -ENODEV;
-
-	lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL);
-	if (!lchip)
-		return -ENOMEM;
-
-	spin_lock_init(&lchip->lock);
-
-	lchip->dev = me;
-	dev_set_drvdata(lchip->dev, lchip);
-
-	lchip->phys = mem->start;
-	lchip->irq = irq;
-	lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
-
-	/*
-	 * Map the whole region.  This also maps the
-	 * registers for our children.
-	 */
-	lchip->base = ioremap(mem->start, PAGE_SIZE);
-	if (!lchip->base) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	/* locomo initialize */
-	locomo_writel(0, lchip->base + LOCOMO_ICR);
-	/* KEYBOARD */
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-
-	/* GPIO */
-	locomo_writel(0, lchip->base + LOCOMO_GPO);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPE);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPD);
-	locomo_writel(0, lchip->base + LOCOMO_GIE);
-
-	/* Frontlight */
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
-
-	/* Longtime timer */
-	locomo_writel(0, lchip->base + LOCOMO_LTINT);
-	/* SPI */
-	locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
-
-	locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
-	r = locomo_readl(lchip->base + LOCOMO_ASD);
-	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_ASD);
-
-	locomo_writel(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD);
-	r = locomo_readl(lchip->base + LOCOMO_HSD);
-	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_HSD);
-
-	locomo_writel(128 / 8, lchip->base + LOCOMO_HSC);
-
-	/* XON */
-	locomo_writel(0x80, lchip->base + LOCOMO_TADC);
-	udelay(1000);
-	/* CLK9MEN */
-	r = locomo_readl(lchip->base + LOCOMO_TADC);
-	r |= 0x10;
-	locomo_writel(r, lchip->base + LOCOMO_TADC);
-	udelay(100);
-
-	/* init DAC */
-	r = locomo_readl(lchip->base + LOCOMO_DAC);
-	r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, lchip->base + LOCOMO_DAC);
-
-	r = locomo_readl(lchip->base + LOCOMO_VER);
-	printk(KERN_INFO "LoCoMo Chip: %lu%lu\n", (r >> 8), (r & 0xff));
-
-	/*
-	 * The interrupt controller must be initialised before any
-	 * other device to ensure that the interrupts are available.
-	 */
-	if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
-		locomo_setup_irq(lchip);
-
-	for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
-		locomo_init_one_child(lchip, &locomo_devices[i]);
-	return 0;
-
- out:
-	kfree(lchip);
-	return ret;
-}
-
-static int locomo_remove_child(struct device *dev, void *data)
-{
-	device_unregister(dev);
-	return 0;
-} 
-
-static void __locomo_remove(struct locomo *lchip)
-{
-	device_for_each_child(lchip->dev, NULL, locomo_remove_child);
-
-	if (lchip->irq != NO_IRQ) {
-		irq_set_chained_handler(lchip->irq, NULL);
-		irq_set_handler_data(lchip->irq, NULL);
-	}
-
-	iounmap(lchip->base);
-	kfree(lchip);
-}
-
-static int locomo_probe(struct platform_device *dev)
-{
-	struct resource *mem;
-	int irq;
-
-	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (!mem)
-		return -EINVAL;
-	irq = platform_get_irq(dev, 0);
-	if (irq < 0)
-		return -ENXIO;
-
-	return __locomo_probe(&dev->dev, mem, irq);
-}
-
-static int locomo_remove(struct platform_device *dev)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-
-	if (lchip) {
-		__locomo_remove(lchip);
-		platform_set_drvdata(dev, NULL);
-	}
-
-	return 0;
-}
-
-/*
- *	Not sure if this should be on the system bus or not yet.
- *	We really want some way to register a system device at
- *	the per-machine level, and then have this driver pick
- *	up the registered devices.
- */
-static struct platform_driver locomo_device_driver = {
-	.probe		= locomo_probe,
-	.remove		= locomo_remove,
-#ifdef CONFIG_PM
-	.suspend	= locomo_suspend,
-	.resume		= locomo_resume,
-#endif
-	.driver		= {
-		.name	= "locomo",
-	},
-};
-
-/*
- *	Get the parent device driver (us) structure
- *	from a child function device
- */
-static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev)
-{
-	return (struct locomo *)dev_get_drvdata(ldev->dev.parent);
-}
-
-void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int r;
-
-	if (!lchip)
-		return;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPD);
-	if (dir)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPD);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPE);
-	if (dir)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPE);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_gpio_set_dir);
-
-int locomo_gpio_read_level(struct device *dev, unsigned int bits)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int ret;
-
-	if (!lchip)
-		return -ENODEV;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPL);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	ret &= bits;
-	return ret;
-}
-EXPORT_SYMBOL(locomo_gpio_read_level);
-
-int locomo_gpio_read_output(struct device *dev, unsigned int bits)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int ret;
-
-	if (!lchip)
-		return -ENODEV;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPO);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	ret &= bits;
-	return ret;
-}
-EXPORT_SYMBOL(locomo_gpio_read_output);
-
-void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int r;
-
-	if (!lchip)
-		return;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPO);
-	if (set)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPO);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_gpio_write);
-
-static void locomo_m62332_sendbit(void *mapbase, int bit)
-{
-	unsigned int r;
-
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-
-	if (bit & 1) {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
-		r |=  LOCOMO_DAC_SDAOEB;
-		locomo_writel(r, mapbase + LOCOMO_DAC);
-		udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	} else {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
-		r &=  ~(LOCOMO_DAC_SDAOEB);
-		locomo_writel(r, mapbase + LOCOMO_DAC);
-		udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	}
-
-	udelay(DAC_DATA_SETUP_TIME);	/* 250 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/*  4.0 usec */
-}
-
-void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel)
-{
-	struct locomo *lchip = locomo_chip_driver(ldev);
-	int i;
-	unsigned char data;
-	unsigned int r;
-	void *mapbase = lchip->base;
-	unsigned long flags;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	/* Start */
-	udelay(DAC_BUS_FREE_TIME);	/* 5.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_START_HOLD_TIME);	/* 5.0 usec */
-	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
-
-	/* Send slave address and W bit (LSB is W bit) */
-	data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT;
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
-		goto out;
-	}
-
-	/* Send Sub address (LSB is channel select) */
-	/*    channel = 0 : ch1 select              */
-	/*            = 1 : ch2 select              */
-	data = M62332_SUB_ADDR + channel;
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
-		goto out;
-	}
-
-	/* Send DAC data */
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, dac_data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
-	}
-
-out:
-	/* stop */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
-
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_m62332_senddata);
-
-/*
- *	Frontlight control
- */
-
-void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
-{
-	unsigned long flags;
-	struct locomo *lchip = locomo_chip_driver(dev);
-
-	if (vr)
-		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);
-	else
-		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	udelay(100);
-	locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
-	locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_frontlight_set);
-
-/*
- *	LoCoMo "Register Access Bus."
- *
- *	We model this as a regular bus type, and hang devices directly
- *	off this.
- */
-static int locomo_match(struct device *_dev, struct device_driver *_drv)
-{
-	struct locomo_dev *dev = LOCOMO_DEV(_dev);
-	struct locomo_driver *drv = LOCOMO_DRV(_drv);
-
-	return dev->devid == drv->devid;
-}
-
-static int locomo_bus_suspend(struct device *dev, pm_message_t state)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv && drv->suspend)
-		ret = drv->suspend(ldev, state);
-	return ret;
-}
-
-static int locomo_bus_resume(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv && drv->resume)
-		ret = drv->resume(ldev);
-	return ret;
-}
-
-static int locomo_bus_probe(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = -ENODEV;
-
-	if (drv->probe)
-		ret = drv->probe(ldev);
-	return ret;
-}
-
-static int locomo_bus_remove(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv->remove)
-		ret = drv->remove(ldev);
-	return ret;
-}
-
-struct bus_type locomo_bus_type = {
-	.name		= "locomo-bus",
-	.match		= locomo_match,
-	.probe		= locomo_bus_probe,
-	.remove		= locomo_bus_remove,
-	.suspend	= locomo_bus_suspend,
-	.resume		= locomo_bus_resume,
-};
-
-int locomo_driver_register(struct locomo_driver *driver)
-{
-	driver->drv.bus = &locomo_bus_type;
-	return driver_register(&driver->drv);
-}
-EXPORT_SYMBOL(locomo_driver_register);
-
-void locomo_driver_unregister(struct locomo_driver *driver)
-{
-	driver_unregister(&driver->drv);
-}
-EXPORT_SYMBOL(locomo_driver_unregister);
-
-static int __init locomo_init(void)
-{
-	int ret = bus_register(&locomo_bus_type);
-	if (ret == 0)
-		platform_driver_register(&locomo_device_driver);
-	return ret;
-}
-
-static void __exit locomo_exit(void)
-{
-	platform_driver_unregister(&locomo_device_driver);
-	bus_unregister(&locomo_bus_type);
-}
-
-module_init(locomo_init);
-module_exit(locomo_exit);
-
-MODULE_DESCRIPTION("Sharp LoCoMo core driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
deleted file mode 100644
index 74e51d6b..0000000
--- a/arch/arm/include/asm/hardware/locomo.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/locomo.h
- *
- * This file contains the definitions for the LoCoMo G/A Chip
- *
- * (C) Copyright 2004 John Lenz
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Based on sa1111.h
- */
-#ifndef _ASM_ARCH_LOCOMO
-#define _ASM_ARCH_LOCOMO
-
-#define locomo_writel(val,addr)	({ *(volatile u16 *)(addr) = (val); })
-#define locomo_readl(addr)	(*(volatile u16 *)(addr))
-
-/* LOCOMO version */
-#define LOCOMO_VER	0x00
-
-/* Pin status */
-#define LOCOMO_ST	0x04
-
-/* Pin status */
-#define LOCOMO_C32K	0x08
-
-/* Interrupt controller */
-#define LOCOMO_ICR	0x0C
-
-/* MCS decoder for boot selecting */
-#define LOCOMO_MCSX0	0x10
-#define LOCOMO_MCSX1	0x14
-#define LOCOMO_MCSX2	0x18
-#define LOCOMO_MCSX3	0x1c
-
-/* Touch panel controller */
-#define LOCOMO_ASD	0x20		/* AD start delay */
-#define LOCOMO_HSD	0x28		/* HSYS delay */
-#define LOCOMO_HSC	0x2c		/* HSYS period */
-#define LOCOMO_TADC	0x30		/* tablet ADC clock */
-
-
-/* Long time timer */
-#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
-#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
-
-/* DAC control signal for LCD (COMADJ ) */
-#define LOCOMO_DAC		0xe0
-/* DAC control */
-#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
-#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
-#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
-#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
-
-/* SPI interface */
-#define LOCOMO_SPI	0x60
-#define LOCOMO_SPIMD	0x00		/* SPI mode setting */
-#define LOCOMO_SPICT	0x04		/* SPI mode control */
-#define LOCOMO_SPIST	0x08		/* SPI status */
-#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
-#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
-#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
-#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
-
-#define LOCOMO_SPIIS	0x10		/* SPI interrupt status */
-#define LOCOMO_SPIWE	0x14		/* SPI interrupt status write enable */
-#define LOCOMO_SPIIE	0x18		/* SPI interrupt enable */
-#define LOCOMO_SPIIR	0x1c		/* SPI interrupt request */
-#define LOCOMO_SPITD	0x20		/* SPI transfer data write */
-#define LOCOMO_SPIRD	0x24		/* SPI receive data read */
-#define LOCOMO_SPITS	0x28		/* SPI transfer data shift */
-#define LOCOMO_SPIRS	0x2C		/* SPI receive data shift */
-
-/* GPIO */
-#define LOCOMO_GPD		0x90	/* GPIO direction */
-#define LOCOMO_GPE		0x94	/* GPIO input enable */
-#define LOCOMO_GPL		0x98	/* GPIO level */
-#define LOCOMO_GPO		0x9c	/* GPIO out data setting */
-#define LOCOMO_GRIE		0xa0	/* GPIO rise detection */
-#define LOCOMO_GFIE		0xa4	/* GPIO fall detection */
-#define LOCOMO_GIS		0xa8	/* GPIO edge detection status */
-#define LOCOMO_GWE		0xac	/* GPIO status write enable */
-#define LOCOMO_GIE		0xb0	/* GPIO interrupt enable */
-#define LOCOMO_GIR		0xb4	/* GPIO interrupt request */
-#define	LOCOMO_GPIO(Nb)		(0x01 << (Nb))
-#define LOCOMO_GPIO_RTS		LOCOMO_GPIO(0)
-#define LOCOMO_GPIO_CTS		LOCOMO_GPIO(1)
-#define LOCOMO_GPIO_DSR		LOCOMO_GPIO(2)
-#define LOCOMO_GPIO_DTR		LOCOMO_GPIO(3)
-#define LOCOMO_GPIO_LCD_VSHA_ON	LOCOMO_GPIO(4)
-#define LOCOMO_GPIO_LCD_VSHD_ON	LOCOMO_GPIO(5)
-#define LOCOMO_GPIO_LCD_VEE_ON	LOCOMO_GPIO(6)
-#define LOCOMO_GPIO_LCD_MOD	LOCOMO_GPIO(7)
-#define LOCOMO_GPIO_DAC_ON	LOCOMO_GPIO(8)
-#define LOCOMO_GPIO_FL_VR	LOCOMO_GPIO(9)
-#define LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
-#define LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
-#define LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
-#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13)
-#define LOCOMO_GPIO_WRITE_PROT  LOCOMO_GPIO(14)
-#define LOCOMO_GPIO_CARD_POWER  LOCOMO_GPIO(15)
-
-/* Start the definitions of the devices.  Each device has an initial
- * base address and a series of offsets from that base address. */
-
-/* Keyboard controller */
-#define LOCOMO_KEYBOARD		0x40
-#define LOCOMO_KIB		0x00	/* KIB level */
-#define LOCOMO_KSC		0x04	/* KSTRB control */
-#define LOCOMO_KCMD		0x08	/* KSTRB command */
-#define LOCOMO_KIC		0x0c	/* Key interrupt */
-
-/* Front light adjustment controller */
-#define LOCOMO_FRONTLIGHT	0xc8
-#define LOCOMO_ALS		0x00	/* Adjust light cycle */
-#define LOCOMO_ALD		0x04	/* Adjust light duty */
-
-#define LOCOMO_ALC_EN		0x8000
-
-/* Backlight controller: TFT signal */
-#define LOCOMO_BACKLIGHT	0x38
-#define LOCOMO_TC		0x00		/* TFT control signal */
-#define LOCOMO_CPSD		0x04		/* CPS delay */
-
-/* Audio controller */
-#define LOCOMO_AUDIO		0x54
-#define LOCOMO_ACC		0x00	/* Audio clock */
-#define LOCOMO_PAIF		0xD0	/* PCM audio interface */
-/* Audio clock */
-#define	LOCOMO_ACC_XON		0x80
-#define	LOCOMO_ACC_XEN		0x40
-#define	LOCOMO_ACC_XSEL0	0x00
-#define	LOCOMO_ACC_XSEL1	0x20
-#define	LOCOMO_ACC_MCLKEN	0x10
-#define	LOCOMO_ACC_64FSEN	0x08
-#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
-#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
-#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
-#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
-#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
-#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */
-/* PCM audio interface */
-#define	LOCOMO_PAIF_SCINV	0x20
-#define	LOCOMO_PAIF_SCEN	0x10
-#define	LOCOMO_PAIF_LRCRST	0x08
-#define	LOCOMO_PAIF_LRCEVE	0x04
-#define	LOCOMO_PAIF_LRCINV	0x02
-#define	LOCOMO_PAIF_LRCEN	0x01
-
-/* LED controller */
-#define LOCOMO_LED		0xe8
-#define LOCOMO_LPT0		0x00
-#define LOCOMO_LPT1		0x04
-/* LED control */
-#define LOCOMO_LPT_TOFH		0x80
-#define LOCOMO_LPT_TOFL		0x08
-#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
-#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
-
-extern struct bus_type locomo_bus_type;
-
-#define LOCOMO_DEVID_KEYBOARD	0
-#define LOCOMO_DEVID_FRONTLIGHT	1
-#define LOCOMO_DEVID_BACKLIGHT	2
-#define LOCOMO_DEVID_AUDIO	3
-#define LOCOMO_DEVID_LED	4
-#define LOCOMO_DEVID_UART	5
-#define LOCOMO_DEVID_SPI	6
-
-struct locomo_dev {
-	struct device	dev;
-	unsigned int	devid;
-	unsigned int	irq[1];
-
-	void		*mapbase;
-	unsigned long	length;
-
-	u64		dma_mask;
-};
-
-#define LOCOMO_DEV(_d)	container_of((_d), struct locomo_dev, dev)
-
-#define locomo_get_drvdata(d)	dev_get_drvdata(&(d)->dev)
-#define locomo_set_drvdata(d,p)	dev_set_drvdata(&(d)->dev, p)
-
-struct locomo_driver {
-	struct device_driver	drv;
-	unsigned int		devid;
-	int (*probe)(struct locomo_dev *);
-	int (*remove)(struct locomo_dev *);
-	int (*suspend)(struct locomo_dev *, pm_message_t);
-	int (*resume)(struct locomo_dev *);
-};
-
-#define LOCOMO_DRV(_d)	container_of((_d), struct locomo_driver, drv)
-
-#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
-
-void locomo_lcd_power(struct locomo_dev *, int, unsigned int);
-
-int locomo_driver_register(struct locomo_driver *);
-void locomo_driver_unregister(struct locomo_driver *);
-
-/* GPIO control functions */
-void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir);
-int locomo_gpio_read_level(struct device *dev, unsigned int bits);
-int locomo_gpio_read_output(struct device *dev, unsigned int bits);
-void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set);
-
-/* M62332 control function */
-void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
-
-/* Frontlight control */
-void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
-
-struct locomo_platform_data {
-	int	irq_base;	/* IRQ base for cascaded on-chip IRQs */
-};
-
-#endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [PATCH v2 17/17] ARM: drop old LoCoMo driver
@ 2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-27 23:55 UTC (permalink / raw)
  To: linux-arm-kernel

As there are no in-kernel users of old locomo driver, drop all
alltogether. Remove Kconfig entry, driver and header.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/common/Kconfig                |   3 -
 arch/arm/common/Makefile               |   1 -
 arch/arm/common/locomo.c               | 914 ---------------------------------
 arch/arm/include/asm/hardware/locomo.h | 221 --------
 4 files changed, 1139 deletions(-)
 delete mode 100644 arch/arm/common/locomo.c
 delete mode 100644 arch/arm/include/asm/hardware/locomo.h

diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index c3a4e9c..76c9970 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -9,9 +9,6 @@ config DMABOUNCE
 	bool
 	select ZONE_DMA
 
-config SHARP_LOCOMO
-	bool
-
 config SHARP_PARAM
 	bool
 
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 70b1eff..437c79a 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -7,7 +7,6 @@ obj-y				+= firmware.o
 obj-$(CONFIG_ICST)		+= icst.o
 obj-$(CONFIG_SA1111)		+= sa1111.o
 obj-$(CONFIG_DMABOUNCE)		+= dmabounce.o
-obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
deleted file mode 100644
index b55c362..0000000
--- a/arch/arm/common/locomo.c
+++ /dev/null
@@ -1,914 +0,0 @@
-/*
- * linux/arch/arm/common/locomo.c
- *
- * Sharp LoCoMo support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This file contains all generic LoCoMo support.
- *
- * All initialization functions provided here are intended to be called
- * from machine specific code with proper arguments when required.
- *
- * Based on sa1111.c
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <asm/hardware/locomo.h>
-
-/* LoCoMo Interrupts */
-#define IRQ_LOCOMO_KEY		(0)
-#define IRQ_LOCOMO_GPIO		(1)
-#define IRQ_LOCOMO_LT		(2)
-#define IRQ_LOCOMO_SPI		(3)
-
-/* M62332 output channel selection */
-#define M62332_EVR_CH	1	/* M62332 volume channel number  */
-				/*   0 : CH.1 , 1 : CH. 2        */
-/* DAC send data */
-#define	M62332_SLAVE_ADDR	0x4e	/* Slave address  */
-#define	M62332_W_BIT		0x00	/* W bit (0 only) */
-#define	M62332_SUB_ADDR		0x00	/* Sub address    */
-#define	M62332_A_BIT		0x00	/* A bit (0 only) */
-
-/* DAC setup and hold times (expressed in us) */
-#define DAC_BUS_FREE_TIME	5	/*   4.7 us */
-#define DAC_START_SETUP_TIME	5	/*   4.7 us */
-#define DAC_STOP_SETUP_TIME	4	/*   4.0 us */
-#define DAC_START_HOLD_TIME	5	/*   4.7 us */
-#define DAC_SCL_LOW_HOLD_TIME	5	/*   4.7 us */
-#define DAC_SCL_HIGH_HOLD_TIME	4	/*   4.0 us */
-#define DAC_DATA_SETUP_TIME	1	/*   250 ns */
-#define DAC_DATA_HOLD_TIME	1	/*   300 ns */
-#define DAC_LOW_SETUP_TIME	1	/*   300 ns */
-#define DAC_HIGH_SETUP_TIME	1	/*  1000 ns */
-
-/* the following is the overall data for the locomo chip */
-struct locomo {
-	struct device *dev;
-	unsigned long phys;
-	unsigned int irq;
-	int irq_base;
-	spinlock_t lock;
-	void __iomem *base;
-#ifdef CONFIG_PM
-	void *saved_state;
-#endif
-};
-
-struct locomo_dev_info {
-	unsigned long	offset;
-	unsigned long	length;
-	unsigned int	devid;
-	unsigned int	irq[1];
-	const char *	name;
-};
-
-/* All the locomo devices.  If offset is non-zero, the mapbase for the
- * locomo_dev will be set to the chip base plus offset.  If offset is
- * zero, then the mapbase for the locomo_dev will be set to zero.  An
- * offset of zero means the device only uses GPIOs or other helper
- * functions inside this file */
-static struct locomo_dev_info locomo_devices[] = {
-	{
-		.devid 		= LOCOMO_DEVID_KEYBOARD,
-		.irq		= { IRQ_LOCOMO_KEY },
-		.name		= "locomo-keyboard",
-		.offset		= LOCOMO_KEYBOARD,
-		.length		= 16,
-	},
-	{
-		.devid		= LOCOMO_DEVID_FRONTLIGHT,
-		.irq		= {},
-		.name		= "locomo-frontlight",
-		.offset		= LOCOMO_FRONTLIGHT,
-		.length		= 8,
-
-	},
-	{
-		.devid		= LOCOMO_DEVID_BACKLIGHT,
-		.irq		= {},
-		.name		= "locomo-backlight",
-		.offset		= LOCOMO_BACKLIGHT,
-		.length		= 8,
-	},
-	{
-		.devid		= LOCOMO_DEVID_AUDIO,
-		.irq		= {},
-		.name		= "locomo-audio",
-		.offset		= LOCOMO_AUDIO,
-		.length		= 4,
-	},
-	{
-		.devid		= LOCOMO_DEVID_LED,
-		.irq 		= {},
-		.name		= "locomo-led",
-		.offset		= LOCOMO_LED,
-		.length		= 8,
-	},
-	{
-		.devid		= LOCOMO_DEVID_UART,
-		.irq		= {},
-		.name		= "locomo-uart",
-		.offset		= 0,
-		.length		= 0,
-	},
-	{
-		.devid		= LOCOMO_DEVID_SPI,
-		.irq		= {},
-		.name		= "locomo-spi",
-		.offset		= LOCOMO_SPI,
-		.length		= 0x30,
-	},
-};
-
-static void locomo_handler(unsigned int irq, struct irq_desc *desc)
-{
-	struct locomo *lchip = irq_get_chip_data(irq);
-	int req, i;
-
-	/* Acknowledge the parent IRQ */
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-	/* check why this interrupt was generated */
-	req = locomo_readl(lchip->base + LOCOMO_ICR) & 0x0f00;
-
-	if (req) {
-		/* generate the next interrupt(s) */
-		irq = lchip->irq_base;
-		for (i = 0; i <= 3; i++, irq++) {
-			if (req & (0x0100 << i)) {
-				generic_handle_irq(irq);
-			}
-
-		}
-	}
-}
-
-static void locomo_ack_irq(struct irq_data *d)
-{
-}
-
-static void locomo_mask_irq(struct irq_data *d)
-{
-	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
-	r &= ~(0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
-}
-
-static void locomo_unmask_irq(struct irq_data *d)
-{
-	struct locomo *lchip = irq_data_get_irq_chip_data(d);
-	unsigned int r;
-	r = locomo_readl(lchip->base + LOCOMO_ICR);
-	r |= (0x0010 << (d->irq - lchip->irq_base));
-	locomo_writel(r, lchip->base + LOCOMO_ICR);
-}
-
-static struct irq_chip locomo_chip = {
-	.name		= "LOCOMO",
-	.irq_ack	= locomo_ack_irq,
-	.irq_mask	= locomo_mask_irq,
-	.irq_unmask	= locomo_unmask_irq,
-};
-
-static void locomo_setup_irq(struct locomo *lchip)
-{
-	int irq = lchip->irq_base;
-
-	/*
-	 * Install handler for IRQ_LOCOMO_HW.
-	 */
-	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
-	irq_set_chip_data(lchip->irq, lchip);
-	irq_set_chained_handler(lchip->irq, locomo_handler);
-
-	/* Install handlers for IRQ_LOCOMO_* */
-	for ( ; irq <= lchip->irq_base + 3; irq++) {
-		irq_set_chip_and_handler(irq, &locomo_chip, handle_level_irq);
-		irq_set_chip_data(irq, lchip);
-		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-	}
-}
-
-
-static void locomo_dev_release(struct device *_dev)
-{
-	struct locomo_dev *dev = LOCOMO_DEV(_dev);
-
-	kfree(dev);
-}
-
-static int
-locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
-{
-	struct locomo_dev *dev;
-	int ret;
-
-	dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL);
-	if (!dev) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	/*
-	 * If the parent device has a DMA mask associated with it,
-	 * propagate it down to the children.
-	 */
-	if (lchip->dev->dma_mask) {
-		dev->dma_mask = *lchip->dev->dma_mask;
-		dev->dev.dma_mask = &dev->dma_mask;
-	}
-
-	dev_set_name(&dev->dev, "%s", info->name);
-	dev->devid	 = info->devid;
-	dev->dev.parent  = lchip->dev;
-	dev->dev.bus     = &locomo_bus_type;
-	dev->dev.release = locomo_dev_release;
-	dev->dev.coherent_dma_mask = lchip->dev->coherent_dma_mask;
-
-	if (info->offset)
-		dev->mapbase = lchip->base + info->offset;
-	else
-		dev->mapbase = 0;
-	dev->length = info->length;
-
-	dev->irq[0] = (lchip->irq_base == NO_IRQ) ?
-			NO_IRQ : lchip->irq_base + info->irq[0];
-
-	ret = device_register(&dev->dev);
-	if (ret) {
- out:
-		kfree(dev);
-	}
-	return ret;
-}
-
-#ifdef CONFIG_PM
-
-struct locomo_save_data {
-	u16	LCM_GPO;
-	u16	LCM_SPICT;
-	u16	LCM_GPE;
-	u16	LCM_ASD;
-	u16	LCM_SPIMD;
-};
-
-static int locomo_suspend(struct platform_device *dev, pm_message_t state)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-	struct locomo_save_data *save;
-	unsigned long flags;
-
-	save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
-	if (!save)
-		return -ENOMEM;
-
-	lchip->saved_state = save;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
-	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);	/* SPI */
-	locomo_writel(0x40, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	save->LCM_GPE     = locomo_readl(lchip->base + LOCOMO_GPE);	/* GPIO */
-	locomo_writel(0x00, lchip->base + LOCOMO_GPE);
-	save->LCM_ASD     = locomo_readl(lchip->base + LOCOMO_ASD);	/* ADSTART */
-	locomo_writel(0x00, lchip->base + LOCOMO_ASD);
-	save->LCM_SPIMD   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);	/* SPI */
-	locomo_writel(0x3C14, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
-
-	locomo_writel(0x00, lchip->base + LOCOMO_PAIF);
-	locomo_writel(0x00, lchip->base + LOCOMO_DAC);
-	locomo_writel(0x00, lchip->base + LOCOMO_BACKLIGHT + LOCOMO_TC);
-
-	if ((locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT0) & 0x88) && (locomo_readl(lchip->base + LOCOMO_LED + LOCOMO_LPT1) & 0x88))
-		locomo_writel(0x00, lchip->base + LOCOMO_C32K); 	/* CLK32 off */
-	else
-		/* 18MHz already enabled, so no wait */
-		locomo_writel(0xc1, lchip->base + LOCOMO_C32K); 	/* CLK32 on */
-
-	locomo_writel(0x00, lchip->base + LOCOMO_TADC);		/* 18MHz clock off*/
-	locomo_writel(0x00, lchip->base + LOCOMO_AUDIO + LOCOMO_ACC);			/* 22MHz/24MHz clock off */
-	locomo_writel(0x00, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);			/* FL */
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	return 0;
-}
-
-static int locomo_resume(struct platform_device *dev)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-	struct locomo_save_data *save;
-	unsigned long r;
-	unsigned long flags;
-
-	save = lchip->saved_state;
-	if (!save)
-		return 0;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	locomo_writel(save->LCM_GPO, lchip->base + LOCOMO_GPO);
-	locomo_writel(save->LCM_SPICT, lchip->base + LOCOMO_SPI + LOCOMO_SPICT);
-	locomo_writel(save->LCM_GPE, lchip->base + LOCOMO_GPE);
-	locomo_writel(save->LCM_ASD, lchip->base + LOCOMO_ASD);
-	locomo_writel(save->LCM_SPIMD, lchip->base + LOCOMO_SPI + LOCOMO_SPIMD);
-
-	locomo_writel(0x00, lchip->base + LOCOMO_C32K);
-	locomo_writel(0x90, lchip->base + LOCOMO_TADC);
-
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KSC);
-	r = locomo_readl(lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	r &= 0xFEFF;
-	locomo_writel(r, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-	locomo_writel(0x1, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KCMD);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	lchip->saved_state = NULL;
-	kfree(save);
-
-	return 0;
-}
-#endif
-
-
-/**
- *	locomo_probe - probe for a single LoCoMo chip.
- *	@phys_addr: physical address of device.
- *
- *	Probe for a LoCoMo chip.  This must be called
- *	before any other locomo-specific code.
- *
- *	Returns:
- *	%-ENODEV	device not found.
- *	%-EBUSY		physical address already marked in-use.
- *	%0		successful.
- */
-static int
-__locomo_probe(struct device *me, struct resource *mem, int irq)
-{
-	struct locomo_platform_data *pdata = me->platform_data;
-	struct locomo *lchip;
-	unsigned long r;
-	int i, ret = -ENODEV;
-
-	lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL);
-	if (!lchip)
-		return -ENOMEM;
-
-	spin_lock_init(&lchip->lock);
-
-	lchip->dev = me;
-	dev_set_drvdata(lchip->dev, lchip);
-
-	lchip->phys = mem->start;
-	lchip->irq = irq;
-	lchip->irq_base = (pdata) ? pdata->irq_base : NO_IRQ;
-
-	/*
-	 * Map the whole region.  This also maps the
-	 * registers for our children.
-	 */
-	lchip->base = ioremap(mem->start, PAGE_SIZE);
-	if (!lchip->base) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	/* locomo initialize */
-	locomo_writel(0, lchip->base + LOCOMO_ICR);
-	/* KEYBOARD */
-	locomo_writel(0, lchip->base + LOCOMO_KEYBOARD + LOCOMO_KIC);
-
-	/* GPIO */
-	locomo_writel(0, lchip->base + LOCOMO_GPO);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPE);
-	locomo_writel((LOCOMO_GPIO(1) | LOCOMO_GPIO(2) | LOCOMO_GPIO(13) | LOCOMO_GPIO(14))
-			, lchip->base + LOCOMO_GPD);
-	locomo_writel(0, lchip->base + LOCOMO_GIE);
-
-	/* Frontlight */
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	locomo_writel(0, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
-
-	/* Longtime timer */
-	locomo_writel(0, lchip->base + LOCOMO_LTINT);
-	/* SPI */
-	locomo_writel(0, lchip->base + LOCOMO_SPI + LOCOMO_SPIIE);
-
-	locomo_writel(6 + 8 + 320 + 30 - 10, lchip->base + LOCOMO_ASD);
-	r = locomo_readl(lchip->base + LOCOMO_ASD);
-	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_ASD);
-
-	locomo_writel(6 + 8 + 320 + 30 - 10 - 128 + 4, lchip->base + LOCOMO_HSD);
-	r = locomo_readl(lchip->base + LOCOMO_HSD);
-	r |= 0x8000;
-	locomo_writel(r, lchip->base + LOCOMO_HSD);
-
-	locomo_writel(128 / 8, lchip->base + LOCOMO_HSC);
-
-	/* XON */
-	locomo_writel(0x80, lchip->base + LOCOMO_TADC);
-	udelay(1000);
-	/* CLK9MEN */
-	r = locomo_readl(lchip->base + LOCOMO_TADC);
-	r |= 0x10;
-	locomo_writel(r, lchip->base + LOCOMO_TADC);
-	udelay(100);
-
-	/* init DAC */
-	r = locomo_readl(lchip->base + LOCOMO_DAC);
-	r |= LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, lchip->base + LOCOMO_DAC);
-
-	r = locomo_readl(lchip->base + LOCOMO_VER);
-	printk(KERN_INFO "LoCoMo Chip: %lu%lu\n", (r >> 8), (r & 0xff));
-
-	/*
-	 * The interrupt controller must be initialised before any
-	 * other device to ensure that the interrupts are available.
-	 */
-	if (lchip->irq != NO_IRQ && lchip->irq_base != NO_IRQ)
-		locomo_setup_irq(lchip);
-
-	for (i = 0; i < ARRAY_SIZE(locomo_devices); i++)
-		locomo_init_one_child(lchip, &locomo_devices[i]);
-	return 0;
-
- out:
-	kfree(lchip);
-	return ret;
-}
-
-static int locomo_remove_child(struct device *dev, void *data)
-{
-	device_unregister(dev);
-	return 0;
-} 
-
-static void __locomo_remove(struct locomo *lchip)
-{
-	device_for_each_child(lchip->dev, NULL, locomo_remove_child);
-
-	if (lchip->irq != NO_IRQ) {
-		irq_set_chained_handler(lchip->irq, NULL);
-		irq_set_handler_data(lchip->irq, NULL);
-	}
-
-	iounmap(lchip->base);
-	kfree(lchip);
-}
-
-static int locomo_probe(struct platform_device *dev)
-{
-	struct resource *mem;
-	int irq;
-
-	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (!mem)
-		return -EINVAL;
-	irq = platform_get_irq(dev, 0);
-	if (irq < 0)
-		return -ENXIO;
-
-	return __locomo_probe(&dev->dev, mem, irq);
-}
-
-static int locomo_remove(struct platform_device *dev)
-{
-	struct locomo *lchip = platform_get_drvdata(dev);
-
-	if (lchip) {
-		__locomo_remove(lchip);
-		platform_set_drvdata(dev, NULL);
-	}
-
-	return 0;
-}
-
-/*
- *	Not sure if this should be on the system bus or not yet.
- *	We really want some way to register a system device at
- *	the per-machine level, and then have this driver pick
- *	up the registered devices.
- */
-static struct platform_driver locomo_device_driver = {
-	.probe		= locomo_probe,
-	.remove		= locomo_remove,
-#ifdef CONFIG_PM
-	.suspend	= locomo_suspend,
-	.resume		= locomo_resume,
-#endif
-	.driver		= {
-		.name	= "locomo",
-	},
-};
-
-/*
- *	Get the parent device driver (us) structure
- *	from a child function device
- */
-static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev)
-{
-	return (struct locomo *)dev_get_drvdata(ldev->dev.parent);
-}
-
-void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int r;
-
-	if (!lchip)
-		return;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPD);
-	if (dir)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPD);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPE);
-	if (dir)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPE);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_gpio_set_dir);
-
-int locomo_gpio_read_level(struct device *dev, unsigned int bits)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int ret;
-
-	if (!lchip)
-		return -ENODEV;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPL);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	ret &= bits;
-	return ret;
-}
-EXPORT_SYMBOL(locomo_gpio_read_level);
-
-int locomo_gpio_read_output(struct device *dev, unsigned int bits)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int ret;
-
-	if (!lchip)
-		return -ENODEV;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	ret = locomo_readl(lchip->base + LOCOMO_GPO);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-
-	ret &= bits;
-	return ret;
-}
-EXPORT_SYMBOL(locomo_gpio_read_output);
-
-void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set)
-{
-	struct locomo *lchip = dev_get_drvdata(dev);
-	unsigned long flags;
-	unsigned int r;
-
-	if (!lchip)
-		return;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	r = locomo_readl(lchip->base + LOCOMO_GPO);
-	if (set)
-		r |= bits;
-	else
-		r &= ~bits;
-	locomo_writel(r, lchip->base + LOCOMO_GPO);
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_gpio_write);
-
-static void locomo_m62332_sendbit(void *mapbase, int bit)
-{
-	unsigned int r;
-
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-
-	if (bit & 1) {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
-		r |=  LOCOMO_DAC_SDAOEB;
-		locomo_writel(r, mapbase + LOCOMO_DAC);
-		udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	} else {
-		r = locomo_readl(mapbase + LOCOMO_DAC);
-		r &=  ~(LOCOMO_DAC_SDAOEB);
-		locomo_writel(r, mapbase + LOCOMO_DAC);
-		udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	}
-
-	udelay(DAC_DATA_SETUP_TIME);	/* 250 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/*  4.0 usec */
-}
-
-void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel)
-{
-	struct locomo *lchip = locomo_chip_driver(ldev);
-	int i;
-	unsigned char data;
-	unsigned int r;
-	void *mapbase = lchip->base;
-	unsigned long flags;
-
-	spin_lock_irqsave(&lchip->lock, flags);
-
-	/* Start */
-	udelay(DAC_BUS_FREE_TIME);	/* 5.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.0 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_START_HOLD_TIME);	/* 5.0 usec */
-	udelay(DAC_DATA_HOLD_TIME);	/* 300 nsec */
-
-	/* Send slave address and W bit (LSB is W bit) */
-	data = (M62332_SLAVE_ADDR << 1) | M62332_W_BIT;
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 1\n");
-		goto out;
-	}
-
-	/* Send Sub address (LSB is channel select) */
-	/*    channel = 0 : ch1 select              */
-	/*            = 1 : ch2 select              */
-	data = M62332_SUB_ADDR + channel;
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 2\n");
-		goto out;
-	}
-
-	/* Send DAC data */
-	for (i = 1; i <= 8; i++) {
-		locomo_m62332_sendbit(mapbase, dac_data >> (8 - i));
-	}
-
-	/* Check A bit */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SDAOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4.7 usec */
-	if (locomo_readl(mapbase + LOCOMO_DAC) & LOCOMO_DAC_SDAOEB) {	/* High is error */
-		printk(KERN_WARNING "locomo: m62332_senddata Error 3\n");
-	}
-
-out:
-	/* stop */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r &=  ~(LOCOMO_DAC_SCLOEB);
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 300 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_HIGH_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_HIGH_HOLD_TIME);	/* 4 usec */
-
-	r = locomo_readl(mapbase + LOCOMO_DAC);
-	r |=  LOCOMO_DAC_SCLOEB | LOCOMO_DAC_SDAOEB;
-	locomo_writel(r, mapbase + LOCOMO_DAC);
-	udelay(DAC_LOW_SETUP_TIME);	/* 1000 nsec */
-	udelay(DAC_SCL_LOW_HOLD_TIME);	/* 4.7 usec */
-
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_m62332_senddata);
-
-/*
- *	Frontlight control
- */
-
-void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
-{
-	unsigned long flags;
-	struct locomo *lchip = locomo_chip_driver(dev);
-
-	if (vr)
-		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);
-	else
-		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0);
-
-	spin_lock_irqsave(&lchip->lock, flags);
-	locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	udelay(100);
-	locomo_writel(duty, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALD);
-	locomo_writel(bpwf | LOCOMO_ALC_EN, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS);
-	spin_unlock_irqrestore(&lchip->lock, flags);
-}
-EXPORT_SYMBOL(locomo_frontlight_set);
-
-/*
- *	LoCoMo "Register Access Bus."
- *
- *	We model this as a regular bus type, and hang devices directly
- *	off this.
- */
-static int locomo_match(struct device *_dev, struct device_driver *_drv)
-{
-	struct locomo_dev *dev = LOCOMO_DEV(_dev);
-	struct locomo_driver *drv = LOCOMO_DRV(_drv);
-
-	return dev->devid == drv->devid;
-}
-
-static int locomo_bus_suspend(struct device *dev, pm_message_t state)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv && drv->suspend)
-		ret = drv->suspend(ldev, state);
-	return ret;
-}
-
-static int locomo_bus_resume(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv && drv->resume)
-		ret = drv->resume(ldev);
-	return ret;
-}
-
-static int locomo_bus_probe(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = -ENODEV;
-
-	if (drv->probe)
-		ret = drv->probe(ldev);
-	return ret;
-}
-
-static int locomo_bus_remove(struct device *dev)
-{
-	struct locomo_dev *ldev = LOCOMO_DEV(dev);
-	struct locomo_driver *drv = LOCOMO_DRV(dev->driver);
-	int ret = 0;
-
-	if (drv->remove)
-		ret = drv->remove(ldev);
-	return ret;
-}
-
-struct bus_type locomo_bus_type = {
-	.name		= "locomo-bus",
-	.match		= locomo_match,
-	.probe		= locomo_bus_probe,
-	.remove		= locomo_bus_remove,
-	.suspend	= locomo_bus_suspend,
-	.resume		= locomo_bus_resume,
-};
-
-int locomo_driver_register(struct locomo_driver *driver)
-{
-	driver->drv.bus = &locomo_bus_type;
-	return driver_register(&driver->drv);
-}
-EXPORT_SYMBOL(locomo_driver_register);
-
-void locomo_driver_unregister(struct locomo_driver *driver)
-{
-	driver_unregister(&driver->drv);
-}
-EXPORT_SYMBOL(locomo_driver_unregister);
-
-static int __init locomo_init(void)
-{
-	int ret = bus_register(&locomo_bus_type);
-	if (ret == 0)
-		platform_driver_register(&locomo_device_driver);
-	return ret;
-}
-
-static void __exit locomo_exit(void)
-{
-	platform_driver_unregister(&locomo_device_driver);
-	bus_unregister(&locomo_bus_type);
-}
-
-module_init(locomo_init);
-module_exit(locomo_exit);
-
-MODULE_DESCRIPTION("Sharp LoCoMo core driver");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
diff --git a/arch/arm/include/asm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h
deleted file mode 100644
index 74e51d6b..0000000
--- a/arch/arm/include/asm/hardware/locomo.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/locomo.h
- *
- * This file contains the definitions for the LoCoMo G/A Chip
- *
- * (C) Copyright 2004 John Lenz
- *
- * May be copied or modified under the terms of the GNU General Public
- * License.  See linux/COPYING for more information.
- *
- * Based on sa1111.h
- */
-#ifndef _ASM_ARCH_LOCOMO
-#define _ASM_ARCH_LOCOMO
-
-#define locomo_writel(val,addr)	({ *(volatile u16 *)(addr) = (val); })
-#define locomo_readl(addr)	(*(volatile u16 *)(addr))
-
-/* LOCOMO version */
-#define LOCOMO_VER	0x00
-
-/* Pin status */
-#define LOCOMO_ST	0x04
-
-/* Pin status */
-#define LOCOMO_C32K	0x08
-
-/* Interrupt controller */
-#define LOCOMO_ICR	0x0C
-
-/* MCS decoder for boot selecting */
-#define LOCOMO_MCSX0	0x10
-#define LOCOMO_MCSX1	0x14
-#define LOCOMO_MCSX2	0x18
-#define LOCOMO_MCSX3	0x1c
-
-/* Touch panel controller */
-#define LOCOMO_ASD	0x20		/* AD start delay */
-#define LOCOMO_HSD	0x28		/* HSYS delay */
-#define LOCOMO_HSC	0x2c		/* HSYS period */
-#define LOCOMO_TADC	0x30		/* tablet ADC clock */
-
-
-/* Long time timer */
-#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
-#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
-
-/* DAC control signal for LCD (COMADJ ) */
-#define LOCOMO_DAC		0xe0
-/* DAC control */
-#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
-#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
-#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
-#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
-
-/* SPI interface */
-#define LOCOMO_SPI	0x60
-#define LOCOMO_SPIMD	0x00		/* SPI mode setting */
-#define LOCOMO_SPICT	0x04		/* SPI mode control */
-#define LOCOMO_SPIST	0x08		/* SPI status */
-#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
-#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
-#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
-#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
-
-#define LOCOMO_SPIIS	0x10		/* SPI interrupt status */
-#define LOCOMO_SPIWE	0x14		/* SPI interrupt status write enable */
-#define LOCOMO_SPIIE	0x18		/* SPI interrupt enable */
-#define LOCOMO_SPIIR	0x1c		/* SPI interrupt request */
-#define LOCOMO_SPITD	0x20		/* SPI transfer data write */
-#define LOCOMO_SPIRD	0x24		/* SPI receive data read */
-#define LOCOMO_SPITS	0x28		/* SPI transfer data shift */
-#define LOCOMO_SPIRS	0x2C		/* SPI receive data shift */
-
-/* GPIO */
-#define LOCOMO_GPD		0x90	/* GPIO direction */
-#define LOCOMO_GPE		0x94	/* GPIO input enable */
-#define LOCOMO_GPL		0x98	/* GPIO level */
-#define LOCOMO_GPO		0x9c	/* GPIO out data setting */
-#define LOCOMO_GRIE		0xa0	/* GPIO rise detection */
-#define LOCOMO_GFIE		0xa4	/* GPIO fall detection */
-#define LOCOMO_GIS		0xa8	/* GPIO edge detection status */
-#define LOCOMO_GWE		0xac	/* GPIO status write enable */
-#define LOCOMO_GIE		0xb0	/* GPIO interrupt enable */
-#define LOCOMO_GIR		0xb4	/* GPIO interrupt request */
-#define	LOCOMO_GPIO(Nb)		(0x01 << (Nb))
-#define LOCOMO_GPIO_RTS		LOCOMO_GPIO(0)
-#define LOCOMO_GPIO_CTS		LOCOMO_GPIO(1)
-#define LOCOMO_GPIO_DSR		LOCOMO_GPIO(2)
-#define LOCOMO_GPIO_DTR		LOCOMO_GPIO(3)
-#define LOCOMO_GPIO_LCD_VSHA_ON	LOCOMO_GPIO(4)
-#define LOCOMO_GPIO_LCD_VSHD_ON	LOCOMO_GPIO(5)
-#define LOCOMO_GPIO_LCD_VEE_ON	LOCOMO_GPIO(6)
-#define LOCOMO_GPIO_LCD_MOD	LOCOMO_GPIO(7)
-#define LOCOMO_GPIO_DAC_ON	LOCOMO_GPIO(8)
-#define LOCOMO_GPIO_FL_VR	LOCOMO_GPIO(9)
-#define LOCOMO_GPIO_DAC_SDATA	LOCOMO_GPIO(10)
-#define LOCOMO_GPIO_DAC_SCK	LOCOMO_GPIO(11)
-#define LOCOMO_GPIO_DAC_SLOAD	LOCOMO_GPIO(12)
-#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13)
-#define LOCOMO_GPIO_WRITE_PROT  LOCOMO_GPIO(14)
-#define LOCOMO_GPIO_CARD_POWER  LOCOMO_GPIO(15)
-
-/* Start the definitions of the devices.  Each device has an initial
- * base address and a series of offsets from that base address. */
-
-/* Keyboard controller */
-#define LOCOMO_KEYBOARD		0x40
-#define LOCOMO_KIB		0x00	/* KIB level */
-#define LOCOMO_KSC		0x04	/* KSTRB control */
-#define LOCOMO_KCMD		0x08	/* KSTRB command */
-#define LOCOMO_KIC		0x0c	/* Key interrupt */
-
-/* Front light adjustment controller */
-#define LOCOMO_FRONTLIGHT	0xc8
-#define LOCOMO_ALS		0x00	/* Adjust light cycle */
-#define LOCOMO_ALD		0x04	/* Adjust light duty */
-
-#define LOCOMO_ALC_EN		0x8000
-
-/* Backlight controller: TFT signal */
-#define LOCOMO_BACKLIGHT	0x38
-#define LOCOMO_TC		0x00		/* TFT control signal */
-#define LOCOMO_CPSD		0x04		/* CPS delay */
-
-/* Audio controller */
-#define LOCOMO_AUDIO		0x54
-#define LOCOMO_ACC		0x00	/* Audio clock */
-#define LOCOMO_PAIF		0xD0	/* PCM audio interface */
-/* Audio clock */
-#define	LOCOMO_ACC_XON		0x80
-#define	LOCOMO_ACC_XEN		0x40
-#define	LOCOMO_ACC_XSEL0	0x00
-#define	LOCOMO_ACC_XSEL1	0x20
-#define	LOCOMO_ACC_MCLKEN	0x10
-#define	LOCOMO_ACC_64FSEN	0x08
-#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
-#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
-#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
-#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
-#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
-#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */
-/* PCM audio interface */
-#define	LOCOMO_PAIF_SCINV	0x20
-#define	LOCOMO_PAIF_SCEN	0x10
-#define	LOCOMO_PAIF_LRCRST	0x08
-#define	LOCOMO_PAIF_LRCEVE	0x04
-#define	LOCOMO_PAIF_LRCINV	0x02
-#define	LOCOMO_PAIF_LRCEN	0x01
-
-/* LED controller */
-#define LOCOMO_LED		0xe8
-#define LOCOMO_LPT0		0x00
-#define LOCOMO_LPT1		0x04
-/* LED control */
-#define LOCOMO_LPT_TOFH		0x80
-#define LOCOMO_LPT_TOFL		0x08
-#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
-#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
-
-extern struct bus_type locomo_bus_type;
-
-#define LOCOMO_DEVID_KEYBOARD	0
-#define LOCOMO_DEVID_FRONTLIGHT	1
-#define LOCOMO_DEVID_BACKLIGHT	2
-#define LOCOMO_DEVID_AUDIO	3
-#define LOCOMO_DEVID_LED	4
-#define LOCOMO_DEVID_UART	5
-#define LOCOMO_DEVID_SPI	6
-
-struct locomo_dev {
-	struct device	dev;
-	unsigned int	devid;
-	unsigned int	irq[1];
-
-	void		*mapbase;
-	unsigned long	length;
-
-	u64		dma_mask;
-};
-
-#define LOCOMO_DEV(_d)	container_of((_d), struct locomo_dev, dev)
-
-#define locomo_get_drvdata(d)	dev_get_drvdata(&(d)->dev)
-#define locomo_set_drvdata(d,p)	dev_set_drvdata(&(d)->dev, p)
-
-struct locomo_driver {
-	struct device_driver	drv;
-	unsigned int		devid;
-	int (*probe)(struct locomo_dev *);
-	int (*remove)(struct locomo_dev *);
-	int (*suspend)(struct locomo_dev *, pm_message_t);
-	int (*resume)(struct locomo_dev *);
-};
-
-#define LOCOMO_DRV(_d)	container_of((_d), struct locomo_driver, drv)
-
-#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
-
-void locomo_lcd_power(struct locomo_dev *, int, unsigned int);
-
-int locomo_driver_register(struct locomo_driver *);
-void locomo_driver_unregister(struct locomo_driver *);
-
-/* GPIO control functions */
-void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir);
-int locomo_gpio_read_level(struct device *dev, unsigned int bits);
-int locomo_gpio_read_output(struct device *dev, unsigned int bits);
-void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set);
-
-/* M62332 control function */
-void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
-
-/* Frontlight control */
-void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
-
-struct locomo_platform_data {
-	int	irq_base;	/* IRQ base for cascaded on-chip IRQs */
-};
-
-#endif
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
@ 2015-04-28 18:45       ` Lee Jones
  -1 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-04-28 18:45 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:

> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> several design issues (special bus instead of platform bus, doesn't use
> mfd-core, etc).
> 
> Implement 'core' parts of locomo support as an mfd driver.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  drivers/mfd/Kconfig        |  10 ++
>  drivers/mfd/Makefile       |   1 +
>  drivers/mfd/locomo.c       | 356 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/locomo.h | 173 ++++++++++++++++++++++
>  4 files changed, 540 insertions(+)
>  create mode 100644 drivers/mfd/locomo.c
>  create mode 100644 include/linux/mfd/locomo.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index d5ad04d..8c33940 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1430,6 +1430,16 @@ config MFD_STW481X
>  	  in various ST Microelectronics and ST-Ericsson embedded
>  	  Nomadik series.
>  
> +config MFD_LOCOMO
> +	bool "Sharp LoCoMo support"
> +	depends on ARM
> +	select MFD_CORE
> +	select IRQ_DOMAIN
> +	select REGMAP_MMIO
> +	help
> +	  Support for Sharp LoCoMo Grid Array found in Sharp SL-5x00
> +          PDA family.

Are people really still using this stuff?

>  menu "Multimedia Capabilities Port drivers"
>  	depends on ARCH_SA1100
>  
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 0e5cfeb..6c23b73 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -181,6 +181,7 @@ obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
>  obj-$(CONFIG_MFD_DLN2)		+= dln2.o
>  obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
>  obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
> +obj-$(CONFIG_MFD_LOCOMO)	+= locomo.o
>  
>  intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
>  obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
> diff --git a/drivers/mfd/locomo.c b/drivers/mfd/locomo.c
> new file mode 100644
> index 0000000..f981c94
> --- /dev/null
> +++ b/drivers/mfd/locomo.c
> @@ -0,0 +1,356 @@
> +/*
> + * Sharp LoCoMo support
> + *
> + * Based on old driver at arch/arm/common/locomo.c
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains all generic LoCoMo support.
> + *
> + * All initialization functions provided here are intended to be called
> + * from machine specific code with proper arguments when required.
> + */

'\n'

> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/locomo.h>
> +
> +/* LoCoMo Interrupts */
> +#define IRQ_LOCOMO_KEY		(0)
> +#define IRQ_LOCOMO_GPIO		(1)
> +#define IRQ_LOCOMO_LT		(2)
> +#define IRQ_LOCOMO_SPI		(3)
> +
> +#define LOCOMO_NR_IRQS		(4)

No need for all this added () protection.

> +/* the following is the overall data for the locomo chip */
> +struct locomo {
> +	struct device *dev;
> +	unsigned int irq;
> +	spinlock_t lock;
> +	struct irq_domain *domain;
> +	struct regmap *regmap;
> +};
> +
> +static struct resource locomo_kbd_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> +};
> +
> +static struct resource locomo_gpio_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> +};
> +
> +/* Filled in locomo_probe() function. */
> +static struct locomo_gpio_platform_data locomo_gpio_pdata;

I'd prefer you didn't use globals for this.

> +static struct resource locomo_lt_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> +};
> +
> +static struct resource locomo_spi_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> +};
> +
> +/* Filled in locomo_probe() function. */
> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> +
> +static struct mfd_cell locomo_cells[] = {
> +	{
> +		.name = "locomo-kbd",
> +		.resources = locomo_kbd_resources,
> +		.num_resources = ARRAY_SIZE(locomo_kbd_resources),
> +	},
> +	{
> +		.name = "locomo-gpio",
> +		.resources = locomo_gpio_resources,
> +		.num_resources = ARRAY_SIZE(locomo_gpio_resources),
> +		.platform_data = &locomo_gpio_pdata,
> +		.pdata_size = sizeof(locomo_gpio_pdata),
> +	},
> +	{
> +		.name = "locomo-lt", /* Long time timer */
> +		.resources = locomo_lt_resources,
> +		.num_resources = ARRAY_SIZE(locomo_lt_resources),
> +	},
> +	{
> +		.name = "locomo-spi",
> +		.resources = locomo_spi_resources,
> +		.num_resources = ARRAY_SIZE(locomo_spi_resources),
> +	},
> +	{
> +		.name = "locomo-led",
> +	},
> +	{
> +		.name = "locomo-backlight",
> +	},

Please make these:

> +	{ .name = "locomo-led" },
> +	{ .name = "locomo-backlight" },

... and put them at the bottom.

> +	{
> +		.name = "locomo-lcd",
> +		.platform_data = &locomo_lcd_pdata,
> +		.pdata_size = sizeof(locomo_lcd_pdata),
> +	},
> +	{
> +		.name = "locomo-i2c",
> +	},
> +};
> +
> +/* IRQ support */
> +static void locomo_handler(unsigned int irq, struct irq_desc *desc)
> +{
> +	struct locomo *lchip = irq_get_handler_data(irq);
> +	struct irq_chip *irqchip = irq_desc_get_chip(desc);
> +	unsigned int req;
> +
> +	chained_irq_enter(irqchip, desc);
> +
> +	/* check why this interrupt was generated */

Start comments with an uppercase character.

> +	while (1) {
> +		regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> +		req &= 0x0f00;

What is this magic number?  Please #define it.

> +		if (!req)
> +			break;
> +
> +		irq = ffs(req) - 9;

Minus another random number?  Either define it or enter a comment.

> +		generic_handle_irq(irq_find_mapping(lchip->domain, irq));
> +	}
> +
> +	chained_irq_exit(irqchip, desc);
> +}
> +
> +static void locomo_ack_irq(struct irq_data *d)
> +{
> +}

Not sure you need this.  Please check.

If you do, please fix the caller, as it should be checked for NULL
prior to invocation.

> +static void locomo_mask_irq(struct irq_data *d)
> +{
> +	struct locomo *lchip = irq_data_get_irq_chip_data(d);
> +
> +	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
> +		0x0010 << d->hwirq,
> +		0);

Why the forced line break here.

More magic numbers -- please define.

> +}
> +
> +static void locomo_unmask_irq(struct irq_data *d)
> +{
> +	struct locomo *lchip = irq_data_get_irq_chip_data(d);
> +
> +	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
> +		(0x0010 << d->hwirq),
> +		(0x0010 << d->hwirq));

This looks hacky.  Please define a proper mask and value.

> +}
> +
> +static struct irq_chip locomo_chip = {
> +	.name		= "LOCOMO",

Any reason why this has to be uppercase?

> +	.irq_ack	= locomo_ack_irq,
> +	.irq_mask	= locomo_mask_irq,
> +	.irq_unmask	= locomo_unmask_irq,
> +};
> +
> +static int locomo_irq_map(struct irq_domain *d, unsigned int virq,
> +				irq_hw_number_t hwirq)
> +{
> +	struct locomo *locomo = d->host_data;
> +
> +	irq_set_chip_data(virq, locomo);
> +	irq_set_chip_and_handler(virq, &locomo_chip,
> +				handle_level_irq);
> +	set_irq_flags(virq, IRQF_VALID);
> +
> +	return 0;
> +}
> +
> +static void locomo_irq_unmap(struct irq_domain *d, unsigned int virq)
> +{
> +	set_irq_flags(virq, 0);
> +	irq_set_chip_and_handler(virq, NULL, NULL);
> +	irq_set_chip_data(virq, NULL);
> +}
> +
> +static struct irq_domain_ops locomo_irq_ops = {
> +	.map    = locomo_irq_map,
> +	.unmap  = locomo_irq_unmap,
> +	.xlate  = irq_domain_xlate_onecell,
> +};
> +
> +static int locomo_setup_irq(struct locomo *lchip)
> +{
> +	lchip->domain = irq_domain_add_simple(NULL, LOCOMO_NR_IRQS, 0,
> +			&locomo_irq_ops, lchip);

Please line up line breaks with the '('.

> +	if (!lchip->domain) {
> +		dev_err(lchip->dev, "Failed to register irqdomain\n");

No need for this.  The IRQ domain handling with print one out for you.

> +		return -ENOMEM;
> +	}
> +
> +	/*
> +	 * Install handler for IRQ_LOCOMO_HW.
> +	 */
> +	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
> +	irq_set_handler_data(lchip->irq, lchip);
> +	irq_set_chained_handler(lchip->irq, locomo_handler);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int locomo_suspend(struct device *dev)
> +{
> +	struct locomo *lchip = dev_get_drvdata(dev);
> +
> +	/* AUDIO */

WHY ARE YOU SHOUTING?  Ironic eh? ;)

> +	regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> +
> +	/*
> +	 * Original code disabled the clock depending on leds settings
> +	 * However we disable leds before suspend, thus it's safe
> +	 * to just assume this setting.
> +	 */
> +	/* CLK32 off */
> +	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> +
> +	/* 22MHz/24MHz clock off */
> +	regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> +
> +	return 0;
> +}
> +
> +static int locomo_resume(struct device *dev)
> +{
> +	struct locomo *lchip = dev_get_drvdata(dev);

Do audio and clk sort themselves out?

> +	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(locomo_pm, locomo_suspend, locomo_resume);

Put this outside of CONFIG_PM_SLEEP and SIMPLE_DEV_PM_OPS() will take
care of this for you.

> +#define LOCOMO_PM	(&locomo_pm)
> +
> +#else
> +#define LOCOMO_PM/	NULL

This you can remove all of this.

> +#endif
> +
> +static const struct regmap_config locomo_regmap_config = {
> +	.name = "LoCoMo",
> +	.reg_bits = 8,
> +	.reg_stride = 4,
> +	.val_bits = 16,
> +	.cache_type = REGCACHE_NONE,
> +	.max_register = 0xec,
> +};
> +
> +static int locomo_probe(struct platform_device *dev)

s/dev/pdev/

dev is usually used for 'struct device' pointers.

> +{
> +	struct locomo_platform_data *pdata = dev_get_platdata(&dev->dev);
> +	struct resource *mem;

Nit: res is more commonplace.

> +	void __iomem *base;
> +	struct locomo *lchip;

I always quite like ldev.

> +	unsigned int r;

r is not a good variable name.

> +	int ret = -ENODEV;

No need to initialise.

> +	lchip = devm_kzalloc(&dev->dev, sizeof(struct locomo), GFP_KERNEL);

s/struct locomo/*lchip/

> +	if (!lchip)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&lchip->lock);
> +	lchip->dev = &dev->dev;
> +
> +	lchip->irq = platform_get_irq(dev, 0);
> +	if (lchip->irq < 0)
> +		return -ENXIO;

Why are you making up your own return codes?

return lchip->irq;

> +	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&dev->dev, mem);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	lchip->regmap = devm_regmap_init_mmio(&dev->dev, base,
> +			&locomo_regmap_config);

Line up with '('.

> +	if (IS_ERR(lchip->regmap))
> +		return PTR_ERR(lchip->regmap);
> +
> +	if (pdata) {
> +		locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> +		locomo_lcd_pdata.comadj = pdata->comadj;
> +	} else {
> +		locomo_gpio_pdata.gpio_base = -1;
> +		locomo_lcd_pdata.comadj = 128;
> +	}

struct locomo_gpio_platform_data locomo_gpio_pdata;

locomo_gpio_pdata = devm_kzalloc(<blah>);

locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

> +	platform_set_drvdata(dev, lchip);
> +
> +	regmap_read(lchip->regmap, LOCOMO_VER, &r);
> +	dev_info(&dev->dev, "LoCoMo Chip: %04x\n", r);

s/r/rev/

or

s/r/id/

> +	/* locomo initialize */
> +	regmap_write(lchip->regmap, LOCOMO_ICR, 0);

What does initialize mean?  Enable? Reset IRQs? Reset chip?

> +	/* Longtime timer */
> +	regmap_write(lchip->regmap, LOCOMO_LTINT, 0);
> +
> +	/*
> +	 * The interrupt controller must be initialised before any
> +	 * other device to ensure that the interrupts are available.
> +	 */

That's pretty normal isn't it?

> +	ret = locomo_setup_irq(lchip);
> +	if (ret < 0)
> +		goto err_add;

What if ret > 0?

Suggest:
  if (ret)

> +	ret = mfd_add_devices(&dev->dev, dev->id,
> +			locomo_cells, ARRAY_SIZE(locomo_cells),
> +			mem, -1, lchip->domain);

s/mem/base/

> +	if (ret)
> +		goto err_add;
> +
> +	return 0;
> +
> +err_add:

What does err_add mean?

> +	irq_set_chained_handler(lchip->irq, NULL);
> +	irq_set_handler_data(lchip->irq, NULL);
> +	if (lchip->domain)
> +		irq_domain_remove(lchip->domain);
> +
> +	return ret;
> +}
> +
> +static int locomo_remove(struct platform_device *dev)
> +{
> +	struct locomo *lchip = platform_get_drvdata(dev);
> +
> +	if (!lchip)
> +		return 0;

Is that even possible?

> +	mfd_remove_devices(&dev->dev);
> +
> +	irq_set_chained_handler(lchip->irq, NULL);
> +	irq_set_handler_data(lchip->irq, NULL);

'\n'

> +	if (lchip->domain)
> +		irq_domain_remove(lchip->domain);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver locomo_device_driver = {
> +	.probe		= locomo_probe,
> +	.remove		= locomo_remove,
> +	.driver		= {
> +		.name	= "locomo",
> +		.pm	= LOCOMO_PM,
> +	},
> +};

Lining these up looks weird.  Especially as the stuff in .driver is
*meant* to be indented.

> +module_platform_driver(locomo_device_driver);
> +
> +MODULE_DESCRIPTION("Sharp LoCoMo core driver");
> +MODULE_LICENSE("GPL");

GPL v2

> +MODULE_AUTHOR("John Lenz <lenz-hcNo3dDEHLuVc3sceRu5cw@public.gmane.org>");
> +MODULE_ALIAS("platform:locomo");
> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> new file mode 100644
> index 0000000..6729767
> --- /dev/null
> +++ b/include/linux/mfd/locomo.h

This whole file needs a jolly good tidy-up.

> @@ -0,0 +1,173 @@
> +/*
> + * include/linux/mfd/locomo.h

Remove this.  We know what file it's in.

> + * This file contains the definitions for the LoCoMo G/A Chip
> + *
> + * (C) Copyright 2004 John Lenz

This is out of date.

> + * May be copied or modified under the terms of the GNU General Public
> + * License.  See linux/COPYING for more information.
> + *
> + * Based on sa1111.h
> + */

'/n'

> +#ifndef _ASM_ARCH_LOCOMO
> +#define _ASM_ARCH_LOCOMO
> +
> +/* LOCOMO version */
> +#define LOCOMO_VER	0x00

This is misleading.

The version is not 0, this is the register address.

> +/* Pin status */
> +#define LOCOMO_ST	0x04
> +
> +/* Pin status */
> +#define LOCOMO_C32K	0x08
> +
> +/* Interrupt controller */
> +#define LOCOMO_ICR	0x0C
> +
> +/* MCS decoder for boot selecting */
> +#define LOCOMO_MCSX0	0x10
> +#define LOCOMO_MCSX1	0x14
> +#define LOCOMO_MCSX2	0x18
> +#define LOCOMO_MCSX3	0x1c

These are pretty cryptic.  Any way of making them easier to identify.

> +/* Touch panel controller */
> +#define LOCOMO_ASD	0x20		/* AD start delay */
> +#define LOCOMO_HSD	0x28		/* HSYS delay */
> +#define LOCOMO_HSC	0x2c		/* HSYS period */
> +#define LOCOMO_TADC	0x30		/* tablet ADC clock */
> +
> +/* Backlight controller: TFT signal */
> +#define LOCOMO_TC	0x38		/* TFT control signal */
> +#define LOCOMO_CPSD	0x3c		/* CPS delay */
> +
> +/* Keyboard controller */
> +#define LOCOMO_KIB	0x40	/* KIB level */
> +#define LOCOMO_KSC	0x44	/* KSTRB control */
> +#define LOCOMO_KCMD	0x48	/* KSTRB command */
> +#define LOCOMO_KIC	0x4c	/* Key interrupt */
> +
> +/* Audio clock */
> +#define LOCOMO_ACC	0x54	/* Audio clock */
> +#define	LOCOMO_ACC_XON		0x80
> +#define	LOCOMO_ACC_XEN		0x40
> +#define	LOCOMO_ACC_XSEL0	0x00
> +#define	LOCOMO_ACC_XSEL1	0x20
> +#define	LOCOMO_ACC_MCLKEN	0x10
> +#define	LOCOMO_ACC_64FSEN	0x08
> +#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
> +#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
> +#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
> +#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
> +#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
> +#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */

I think you have an issue with spaces and tabs here.

> +/* SPI interface */
> +#define LOCOMO_SPIMD	0x60		/* SPI mode setting */
> +#define LOCOMO_SPIMD_LOOPBACK (1 << 15)	/* loopback tx to rx */

Use BIT() for all '1 <<'s.

> +#define LOCOMO_SPIMD_MSB1ST   (1 << 14)	/* send MSB first */
> +#define LOCOMO_SPIMD_DOSTAT   (1 << 13)	/* transmit line is idle high */
> +#define LOCOMO_SPIMD_TCPOL    (1 << 11)	/* transmit CPOL (maybe affects CPHA) */
> +#define LOCOMO_SPIMD_RCPOL    (1 << 10)	/* receive CPOL (maybe affects CPHA) */
> +#define	LOCOMO_SPIMD_TDINV    (1 << 9)	/* invert transmit line */

Why is this different?

> +#define LOCOMO_SPIMD_RDINV    (1 << 8)	/* invert receive line */
> +#define LOCOMO_SPIMD_XON      (1 << 7)	/* enable spi controller clock */
> +#define LOCOMO_SPIMD_XEN      (1 << 6)	/* clock bit write enable */
> +#define LOCOMO_SPIMD_XSEL     0x0018	/* clock select */
> +/* xon must be off when enabling xen, wait 300 us before xon -> 1 */
> +#define CLOCK_18MHZ	    0		/* 18,432 MHz clock */
> +#define CLOCK_22MHZ	    1		/* 22,5792 MHz clock */
> +#define CLOCK_25MHZ	    2		/* 24,576 MHz clock */
> +#define LOCOMO_SPIMD_CLKSEL   0x7
> +#define DIV_1		    0		/* don't divide clock   */
> +#define DIV_2		    1		/* divide clock by two	*/
> +#define DIV_4		    2		/* divide clock by four */
> +#define DIV_8		    3		/* divide clock by eight*/
> +#define DIV_64		    4		/* divide clock by 64 */

Better to line all of these up along with the rest of the file.

> +#define LOCOMO_SPICT	0x64		/* SPI mode control */
> +#define LOCOMO_SPICT_CRC16_7_B	(1 << 15)	/* 0: crc16 1: crc7 */
> +#define LOCOMO_SPICT_CRCRX_TX_B	(1 << 14)
> +#define LOCOMO_SPICT_CRCRESET_B	(1 << 13)
> +#define LOCOMO_SPICT_CEN	(1 << 7)	/* ?? enable */
> +#define LOCOMO_SPICT_CS		(1 << 6)	/* chip select */
> +#define LOCOMO_SPICT_UNIT16	(1 << 5)	/* 0: 8 bit, 1: 16 bit*/
> +#define LOCOMO_SPICT_ALIGNEN	(1 << 2)	/* align transfer enable */
> +#define LOCOMO_SPICT_RXWEN	(1 << 1)	/* continuous receive */
> +#define LOCOMO_SPICT_RXUEN	(1 << 0)	/* aligned receive */
> +
> +#define LOCOMO_SPIST	0x68		/* SPI status */
> +#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
> +#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
> +#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
> +#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
> +
> +#define LOCOMO_SPIIS	0x70		/* SPI interrupt status */
> +#define LOCOMO_SPIWE	0x74		/* SPI interrupt status write enable */
> +#define LOCOMO_SPIIE	0x78		/* SPI interrupt enable */
> +#define LOCOMO_SPIIR	0x7c		/* SPI interrupt request */
> +#define LOCOMO_SPITD	0x80		/* SPI transfer data write */
> +#define LOCOMO_SPIRD	0x84		/* SPI receive data read */
> +#define LOCOMO_SPITS	0x88		/* SPI transfer data shift */
> +#define LOCOMO_SPIRS	0x8C		/* SPI receive data shift */
> +
> +/* GPIO */
> +#define LOCOMO_GPD	0x90	/* GPIO direction */
> +#define LOCOMO_GPE	0x94	/* GPIO input enable */
> +#define LOCOMO_GPL	0x98	/* GPIO level */
> +#define LOCOMO_GPO	0x9c	/* GPIO out data setting */
> +#define LOCOMO_GRIE	0xa0	/* GPIO rise detection */
> +#define LOCOMO_GFIE	0xa4	/* GPIO fall detection */
> +#define LOCOMO_GIS	0xa8	/* GPIO edge detection status */
> +#define LOCOMO_GWE	0xac	/* GPIO status write enable */
> +#define LOCOMO_GIE	0xb0	/* GPIO interrupt enable */
> +#define LOCOMO_GIR	0xb4	/* GPIO interrupt request */
> +
> +/* Front light adjustment controller */
> +#define LOCOMO_ALS	0xc8	/* Adjust light cycle */
> +#define LOCOMO_ALS_EN		0x8000
> +#define LOCOMO_ALD	0xcc	/* Adjust light duty */
> +
> +/* PCM audio interface */
> +#define LOCOMO_PAIF	0xd0	/* PCM audio interface */
> +#define	LOCOMO_PAIF_SCINV	0x20
> +#define	LOCOMO_PAIF_SCEN	0x10
> +#define	LOCOMO_PAIF_LRCRST	0x08
> +#define	LOCOMO_PAIF_LRCEVE	0x04
> +#define	LOCOMO_PAIF_LRCINV	0x02
> +#define	LOCOMO_PAIF_LRCEN	0x01
> +
> +/* Long time timer */
> +#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
> +#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
> +
> +/* DAC control signal for LCD (COMADJ ) */
> +#define LOCOMO_DAC	0xe0
> +/* DAC control */
> +#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
> +#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
> +#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
> +#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
> +
> +/* LED controller */
> +#define LOCOMO_LPT0	0xe8
> +#define LOCOMO_LPT1	0xec
> +#define LOCOMO_LPT_TOFH		0x80
> +#define LOCOMO_LPT_TOFL		0x08
> +#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
> +#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
> +
> +struct locomo_gpio_platform_data {
> +	unsigned int gpio_base;
> +};

A struct for a single int seems overkill.

> +struct locomo_lcd_platform_data {
> +	u8 comadj;
> +};
> +
> +struct locomo_platform_data {
> +	unsigned int gpio_base;
> +	u8 comadj;
> +};

Why do you need to pass gpio_base twice?

> +#endif

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-04-28 18:45       ` Lee Jones
  0 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-04-28 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:

> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> several design issues (special bus instead of platform bus, doesn't use
> mfd-core, etc).
> 
> Implement 'core' parts of locomo support as an mfd driver.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/mfd/Kconfig        |  10 ++
>  drivers/mfd/Makefile       |   1 +
>  drivers/mfd/locomo.c       | 356 +++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/locomo.h | 173 ++++++++++++++++++++++
>  4 files changed, 540 insertions(+)
>  create mode 100644 drivers/mfd/locomo.c
>  create mode 100644 include/linux/mfd/locomo.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index d5ad04d..8c33940 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1430,6 +1430,16 @@ config MFD_STW481X
>  	  in various ST Microelectronics and ST-Ericsson embedded
>  	  Nomadik series.
>  
> +config MFD_LOCOMO
> +	bool "Sharp LoCoMo support"
> +	depends on ARM
> +	select MFD_CORE
> +	select IRQ_DOMAIN
> +	select REGMAP_MMIO
> +	help
> +	  Support for Sharp LoCoMo Grid Array found in Sharp SL-5x00
> +          PDA family.

Are people really still using this stuff?

>  menu "Multimedia Capabilities Port drivers"
>  	depends on ARCH_SA1100
>  
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 0e5cfeb..6c23b73 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -181,6 +181,7 @@ obj-$(CONFIG_MFD_HI6421_PMIC)	+= hi6421-pmic-core.o
>  obj-$(CONFIG_MFD_DLN2)		+= dln2.o
>  obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
>  obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
> +obj-$(CONFIG_MFD_LOCOMO)	+= locomo.o
>  
>  intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
>  obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
> diff --git a/drivers/mfd/locomo.c b/drivers/mfd/locomo.c
> new file mode 100644
> index 0000000..f981c94
> --- /dev/null
> +++ b/drivers/mfd/locomo.c
> @@ -0,0 +1,356 @@
> +/*
> + * Sharp LoCoMo support
> + *
> + * Based on old driver at arch/arm/common/locomo.c
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains all generic LoCoMo support.
> + *
> + * All initialization functions provided here are intended to be called
> + * from machine specific code with proper arguments when required.
> + */

'\n'

> +#include <linux/delay.h>
> +#include <linux/gpio.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/core.h>
> +#include <linux/mfd/locomo.h>
> +
> +/* LoCoMo Interrupts */
> +#define IRQ_LOCOMO_KEY		(0)
> +#define IRQ_LOCOMO_GPIO		(1)
> +#define IRQ_LOCOMO_LT		(2)
> +#define IRQ_LOCOMO_SPI		(3)
> +
> +#define LOCOMO_NR_IRQS		(4)

No need for all this added () protection.

> +/* the following is the overall data for the locomo chip */
> +struct locomo {
> +	struct device *dev;
> +	unsigned int irq;
> +	spinlock_t lock;
> +	struct irq_domain *domain;
> +	struct regmap *regmap;
> +};
> +
> +static struct resource locomo_kbd_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> +};
> +
> +static struct resource locomo_gpio_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> +};
> +
> +/* Filled in locomo_probe() function. */
> +static struct locomo_gpio_platform_data locomo_gpio_pdata;

I'd prefer you didn't use globals for this.

> +static struct resource locomo_lt_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> +};
> +
> +static struct resource locomo_spi_resources[] = {
> +	DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> +};
> +
> +/* Filled in locomo_probe() function. */
> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> +
> +static struct mfd_cell locomo_cells[] = {
> +	{
> +		.name = "locomo-kbd",
> +		.resources = locomo_kbd_resources,
> +		.num_resources = ARRAY_SIZE(locomo_kbd_resources),
> +	},
> +	{
> +		.name = "locomo-gpio",
> +		.resources = locomo_gpio_resources,
> +		.num_resources = ARRAY_SIZE(locomo_gpio_resources),
> +		.platform_data = &locomo_gpio_pdata,
> +		.pdata_size = sizeof(locomo_gpio_pdata),
> +	},
> +	{
> +		.name = "locomo-lt", /* Long time timer */
> +		.resources = locomo_lt_resources,
> +		.num_resources = ARRAY_SIZE(locomo_lt_resources),
> +	},
> +	{
> +		.name = "locomo-spi",
> +		.resources = locomo_spi_resources,
> +		.num_resources = ARRAY_SIZE(locomo_spi_resources),
> +	},
> +	{
> +		.name = "locomo-led",
> +	},
> +	{
> +		.name = "locomo-backlight",
> +	},

Please make these:

> +	{ .name = "locomo-led" },
> +	{ .name = "locomo-backlight" },

... and put them at the bottom.

> +	{
> +		.name = "locomo-lcd",
> +		.platform_data = &locomo_lcd_pdata,
> +		.pdata_size = sizeof(locomo_lcd_pdata),
> +	},
> +	{
> +		.name = "locomo-i2c",
> +	},
> +};
> +
> +/* IRQ support */
> +static void locomo_handler(unsigned int irq, struct irq_desc *desc)
> +{
> +	struct locomo *lchip = irq_get_handler_data(irq);
> +	struct irq_chip *irqchip = irq_desc_get_chip(desc);
> +	unsigned int req;
> +
> +	chained_irq_enter(irqchip, desc);
> +
> +	/* check why this interrupt was generated */

Start comments with an uppercase character.

> +	while (1) {
> +		regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> +		req &= 0x0f00;

What is this magic number?  Please #define it.

> +		if (!req)
> +			break;
> +
> +		irq = ffs(req) - 9;

Minus another random number?  Either define it or enter a comment.

> +		generic_handle_irq(irq_find_mapping(lchip->domain, irq));
> +	}
> +
> +	chained_irq_exit(irqchip, desc);
> +}
> +
> +static void locomo_ack_irq(struct irq_data *d)
> +{
> +}

Not sure you need this.  Please check.

If you do, please fix the caller, as it should be checked for NULL
prior to invocation.

> +static void locomo_mask_irq(struct irq_data *d)
> +{
> +	struct locomo *lchip = irq_data_get_irq_chip_data(d);
> +
> +	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
> +		0x0010 << d->hwirq,
> +		0);

Why the forced line break here.

More magic numbers -- please define.

> +}
> +
> +static void locomo_unmask_irq(struct irq_data *d)
> +{
> +	struct locomo *lchip = irq_data_get_irq_chip_data(d);
> +
> +	regmap_update_bits(lchip->regmap, LOCOMO_ICR,
> +		(0x0010 << d->hwirq),
> +		(0x0010 << d->hwirq));

This looks hacky.  Please define a proper mask and value.

> +}
> +
> +static struct irq_chip locomo_chip = {
> +	.name		= "LOCOMO",

Any reason why this has to be uppercase?

> +	.irq_ack	= locomo_ack_irq,
> +	.irq_mask	= locomo_mask_irq,
> +	.irq_unmask	= locomo_unmask_irq,
> +};
> +
> +static int locomo_irq_map(struct irq_domain *d, unsigned int virq,
> +				irq_hw_number_t hwirq)
> +{
> +	struct locomo *locomo = d->host_data;
> +
> +	irq_set_chip_data(virq, locomo);
> +	irq_set_chip_and_handler(virq, &locomo_chip,
> +				handle_level_irq);
> +	set_irq_flags(virq, IRQF_VALID);
> +
> +	return 0;
> +}
> +
> +static void locomo_irq_unmap(struct irq_domain *d, unsigned int virq)
> +{
> +	set_irq_flags(virq, 0);
> +	irq_set_chip_and_handler(virq, NULL, NULL);
> +	irq_set_chip_data(virq, NULL);
> +}
> +
> +static struct irq_domain_ops locomo_irq_ops = {
> +	.map    = locomo_irq_map,
> +	.unmap  = locomo_irq_unmap,
> +	.xlate  = irq_domain_xlate_onecell,
> +};
> +
> +static int locomo_setup_irq(struct locomo *lchip)
> +{
> +	lchip->domain = irq_domain_add_simple(NULL, LOCOMO_NR_IRQS, 0,
> +			&locomo_irq_ops, lchip);

Please line up line breaks with the '('.

> +	if (!lchip->domain) {
> +		dev_err(lchip->dev, "Failed to register irqdomain\n");

No need for this.  The IRQ domain handling with print one out for you.

> +		return -ENOMEM;
> +	}
> +
> +	/*
> +	 * Install handler for IRQ_LOCOMO_HW.
> +	 */
> +	irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
> +	irq_set_handler_data(lchip->irq, lchip);
> +	irq_set_chained_handler(lchip->irq, locomo_handler);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int locomo_suspend(struct device *dev)
> +{
> +	struct locomo *lchip = dev_get_drvdata(dev);
> +
> +	/* AUDIO */

WHY ARE YOU SHOUTING?  Ironic eh? ;)

> +	regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> +
> +	/*
> +	 * Original code disabled the clock depending on leds settings
> +	 * However we disable leds before suspend, thus it's safe
> +	 * to just assume this setting.
> +	 */
> +	/* CLK32 off */
> +	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> +
> +	/* 22MHz/24MHz clock off */
> +	regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> +
> +	return 0;
> +}
> +
> +static int locomo_resume(struct device *dev)
> +{
> +	struct locomo *lchip = dev_get_drvdata(dev);

Do audio and clk sort themselves out?

> +	regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(locomo_pm, locomo_suspend, locomo_resume);

Put this outside of CONFIG_PM_SLEEP and SIMPLE_DEV_PM_OPS() will take
care of this for you.

> +#define LOCOMO_PM	(&locomo_pm)
> +
> +#else
> +#define LOCOMO_PM/	NULL

This you can remove all of this.

> +#endif
> +
> +static const struct regmap_config locomo_regmap_config = {
> +	.name = "LoCoMo",
> +	.reg_bits = 8,
> +	.reg_stride = 4,
> +	.val_bits = 16,
> +	.cache_type = REGCACHE_NONE,
> +	.max_register = 0xec,
> +};
> +
> +static int locomo_probe(struct platform_device *dev)

s/dev/pdev/

dev is usually used for 'struct device' pointers.

> +{
> +	struct locomo_platform_data *pdata = dev_get_platdata(&dev->dev);
> +	struct resource *mem;

Nit: res is more commonplace.

> +	void __iomem *base;
> +	struct locomo *lchip;

I always quite like ldev.

> +	unsigned int r;

r is not a good variable name.

> +	int ret = -ENODEV;

No need to initialise.

> +	lchip = devm_kzalloc(&dev->dev, sizeof(struct locomo), GFP_KERNEL);

s/struct locomo/*lchip/

> +	if (!lchip)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&lchip->lock);
> +	lchip->dev = &dev->dev;
> +
> +	lchip->irq = platform_get_irq(dev, 0);
> +	if (lchip->irq < 0)
> +		return -ENXIO;

Why are you making up your own return codes?

return lchip->irq;

> +	mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
> +	base = devm_ioremap_resource(&dev->dev, mem);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	lchip->regmap = devm_regmap_init_mmio(&dev->dev, base,
> +			&locomo_regmap_config);

Line up with '('.

> +	if (IS_ERR(lchip->regmap))
> +		return PTR_ERR(lchip->regmap);
> +
> +	if (pdata) {
> +		locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> +		locomo_lcd_pdata.comadj = pdata->comadj;
> +	} else {
> +		locomo_gpio_pdata.gpio_base = -1;
> +		locomo_lcd_pdata.comadj = 128;
> +	}

struct locomo_gpio_platform_data locomo_gpio_pdata;

locomo_gpio_pdata = devm_kzalloc(<blah>);

locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

> +	platform_set_drvdata(dev, lchip);
> +
> +	regmap_read(lchip->regmap, LOCOMO_VER, &r);
> +	dev_info(&dev->dev, "LoCoMo Chip: %04x\n", r);

s/r/rev/

or

s/r/id/

> +	/* locomo initialize */
> +	regmap_write(lchip->regmap, LOCOMO_ICR, 0);

What does initialize mean?  Enable? Reset IRQs? Reset chip?

> +	/* Longtime timer */
> +	regmap_write(lchip->regmap, LOCOMO_LTINT, 0);
> +
> +	/*
> +	 * The interrupt controller must be initialised before any
> +	 * other device to ensure that the interrupts are available.
> +	 */

That's pretty normal isn't it?

> +	ret = locomo_setup_irq(lchip);
> +	if (ret < 0)
> +		goto err_add;

What if ret > 0?

Suggest:
  if (ret)

> +	ret = mfd_add_devices(&dev->dev, dev->id,
> +			locomo_cells, ARRAY_SIZE(locomo_cells),
> +			mem, -1, lchip->domain);

s/mem/base/

> +	if (ret)
> +		goto err_add;
> +
> +	return 0;
> +
> +err_add:

What does err_add mean?

> +	irq_set_chained_handler(lchip->irq, NULL);
> +	irq_set_handler_data(lchip->irq, NULL);
> +	if (lchip->domain)
> +		irq_domain_remove(lchip->domain);
> +
> +	return ret;
> +}
> +
> +static int locomo_remove(struct platform_device *dev)
> +{
> +	struct locomo *lchip = platform_get_drvdata(dev);
> +
> +	if (!lchip)
> +		return 0;

Is that even possible?

> +	mfd_remove_devices(&dev->dev);
> +
> +	irq_set_chained_handler(lchip->irq, NULL);
> +	irq_set_handler_data(lchip->irq, NULL);

'\n'

> +	if (lchip->domain)
> +		irq_domain_remove(lchip->domain);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver locomo_device_driver = {
> +	.probe		= locomo_probe,
> +	.remove		= locomo_remove,
> +	.driver		= {
> +		.name	= "locomo",
> +		.pm	= LOCOMO_PM,
> +	},
> +};

Lining these up looks weird.  Especially as the stuff in .driver is
*meant* to be indented.

> +module_platform_driver(locomo_device_driver);
> +
> +MODULE_DESCRIPTION("Sharp LoCoMo core driver");
> +MODULE_LICENSE("GPL");

GPL v2

> +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> +MODULE_ALIAS("platform:locomo");
> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> new file mode 100644
> index 0000000..6729767
> --- /dev/null
> +++ b/include/linux/mfd/locomo.h

This whole file needs a jolly good tidy-up.

> @@ -0,0 +1,173 @@
> +/*
> + * include/linux/mfd/locomo.h

Remove this.  We know what file it's in.

> + * This file contains the definitions for the LoCoMo G/A Chip
> + *
> + * (C) Copyright 2004 John Lenz

This is out of date.

> + * May be copied or modified under the terms of the GNU General Public
> + * License.  See linux/COPYING for more information.
> + *
> + * Based on sa1111.h
> + */

'/n'

> +#ifndef _ASM_ARCH_LOCOMO
> +#define _ASM_ARCH_LOCOMO
> +
> +/* LOCOMO version */
> +#define LOCOMO_VER	0x00

This is misleading.

The version is not 0, this is the register address.

> +/* Pin status */
> +#define LOCOMO_ST	0x04
> +
> +/* Pin status */
> +#define LOCOMO_C32K	0x08
> +
> +/* Interrupt controller */
> +#define LOCOMO_ICR	0x0C
> +
> +/* MCS decoder for boot selecting */
> +#define LOCOMO_MCSX0	0x10
> +#define LOCOMO_MCSX1	0x14
> +#define LOCOMO_MCSX2	0x18
> +#define LOCOMO_MCSX3	0x1c

These are pretty cryptic.  Any way of making them easier to identify.

> +/* Touch panel controller */
> +#define LOCOMO_ASD	0x20		/* AD start delay */
> +#define LOCOMO_HSD	0x28		/* HSYS delay */
> +#define LOCOMO_HSC	0x2c		/* HSYS period */
> +#define LOCOMO_TADC	0x30		/* tablet ADC clock */
> +
> +/* Backlight controller: TFT signal */
> +#define LOCOMO_TC	0x38		/* TFT control signal */
> +#define LOCOMO_CPSD	0x3c		/* CPS delay */
> +
> +/* Keyboard controller */
> +#define LOCOMO_KIB	0x40	/* KIB level */
> +#define LOCOMO_KSC	0x44	/* KSTRB control */
> +#define LOCOMO_KCMD	0x48	/* KSTRB command */
> +#define LOCOMO_KIC	0x4c	/* Key interrupt */
> +
> +/* Audio clock */
> +#define LOCOMO_ACC	0x54	/* Audio clock */
> +#define	LOCOMO_ACC_XON		0x80
> +#define	LOCOMO_ACC_XEN		0x40
> +#define	LOCOMO_ACC_XSEL0	0x00
> +#define	LOCOMO_ACC_XSEL1	0x20
> +#define	LOCOMO_ACC_MCLKEN	0x10
> +#define	LOCOMO_ACC_64FSEN	0x08
> +#define	LOCOMO_ACC_CLKSEL000	0x00	/* mclk  2 */
> +#define	LOCOMO_ACC_CLKSEL001	0x01	/* mclk  3 */
> +#define	LOCOMO_ACC_CLKSEL010	0x02	/* mclk  4 */
> +#define	LOCOMO_ACC_CLKSEL011	0x03	/* mclk  6 */
> +#define	LOCOMO_ACC_CLKSEL100	0x04	/* mclk  8 */
> +#define	LOCOMO_ACC_CLKSEL101	0x05	/* mclk 12 */

I think you have an issue with spaces and tabs here.

> +/* SPI interface */
> +#define LOCOMO_SPIMD	0x60		/* SPI mode setting */
> +#define LOCOMO_SPIMD_LOOPBACK (1 << 15)	/* loopback tx to rx */

Use BIT() for all '1 <<'s.

> +#define LOCOMO_SPIMD_MSB1ST   (1 << 14)	/* send MSB first */
> +#define LOCOMO_SPIMD_DOSTAT   (1 << 13)	/* transmit line is idle high */
> +#define LOCOMO_SPIMD_TCPOL    (1 << 11)	/* transmit CPOL (maybe affects CPHA) */
> +#define LOCOMO_SPIMD_RCPOL    (1 << 10)	/* receive CPOL (maybe affects CPHA) */
> +#define	LOCOMO_SPIMD_TDINV    (1 << 9)	/* invert transmit line */

Why is this different?

> +#define LOCOMO_SPIMD_RDINV    (1 << 8)	/* invert receive line */
> +#define LOCOMO_SPIMD_XON      (1 << 7)	/* enable spi controller clock */
> +#define LOCOMO_SPIMD_XEN      (1 << 6)	/* clock bit write enable */
> +#define LOCOMO_SPIMD_XSEL     0x0018	/* clock select */
> +/* xon must be off when enabling xen, wait 300 us before xon -> 1 */
> +#define CLOCK_18MHZ	    0		/* 18,432 MHz clock */
> +#define CLOCK_22MHZ	    1		/* 22,5792 MHz clock */
> +#define CLOCK_25MHZ	    2		/* 24,576 MHz clock */
> +#define LOCOMO_SPIMD_CLKSEL   0x7
> +#define DIV_1		    0		/* don't divide clock   */
> +#define DIV_2		    1		/* divide clock by two	*/
> +#define DIV_4		    2		/* divide clock by four */
> +#define DIV_8		    3		/* divide clock by eight*/
> +#define DIV_64		    4		/* divide clock by 64 */

Better to line all of these up along with the rest of the file.

> +#define LOCOMO_SPICT	0x64		/* SPI mode control */
> +#define LOCOMO_SPICT_CRC16_7_B	(1 << 15)	/* 0: crc16 1: crc7 */
> +#define LOCOMO_SPICT_CRCRX_TX_B	(1 << 14)
> +#define LOCOMO_SPICT_CRCRESET_B	(1 << 13)
> +#define LOCOMO_SPICT_CEN	(1 << 7)	/* ?? enable */
> +#define LOCOMO_SPICT_CS		(1 << 6)	/* chip select */
> +#define LOCOMO_SPICT_UNIT16	(1 << 5)	/* 0: 8 bit, 1: 16 bit*/
> +#define LOCOMO_SPICT_ALIGNEN	(1 << 2)	/* align transfer enable */
> +#define LOCOMO_SPICT_RXWEN	(1 << 1)	/* continuous receive */
> +#define LOCOMO_SPICT_RXUEN	(1 << 0)	/* aligned receive */
> +
> +#define LOCOMO_SPIST	0x68		/* SPI status */
> +#define	LOCOMO_SPI_TEND	(1 << 3)	/* Transfer end bit */
> +#define	LOCOMO_SPI_REND	(1 << 2)	/* Receive end bit */
> +#define	LOCOMO_SPI_RFW	(1 << 1)	/* write buffer bit */
> +#define	LOCOMO_SPI_RFR	(1)		/* read buffer bit */
> +
> +#define LOCOMO_SPIIS	0x70		/* SPI interrupt status */
> +#define LOCOMO_SPIWE	0x74		/* SPI interrupt status write enable */
> +#define LOCOMO_SPIIE	0x78		/* SPI interrupt enable */
> +#define LOCOMO_SPIIR	0x7c		/* SPI interrupt request */
> +#define LOCOMO_SPITD	0x80		/* SPI transfer data write */
> +#define LOCOMO_SPIRD	0x84		/* SPI receive data read */
> +#define LOCOMO_SPITS	0x88		/* SPI transfer data shift */
> +#define LOCOMO_SPIRS	0x8C		/* SPI receive data shift */
> +
> +/* GPIO */
> +#define LOCOMO_GPD	0x90	/* GPIO direction */
> +#define LOCOMO_GPE	0x94	/* GPIO input enable */
> +#define LOCOMO_GPL	0x98	/* GPIO level */
> +#define LOCOMO_GPO	0x9c	/* GPIO out data setting */
> +#define LOCOMO_GRIE	0xa0	/* GPIO rise detection */
> +#define LOCOMO_GFIE	0xa4	/* GPIO fall detection */
> +#define LOCOMO_GIS	0xa8	/* GPIO edge detection status */
> +#define LOCOMO_GWE	0xac	/* GPIO status write enable */
> +#define LOCOMO_GIE	0xb0	/* GPIO interrupt enable */
> +#define LOCOMO_GIR	0xb4	/* GPIO interrupt request */
> +
> +/* Front light adjustment controller */
> +#define LOCOMO_ALS	0xc8	/* Adjust light cycle */
> +#define LOCOMO_ALS_EN		0x8000
> +#define LOCOMO_ALD	0xcc	/* Adjust light duty */
> +
> +/* PCM audio interface */
> +#define LOCOMO_PAIF	0xd0	/* PCM audio interface */
> +#define	LOCOMO_PAIF_SCINV	0x20
> +#define	LOCOMO_PAIF_SCEN	0x10
> +#define	LOCOMO_PAIF_LRCRST	0x08
> +#define	LOCOMO_PAIF_LRCEVE	0x04
> +#define	LOCOMO_PAIF_LRCINV	0x02
> +#define	LOCOMO_PAIF_LRCEN	0x01
> +
> +/* Long time timer */
> +#define LOCOMO_LTC	0xd8		/* LTC interrupt setting */
> +#define LOCOMO_LTINT	0xdc		/* LTC interrupt */
> +
> +/* DAC control signal for LCD (COMADJ ) */
> +#define LOCOMO_DAC	0xe0
> +/* DAC control */
> +#define	LOCOMO_DAC_SCLOEB	0x08	/* SCL pin output data       */
> +#define	LOCOMO_DAC_TEST		0x04	/* Test bit                  */
> +#define	LOCOMO_DAC_SDA		0x02	/* SDA pin level (read-only) */
> +#define	LOCOMO_DAC_SDAOEB	0x01	/* SDA pin output data       */
> +
> +/* LED controller */
> +#define LOCOMO_LPT0	0xe8
> +#define LOCOMO_LPT1	0xec
> +#define LOCOMO_LPT_TOFH		0x80
> +#define LOCOMO_LPT_TOFL		0x08
> +#define LOCOMO_LPT_TOH(TOH)	((TOH & 0x7) << 4)
> +#define LOCOMO_LPT_TOL(TOL)	((TOL & 0x7))
> +
> +struct locomo_gpio_platform_data {
> +	unsigned int gpio_base;
> +};

A struct for a single int seems overkill.

> +struct locomo_lcd_platform_data {
> +	u8 comadj;
> +};
> +
> +struct locomo_platform_data {
> +	unsigned int gpio_base;
> +	u8 comadj;
> +};

Why do you need to pass gpio_base twice?

> +#endif

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
       [not found]   ` <1430178954-11138-15-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-28 19:35       ` Robert Jarzmik
@ 2015-04-28 19:35       ` Robert Jarzmik
  1 sibling, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:35 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Linus Walleij, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> writes:

> -#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
> -#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
> -#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
> -#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
> -#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
> +#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
I missed that in the v1 serie : why twelve ?

> +#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
> +#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
> +#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
> +#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
> +#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
> +#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
> +#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
> +#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
> +#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
> +#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
Why not keep the LOCOMO_GPIO() defines, and redevice LOCOMO_GPIO(x) to
(POODLE_LOCOMO_GPIO_BASE + (x)) ?

No comments on the remaining part, as long as it's tested, you know me by now
...

Cheers.

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-04-28 19:35       ` Robert Jarzmik
  0 siblings, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:35 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Linus Walleij, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-leds-u79uwXL29TY76Z2rM5mHXA,
	linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw

Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> writes:

> -#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
> -#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
> -#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
> -#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
> -#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
> +#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
I missed that in the v1 serie : why twelve ?

> +#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
> +#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
> +#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
> +#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
> +#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
> +#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
> +#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
> +#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
> +#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
> +#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
Why not keep the LOCOMO_GPIO() defines, and redevice LOCOMO_GPIO(x) to
(POODLE_LOCOMO_GPIO_BASE + (x)) ?

No comments on the remaining part, as long as it's tested, you know me by now
...

Cheers.

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-04-28 19:35       ` Robert Jarzmik
  0 siblings, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:35 UTC (permalink / raw)
  To: linux-arm-kernel

Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> writes:

> -#define POODLE_LOCOMO_GPIO_AMP_ON      LOCOMO_GPIO(8)
> -#define POODLE_LOCOMO_GPIO_MUTE_L      LOCOMO_GPIO(10)
> -#define POODLE_LOCOMO_GPIO_MUTE_R      LOCOMO_GPIO(11)
> -#define POODLE_LOCOMO_GPIO_232VCC_ON   LOCOMO_GPIO(12)
> -#define POODLE_LOCOMO_GPIO_JK_B        LOCOMO_GPIO(13)
> +#define POODLE_LOCOMO_GPIO_BASE	(PXA_NR_BUILTIN_GPIO + 12)
I missed that in the v1 serie : why twelve ?

> +#define POODLE_GPIO_LCD_VSHA_ON	(POODLE_LOCOMO_GPIO_BASE + 4)
> +#define POODLE_GPIO_LCD_VSHD_ON	(POODLE_LOCOMO_GPIO_BASE + 5)
> +#define POODLE_GPIO_LCD_VEE_ON	(POODLE_LOCOMO_GPIO_BASE + 6)
> +#define POODLE_GPIO_LCD_MOD	(POODLE_LOCOMO_GPIO_BASE + 7)
> +#define POODLE_GPIO_AMP_ON	(POODLE_LOCOMO_GPIO_BASE + 8)
> +#define POODLE_GPIO_FL_VR	(POODLE_LOCOMO_GPIO_BASE + 9)
> +#define POODLE_GPIO_MUTE_L	(POODLE_LOCOMO_GPIO_BASE + 10)
> +#define POODLE_GPIO_MUTE_R	(POODLE_LOCOMO_GPIO_BASE + 11)
> +#define POODLE_GPIO_232VCC_ON	(POODLE_LOCOMO_GPIO_BASE + 12)
> +#define POODLE_GPIO_JK_B	(POODLE_LOCOMO_GPIO_BASE + 13)
Why not keep the LOCOMO_GPIO() defines, and redevice LOCOMO_GPIO(x) to
(POODLE_LOCOMO_GPIO_BASE + (x)) ?

No comments on the remaining part, as long as it's tested, you know me by now
...

Cheers.

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-28 19:36     ` Robert Jarzmik
  -1 siblings, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:36 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Linus Walleij, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> writes:

> As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
> space for it on poodle.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
@ 2015-04-28 19:36     ` Robert Jarzmik
  0 siblings, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:36 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Linus Walleij, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> writes:

> As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
> space for it on poodle.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo
@ 2015-04-28 19:36     ` Robert Jarzmik
  0 siblings, 0 replies; 148+ messages in thread
From: Robert Jarzmik @ 2015-04-28 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> writes:

> As new locomo driver supports SPARSE_IRQ, don't preallocate NR_IRQS
> space for it on poodle.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
Acked-by: Robert Jarzmik <robert.jarzmik@free.fr>

-- 
Robert

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/17] spi: add locomo SPI driver
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-04-29 11:27     ` Mark Brown
  -1 siblings, 0 replies; 148+ messages in thread
From: Mark Brown @ 2015-04-29 11:27 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 1408 bytes --]

On Tue, Apr 28, 2015 at 02:55:46AM +0300, Dmitry Eremin-Solenikov wrote:

> +static int locomospi_reg_open(struct locomospi_dev *spidev)
> +{

> +static int locomospi_reg_release(struct locomospi_dev *spidev)
> +{

These are a bit weird - as far as I can tell they're just doing some
init done on probe and release?  I think I'd expect to see them either
inlined there or done as part of the PM operations too (including
runtime ones).

> +	for (j = 0; j < wait; j++) {
> +		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
> +		if (r & LOCOMO_SPI_RFW)
> +			break;
> +	}
> +	if (j == wait)
> +		dev_err(&spi->dev, "rfw timeout\n");

But we don't return an error if we time out?

> +static int locomo_spi_setup_transfer(struct spi_device *spi,
> +		struct spi_transfer *t)
> +{
> +	struct locomospi_dev *spidev;
> +	u32 hz = 0;
> +
> +	if (t)
> +		hz = t->speed_hz;
> +	if (!hz)
> +		hz = spi->max_speed_hz;

The core will set a speed on every transfer for you.

> +	if (!tx && !rx && t->len)
> +		return -EINVAL;

Put this in the core if it's needed.

> +static int locomo_spi_remove(struct platform_device *pdev)
> +{
> +	struct spi_master *master = platform_get_drvdata(pdev);
> +	struct locomospi_dev *spidev = spi_master_get_devdata(master);
> +
> +	return locomospi_reg_release(spidev);

We're doing this release before we free the master which is potentially
racy - but do we even need to do it at all?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 09/17] spi: add locomo SPI driver
@ 2015-04-29 11:27     ` Mark Brown
  0 siblings, 0 replies; 148+ messages in thread
From: Mark Brown @ 2015-04-29 11:27 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 1408 bytes --]

On Tue, Apr 28, 2015 at 02:55:46AM +0300, Dmitry Eremin-Solenikov wrote:

> +static int locomospi_reg_open(struct locomospi_dev *spidev)
> +{

> +static int locomospi_reg_release(struct locomospi_dev *spidev)
> +{

These are a bit weird - as far as I can tell they're just doing some
init done on probe and release?  I think I'd expect to see them either
inlined there or done as part of the PM operations too (including
runtime ones).

> +	for (j = 0; j < wait; j++) {
> +		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
> +		if (r & LOCOMO_SPI_RFW)
> +			break;
> +	}
> +	if (j == wait)
> +		dev_err(&spi->dev, "rfw timeout\n");

But we don't return an error if we time out?

> +static int locomo_spi_setup_transfer(struct spi_device *spi,
> +		struct spi_transfer *t)
> +{
> +	struct locomospi_dev *spidev;
> +	u32 hz = 0;
> +
> +	if (t)
> +		hz = t->speed_hz;
> +	if (!hz)
> +		hz = spi->max_speed_hz;

The core will set a speed on every transfer for you.

> +	if (!tx && !rx && t->len)
> +		return -EINVAL;

Put this in the core if it's needed.

> +static int locomo_spi_remove(struct platform_device *pdev)
> +{
> +	struct spi_master *master = platform_get_drvdata(pdev);
> +	struct locomospi_dev *spidev = spi_master_get_devdata(master);
> +
> +	return locomospi_reg_release(spidev);

We're doing this release before we free the master which is potentially
racy - but do we even need to do it at all?

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 09/17] spi: add locomo SPI driver
@ 2015-04-29 11:27     ` Mark Brown
  0 siblings, 0 replies; 148+ messages in thread
From: Mark Brown @ 2015-04-29 11:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 02:55:46AM +0300, Dmitry Eremin-Solenikov wrote:

> +static int locomospi_reg_open(struct locomospi_dev *spidev)
> +{

> +static int locomospi_reg_release(struct locomospi_dev *spidev)
> +{

These are a bit weird - as far as I can tell they're just doing some
init done on probe and release?  I think I'd expect to see them either
inlined there or done as part of the PM operations too (including
runtime ones).

> +	for (j = 0; j < wait; j++) {
> +		regmap_read(spidev->regmap, LOCOMO_SPIST, &r);
> +		if (r & LOCOMO_SPI_RFW)
> +			break;
> +	}
> +	if (j == wait)
> +		dev_err(&spi->dev, "rfw timeout\n");

But we don't return an error if we time out?

> +static int locomo_spi_setup_transfer(struct spi_device *spi,
> +		struct spi_transfer *t)
> +{
> +	struct locomospi_dev *spidev;
> +	u32 hz = 0;
> +
> +	if (t)
> +		hz = t->speed_hz;
> +	if (!hz)
> +		hz = spi->max_speed_hz;

The core will set a speed on every transfer for you.

> +	if (!tx && !rx && t->len)
> +		return -EINVAL;

Put this in the core if it's needed.

> +static int locomo_spi_remove(struct platform_device *pdev)
> +{
> +	struct spi_master *master = platform_get_drvdata(pdev);
> +	struct locomospi_dev *spidev = spi_master_get_devdata(master);
> +
> +	return locomospi_reg_release(spidev);

We're doing this release before we free the master which is potentially
racy - but do we even need to do it at all?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150429/45f7d423/attachment.sig>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-06 14:12     ` Linus Walleij
  -1 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:12 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Add gpiolib driver for gpio pins placed on the LoCoMo GA.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I assume this will be funneled through the MFD tree?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
@ 2015-05-06 14:12     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:12 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Add gpiolib driver for gpio pins placed on the LoCoMo GA.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I assume this will be funneled through the MFD tree?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver
@ 2015-05-06 14:12     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Add gpiolib driver for gpio pins placed on the LoCoMo GA.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

I assume this will be funneled through the MFD tree?

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-06 14:15     ` Linus Walleij
  -1 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:15 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
> that was there in old locomo driver, got 'cleaned up' during old driver
> IRQ cascading cleanup and is now reimplemented. It is expected that
> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Assume this will also go through MFD.

> +       irq_set_chained_handler(lg->irq, NULL);
> +       irq_set_handler_data(lg->irq, NULL);

Why is this needed? If the GPIOLIB_IRQCHIP code in
gpiolib.c is not doing this then maybe it's the core code that
needs fixing rather than having this in the driver.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-06 14:15     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:15 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
> that was there in old locomo driver, got 'cleaned up' during old driver
> IRQ cascading cleanup and is now reimplemented. It is expected that
> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Assume this will also go through MFD.

> +       irq_set_chained_handler(lg->irq, NULL);
> +       irq_set_handler_data(lg->irq, NULL);

Why is this needed? If the GPIOLIB_IRQCHIP code in
gpiolib.c is not doing this then maybe it's the core code that
needs fixing rather than having this in the driver.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-06 14:15     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
> that was there in old locomo driver, got 'cleaned up' during old driver
> IRQ cascading cleanup and is now reimplemented. It is expected that
> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Assume this will also go through MFD.

> +       irq_set_chained_handler(lg->irq, NULL);
> +       irq_set_handler_data(lg->irq, NULL);

Why is this needed? If the GPIOLIB_IRQCHIP code in
gpiolib.c is not doing this then maybe it's the core code that
needs fixing rather than having this in the driver.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-06 14:19     ` Linus Walleij
  -1 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:19 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Since LoCoMo driver has been converted to provide proper gpiolib
> interface, make poodle ASoC platform driver use gpiolib API.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Acked-by: Mark Brown <broonie@kernel.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
@ 2015-05-06 14:19     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:19 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Since LoCoMo driver has been converted to provide proper gpiolib
> interface, make poodle ASoC platform driver use gpiolib API.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Acked-by: Mark Brown <broonie@kernel.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface
@ 2015-05-06 14:19     ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Since LoCoMo driver has been converted to provide proper gpiolib
> interface, make poodle ASoC platform driver use gpiolib API.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> Acked-by: Mark Brown <broonie@kernel.org>

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
       [not found]   ` <1430178954-11138-15-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-04-28 19:35       ` Robert Jarzmik
@ 2015-05-06 14:20       ` Linus Walleij
  1 sibling, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:20 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Linux Input,
	linux-leds-u79uwXL29TaqPxH82wqD4g

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> Convert poodle to use new mfd-based LoCoMo driver.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

This:

> +static struct gpiod_lookup_table poodle_audio_gpios_table = {
> +       .dev_id = "poodle-audio",
> +       .table = {
> +               GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
> +               { },
> +       },
> +},

Is very nice to see.

Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-05-06 14:20       ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:20 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Linux Input,
	linux-leds-u79uwXL29TaqPxH82wqD4g

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Convert poodle to use new mfd-based LoCoMo driver.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

This:

> +static struct gpiod_lookup_table poodle_audio_gpios_table = {
> +       .dev_id = "poodle-audio",
> +       .table = {
> +               GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
> +               { },
> +       },
> +},

Is very nice to see.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver
@ 2015-05-06 14:20       ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> Convert poodle to use new mfd-based LoCoMo driver.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

This:

> +static struct gpiod_lookup_table poodle_audio_gpios_table = {
> +       .dev_id = "poodle-audio",
> +       .table = {
> +               GPIO_LOOKUP("locomo-gpio", 10, "mute-l", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 11, "mute-r", GPIO_ACTIVE_LOW),
> +               GPIO_LOOKUP("locomo-gpio", 8, "amp-on", GPIO_ACTIVE_LOW),
> +               { },
> +       },
> +},

Is very nice to see.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 17/17] ARM: drop old LoCoMo driver
       [not found]   ` <1430178954-11138-18-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2015-05-06 14:22       ` Linus Walleij
@ 2015-05-06 14:22       ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:22 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Linux Input,
	linux-leds-u79uwXL29TaqPxH82wqD4g

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> As there are no in-kernel users of old locomo driver, drop all
> alltogether. Remove Kconfig entry, driver and header.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Good riddance.

Reviewed-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 17/17] ARM: drop old LoCoMo driver
@ 2015-05-06 14:22       ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:22 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, Linux Input,
	linux-leds-u79uwXL29TaqPxH82wqD4g

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> As there are no in-kernel users of old locomo driver, drop all
> alltogether. Remove Kconfig entry, driver and header.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Good riddance.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 17/17] ARM: drop old LoCoMo driver
@ 2015-05-06 14:22       ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-06 14:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:

> As there are no in-kernel users of old locomo driver, drop all
> alltogether. Remove Kconfig entry, driver and header.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Good riddance.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
  2015-04-27 23:55   ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-06 15:05     ` Jacek Anaszewski
  -1 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-06 15:05 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> Adapt locomo leds driver to new locomo core setup.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>   drivers/leds/Kconfig       |   1 -
>   drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
>   2 files changed, 61 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 966b960..4b4650b 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -79,7 +79,6 @@ config LEDS_LM3642
>   config LEDS_LOCOMO
>   	tristate "LED Support for Locomo device"
>   	depends on LEDS_CLASS
> -	depends on SHARP_LOCOMO

Why do you remove this dependency?

>   	help
>   	  This option enables support for the LEDs on Sharp Locomo.
>   	  Zaurus models SL-5500 and SL-5600.
> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
> index 80ba048..7fde812 100644
> --- a/drivers/leds/leds-locomo.c
> +++ b/drivers/leds/leds-locomo.c
> @@ -9,89 +9,92 @@
>    */
>
>   #include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/device.h>
>   #include <linux/leds.h>
> -
> -#include <mach/hardware.h>
> -#include <asm/hardware/locomo.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/locomo.h>

Please keep alphabetical order.

> +
> +struct locomo_led {
> +	struct led_classdev led;
> +	struct regmap *regmap;
> +	unsigned int reg;
> +};
>
>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
> -				enum led_brightness value, int offset)
> +				enum led_brightness value)
>   {
> -	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
> -	unsigned long flags;
> +	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
>
> -	local_irq_save(flags);
> -	if (value)
> -		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
> -	else
> -		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
> -	local_irq_restore(flags);
> +	regmap_write(led->regmap, led->reg,
> +			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>   }

Please use work queue for setting brightness. This is required for the
driver to be compatible with led triggers. You can refer to the
existing LED drivers on how to implement this.

>
> -static void locomoled_brightness_set0(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> +static int locomo_led_register(
> +		struct device *dev,
> +		struct locomo_led *led,
> +		const char *name,
> +		const char *trigger,
> +		struct regmap *regmap,
> +		unsigned int reg)
>   {
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
> +	led->led.name = name;
> +	led->led.flags = LED_CORE_SUSPENDRESUME;
> +	led->led.default_trigger = trigger;
> +	led->led.brightness_set = locomoled_brightness_set;
> +	led->regmap = regmap;
> +	led->reg = reg;
> +
> +	return devm_led_classdev_register(dev, &led->led);
>   }
>
> -static void locomoled_brightness_set1(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> -{
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
> -}
> -
> -static struct led_classdev locomo_led0 = {
> -	.name			= "locomo:amber:charge",
> -	.default_trigger	= "main-battery-charging",
> -	.brightness_set		= locomoled_brightness_set0,
> -};
> -
> -static struct led_classdev locomo_led1 = {
> -	.name			= "locomo:green:mail",
> -	.default_trigger	= "nand-disk",
> -	.brightness_set		= locomoled_brightness_set1,
> -};
> -
> -static int locomoled_probe(struct locomo_dev *ldev)
> +static int locomoled_probe(struct platform_device *pdev)
>   {
>   	int ret;
> -
> -	ret = led_classdev_register(&ldev->dev, &locomo_led0);
> +	struct locomo_led *leds;
> +	struct regmap *regmap;
> +
> +	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
> +	if (!leds)
> +		return -ENOMEM;
> +
> +	regmap = dev_get_regmap(pdev->dev.parent, NULL);
> +	if (!regmap)
> +		return -ENODEV;
> +
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds,
> +			"locomo:amber:charge",
> +			"main-battery-charging",
> +			regmap,
> +			LOCOMO_LPT0);
>   	if (ret < 0)
>   		return ret;
>
> -	ret = led_classdev_register(&ldev->dev, &locomo_led1);
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds + 1,
> +			"locomo:green:mail",
> +			"mmc0",
> +			regmap,
> +			LOCOMO_LPT1);
>   	if (ret < 0)
> -		led_classdev_unregister(&locomo_led0);
> -
> -	return ret;
> -}
> +		return ret;
>
> -static int locomoled_remove(struct locomo_dev *dev)
> -{
> -	led_classdev_unregister(&locomo_led0);
> -	led_classdev_unregister(&locomo_led1);
>   	return 0;
>   }
>
> -static struct locomo_driver locomoled_driver = {
> -	.drv = {
> -		.name = "locomoled"
> +static struct platform_driver locomoled_driver = {
> +	.driver = {
> +		.name = "locomo-led"
>   	},
> -	.devid	= LOCOMO_DEVID_LED,
>   	.probe	= locomoled_probe,
> -	.remove	= locomoled_remove,
>   };
>
> -static int __init locomoled_init(void)
> -{
> -	return locomo_driver_register(&locomoled_driver);
> -}
> -module_init(locomoled_init);
> +module_platform_driver(locomoled_driver);
>
>   MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
>   MODULE_DESCRIPTION("Locomo LED driver");
>   MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-led");
>


-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-06 15:05     ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-06 15:05 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> Adapt locomo leds driver to new locomo core setup.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>   drivers/leds/Kconfig       |   1 -
>   drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
>   2 files changed, 61 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 966b960..4b4650b 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -79,7 +79,6 @@ config LEDS_LM3642
>   config LEDS_LOCOMO
>   	tristate "LED Support for Locomo device"
>   	depends on LEDS_CLASS
> -	depends on SHARP_LOCOMO

Why do you remove this dependency?

>   	help
>   	  This option enables support for the LEDs on Sharp Locomo.
>   	  Zaurus models SL-5500 and SL-5600.
> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
> index 80ba048..7fde812 100644
> --- a/drivers/leds/leds-locomo.c
> +++ b/drivers/leds/leds-locomo.c
> @@ -9,89 +9,92 @@
>    */
>
>   #include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/device.h>
>   #include <linux/leds.h>
> -
> -#include <mach/hardware.h>
> -#include <asm/hardware/locomo.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/locomo.h>

Please keep alphabetical order.

> +
> +struct locomo_led {
> +	struct led_classdev led;
> +	struct regmap *regmap;
> +	unsigned int reg;
> +};
>
>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
> -				enum led_brightness value, int offset)
> +				enum led_brightness value)
>   {
> -	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
> -	unsigned long flags;
> +	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
>
> -	local_irq_save(flags);
> -	if (value)
> -		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
> -	else
> -		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
> -	local_irq_restore(flags);
> +	regmap_write(led->regmap, led->reg,
> +			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>   }

Please use work queue for setting brightness. This is required for the
driver to be compatible with led triggers. You can refer to the
existing LED drivers on how to implement this.

>
> -static void locomoled_brightness_set0(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> +static int locomo_led_register(
> +		struct device *dev,
> +		struct locomo_led *led,
> +		const char *name,
> +		const char *trigger,
> +		struct regmap *regmap,
> +		unsigned int reg)
>   {
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
> +	led->led.name = name;
> +	led->led.flags = LED_CORE_SUSPENDRESUME;
> +	led->led.default_trigger = trigger;
> +	led->led.brightness_set = locomoled_brightness_set;
> +	led->regmap = regmap;
> +	led->reg = reg;
> +
> +	return devm_led_classdev_register(dev, &led->led);
>   }
>
> -static void locomoled_brightness_set1(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> -{
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
> -}
> -
> -static struct led_classdev locomo_led0 = {
> -	.name			= "locomo:amber:charge",
> -	.default_trigger	= "main-battery-charging",
> -	.brightness_set		= locomoled_brightness_set0,
> -};
> -
> -static struct led_classdev locomo_led1 = {
> -	.name			= "locomo:green:mail",
> -	.default_trigger	= "nand-disk",
> -	.brightness_set		= locomoled_brightness_set1,
> -};
> -
> -static int locomoled_probe(struct locomo_dev *ldev)
> +static int locomoled_probe(struct platform_device *pdev)
>   {
>   	int ret;
> -
> -	ret = led_classdev_register(&ldev->dev, &locomo_led0);
> +	struct locomo_led *leds;
> +	struct regmap *regmap;
> +
> +	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
> +	if (!leds)
> +		return -ENOMEM;
> +
> +	regmap = dev_get_regmap(pdev->dev.parent, NULL);
> +	if (!regmap)
> +		return -ENODEV;
> +
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds,
> +			"locomo:amber:charge",
> +			"main-battery-charging",
> +			regmap,
> +			LOCOMO_LPT0);
>   	if (ret < 0)
>   		return ret;
>
> -	ret = led_classdev_register(&ldev->dev, &locomo_led1);
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds + 1,
> +			"locomo:green:mail",
> +			"mmc0",
> +			regmap,
> +			LOCOMO_LPT1);
>   	if (ret < 0)
> -		led_classdev_unregister(&locomo_led0);
> -
> -	return ret;
> -}
> +		return ret;
>
> -static int locomoled_remove(struct locomo_dev *dev)
> -{
> -	led_classdev_unregister(&locomo_led0);
> -	led_classdev_unregister(&locomo_led1);
>   	return 0;
>   }
>
> -static struct locomo_driver locomoled_driver = {
> -	.drv = {
> -		.name = "locomoled"
> +static struct platform_driver locomoled_driver = {
> +	.driver = {
> +		.name = "locomo-led"
>   	},
> -	.devid	= LOCOMO_DEVID_LED,
>   	.probe	= locomoled_probe,
> -	.remove	= locomoled_remove,
>   };
>
> -static int __init locomoled_init(void)
> -{
> -	return locomo_driver_register(&locomoled_driver);
> -}
> -module_init(locomoled_init);
> +module_platform_driver(locomoled_driver);
>
>   MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
>   MODULE_DESCRIPTION("Locomo LED driver");
>   MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-led");
>


-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-06 15:05     ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-06 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> Adapt locomo leds driver to new locomo core setup.
>
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>   drivers/leds/Kconfig       |   1 -
>   drivers/leds/leds-locomo.c | 119 +++++++++++++++++++++++----------------------
>   2 files changed, 61 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> index 966b960..4b4650b 100644
> --- a/drivers/leds/Kconfig
> +++ b/drivers/leds/Kconfig
> @@ -79,7 +79,6 @@ config LEDS_LM3642
>   config LEDS_LOCOMO
>   	tristate "LED Support for Locomo device"
>   	depends on LEDS_CLASS
> -	depends on SHARP_LOCOMO

Why do you remove this dependency?

>   	help
>   	  This option enables support for the LEDs on Sharp Locomo.
>   	  Zaurus models SL-5500 and SL-5600.
> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
> index 80ba048..7fde812 100644
> --- a/drivers/leds/leds-locomo.c
> +++ b/drivers/leds/leds-locomo.c
> @@ -9,89 +9,92 @@
>    */
>
>   #include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/device.h>
>   #include <linux/leds.h>
> -
> -#include <mach/hardware.h>
> -#include <asm/hardware/locomo.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/locomo.h>

Please keep alphabetical order.

> +
> +struct locomo_led {
> +	struct led_classdev led;
> +	struct regmap *regmap;
> +	unsigned int reg;
> +};
>
>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
> -				enum led_brightness value, int offset)
> +				enum led_brightness value)
>   {
> -	struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
> -	unsigned long flags;
> +	struct locomo_led *led = container_of(led_cdev, struct locomo_led, led);
>
> -	local_irq_save(flags);
> -	if (value)
> -		locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase + offset);
> -	else
> -		locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase + offset);
> -	local_irq_restore(flags);
> +	regmap_write(led->regmap, led->reg,
> +			value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>   }

Please use work queue for setting brightness. This is required for the
driver to be compatible with led triggers. You can refer to the
existing LED drivers on how to implement this.

>
> -static void locomoled_brightness_set0(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> +static int locomo_led_register(
> +		struct device *dev,
> +		struct locomo_led *led,
> +		const char *name,
> +		const char *trigger,
> +		struct regmap *regmap,
> +		unsigned int reg)
>   {
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT0);
> +	led->led.name = name;
> +	led->led.flags = LED_CORE_SUSPENDRESUME;
> +	led->led.default_trigger = trigger;
> +	led->led.brightness_set = locomoled_brightness_set;
> +	led->regmap = regmap;
> +	led->reg = reg;
> +
> +	return devm_led_classdev_register(dev, &led->led);
>   }
>
> -static void locomoled_brightness_set1(struct led_classdev *led_cdev,
> -				enum led_brightness value)
> -{
> -	locomoled_brightness_set(led_cdev, value, LOCOMO_LPT1);
> -}
> -
> -static struct led_classdev locomo_led0 = {
> -	.name			= "locomo:amber:charge",
> -	.default_trigger	= "main-battery-charging",
> -	.brightness_set		= locomoled_brightness_set0,
> -};
> -
> -static struct led_classdev locomo_led1 = {
> -	.name			= "locomo:green:mail",
> -	.default_trigger	= "nand-disk",
> -	.brightness_set		= locomoled_brightness_set1,
> -};
> -
> -static int locomoled_probe(struct locomo_dev *ldev)
> +static int locomoled_probe(struct platform_device *pdev)
>   {
>   	int ret;
> -
> -	ret = led_classdev_register(&ldev->dev, &locomo_led0);
> +	struct locomo_led *leds;
> +	struct regmap *regmap;
> +
> +	leds = devm_kzalloc(&pdev->dev, 2 * sizeof(*leds), GFP_KERNEL);
> +	if (!leds)
> +		return -ENOMEM;
> +
> +	regmap = dev_get_regmap(pdev->dev.parent, NULL);
> +	if (!regmap)
> +		return -ENODEV;
> +
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds,
> +			"locomo:amber:charge",
> +			"main-battery-charging",
> +			regmap,
> +			LOCOMO_LPT0);
>   	if (ret < 0)
>   		return ret;
>
> -	ret = led_classdev_register(&ldev->dev, &locomo_led1);
> +	ret = locomo_led_register(
> +			&pdev->dev,
> +			leds + 1,
> +			"locomo:green:mail",
> +			"mmc0",
> +			regmap,
> +			LOCOMO_LPT1);
>   	if (ret < 0)
> -		led_classdev_unregister(&locomo_led0);
> -
> -	return ret;
> -}
> +		return ret;
>
> -static int locomoled_remove(struct locomo_dev *dev)
> -{
> -	led_classdev_unregister(&locomo_led0);
> -	led_classdev_unregister(&locomo_led1);
>   	return 0;
>   }
>
> -static struct locomo_driver locomoled_driver = {
> -	.drv = {
> -		.name = "locomoled"
> +static struct platform_driver locomoled_driver = {
> +	.driver = {
> +		.name = "locomo-led"
>   	},
> -	.devid	= LOCOMO_DEVID_LED,
>   	.probe	= locomoled_probe,
> -	.remove	= locomoled_remove,
>   };
>
> -static int __init locomoled_init(void)
> -{
> -	return locomo_driver_register(&locomoled_driver);
> -}
> -module_init(locomoled_init);
> +module_platform_driver(locomoled_driver);
>
>   MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
>   MODULE_DESCRIPTION("Locomo LED driver");
>   MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-led");
>


-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
  2015-05-06 14:15     ` Linus Walleij
  (?)
@ 2015-05-06 16:42       ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-06 16:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>
>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>> that was there in old locomo driver, got 'cleaned up' during old driver
>> IRQ cascading cleanup and is now reimplemented. It is expected that
>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for review of the patches.

> Assume this will also go through MFD.
>
>> +       irq_set_chained_handler(lg->irq, NULL);
>> +       irq_set_handler_data(lg->irq, NULL);
>
> Why is this needed? If the GPIOLIB_IRQCHIP code in
> gpiolib.c is not doing this then maybe it's the core code that
> needs fixing rather than having this in the driver.

I have skimmed through the rest of drivers using
gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
the chained handled and handler data. However I couldn't locate
the code where they would be cleared.

Should I still send the patch fixing the GPIOLIB_IRQCHIP?

>
> Yours,
> Linus Walleij



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-06 16:42       ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-06 16:42 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>
>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>> that was there in old locomo driver, got 'cleaned up' during old driver
>> IRQ cascading cleanup and is now reimplemented. It is expected that
>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for review of the patches.

> Assume this will also go through MFD.
>
>> +       irq_set_chained_handler(lg->irq, NULL);
>> +       irq_set_handler_data(lg->irq, NULL);
>
> Why is this needed? If the GPIOLIB_IRQCHIP code in
> gpiolib.c is not doing this then maybe it's the core code that
> needs fixing rather than having this in the driver.

I have skimmed through the rest of drivers using
gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
the chained handled and handler data. However I couldn't locate
the code where they would be cleared.

Should I still send the patch fixing the GPIOLIB_IRQCHIP?

>
> Yours,
> Linus Walleij



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-06 16:42       ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-06 16:42 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>
>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>> that was there in old locomo driver, got 'cleaned up' during old driver
>> IRQ cascading cleanup and is now reimplemented. It is expected that
>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for review of the patches.

> Assume this will also go through MFD.
>
>> +       irq_set_chained_handler(lg->irq, NULL);
>> +       irq_set_handler_data(lg->irq, NULL);
>
> Why is this needed? If the GPIOLIB_IRQCHIP code in
> gpiolib.c is not doing this then maybe it's the core code that
> needs fixing rather than having this in the driver.

I have skimmed through the rest of drivers using
gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
the chained handled and handler data. However I couldn't locate
the code where they would be cleared.

Should I still send the patch fixing the GPIOLIB_IRQCHIP?

>
> Yours,
> Linus Walleij



-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
  2015-05-06 16:42       ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-12 11:15         ` Linus Walleij
  -1 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-12 11:15 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Wed, May 6, 2015 at 6:42 PM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> 2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
>> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
>> <dbaryshkov@gmail.com> wrote:
>>
>>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>>> that was there in old locomo driver, got 'cleaned up' during old driver
>>> IRQ cascading cleanup and is now reimplemented. It is expected that
>>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>
>> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
>
> Thanks for review of the patches.
>
>> Assume this will also go through MFD.
>>
>>> +       irq_set_chained_handler(lg->irq, NULL);
>>> +       irq_set_handler_data(lg->irq, NULL);
>>
>> Why is this needed? If the GPIOLIB_IRQCHIP code in
>> gpiolib.c is not doing this then maybe it's the core code that
>> needs fixing rather than having this in the driver.
>
> I have skimmed through the rest of drivers using
> gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
> the chained handled and handler data. However I couldn't locate
> the code where they would be cleared.
>
> Should I still send the patch fixing the GPIOLIB_IRQCHIP?

Yes I guess you need to save parent_irq in struct gpio_chip and
remove it in gpiochip_irqchip_remove() if it's != 0.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-12 11:15         ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-12 11:15 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Alexandre Courbot,
	Wolfram Sang, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	Linux Input, linux-leds

On Wed, May 6, 2015 at 6:42 PM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> 2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
>> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
>> <dbaryshkov@gmail.com> wrote:
>>
>>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>>> that was there in old locomo driver, got 'cleaned up' during old driver
>>> IRQ cascading cleanup and is now reimplemented. It is expected that
>>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>
>> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
>
> Thanks for review of the patches.
>
>> Assume this will also go through MFD.
>>
>>> +       irq_set_chained_handler(lg->irq, NULL);
>>> +       irq_set_handler_data(lg->irq, NULL);
>>
>> Why is this needed? If the GPIOLIB_IRQCHIP code in
>> gpiolib.c is not doing this then maybe it's the core code that
>> needs fixing rather than having this in the driver.
>
> I have skimmed through the rest of drivers using
> gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
> the chained handled and handler data. However I couldn't locate
> the code where they would be cleared.
>
> Should I still send the patch fixing the GPIOLIB_IRQCHIP?

Yes I guess you need to save parent_irq in struct gpio_chip and
remove it in gpiochip_irqchip_remove() if it's != 0.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling
@ 2015-05-12 11:15         ` Linus Walleij
  0 siblings, 0 replies; 148+ messages in thread
From: Linus Walleij @ 2015-05-12 11:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 6, 2015 at 6:42 PM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> 2015-05-06 17:15 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
>> On Tue, Apr 28, 2015 at 1:55 AM, Dmitry Eremin-Solenikov
>> <dbaryshkov@gmail.com> wrote:
>>
>>> LoCoMo has a possibility to generate per-GPIO edge irqs. Support for
>>> that was there in old locomo driver, got 'cleaned up' during old driver
>>> IRQ cascading cleanup and is now reimplemented. It is expected that
>>> SL-5500 (collie) will use locomo gpio irqs for mmc detection irq.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>
>> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
>
> Thanks for review of the patches.
>
>> Assume this will also go through MFD.
>>
>>> +       irq_set_chained_handler(lg->irq, NULL);
>>> +       irq_set_handler_data(lg->irq, NULL);
>>
>> Why is this needed? If the GPIOLIB_IRQCHIP code in
>> gpiolib.c is not doing this then maybe it's the core code that
>> needs fixing rather than having this in the driver.
>
> I have skimmed through the rest of drivers using
> gpiochip_set_chained_irqchip(). Indeed none of the drivers NULL
> the chained handled and handler data. However I couldn't locate
> the code where they would be cleared.
>
> Should I still send the patch fixing the GPIOLIB_IRQCHIP?

Yes I guess you need to save parent_irq in struct gpio_chip and
remove it in gpiochip_irqchip_remove() if it's != 0.

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
  2015-05-06 15:05     ` Jacek Anaszewski
  (?)
  (?)
@ 2015-05-12 15:35       ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 15:35 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>
>> Adapt locomo leds driver to new locomo core setup.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>   drivers/leds/Kconfig       |   1 -
>>   drivers/leds/leds-locomo.c | 119
>> +++++++++++++++++++++++----------------------
>>   2 files changed, 61 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 966b960..4b4650b 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>   config LEDS_LOCOMO
>>         tristate "LED Support for Locomo device"
>>         depends on LEDS_CLASS
>> -       depends on SHARP_LOCOMO
>
>
> Why do you remove this dependency?

Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
device and regmap interfaces, so there is no direct dependency on main
LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

>
>>         help
>>           This option enables support for the LEDs on Sharp Locomo.
>>           Zaurus models SL-5500 and SL-5600.
>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>> index 80ba048..7fde812 100644
>> --- a/drivers/leds/leds-locomo.c
>> +++ b/drivers/leds/leds-locomo.c
>> @@ -9,89 +9,92 @@
>>    */
>>
>>   #include <linux/kernel.h>
>> -#include <linux/init.h>
>> -#include <linux/module.h>
>> -#include <linux/device.h>
>>   #include <linux/leds.h>
>> -
>> -#include <mach/hardware.h>
>> -#include <asm/hardware/locomo.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/locomo.h>
>
>
> Please keep alphabetical order.

Ack

>
>> +
>> +struct locomo_led {
>> +       struct led_classdev led;
>> +       struct regmap *regmap;
>> +       unsigned int reg;
>> +};
>>
>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>> -                               enum led_brightness value, int offset)
>> +                               enum led_brightness value)
>>   {
>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>> -       unsigned long flags;
>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>> led);
>>
>> -       local_irq_save(flags);
>> -       if (value)
>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>> offset);
>> -       else
>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>> offset);
>> -       local_irq_restore(flags);
>> +       regmap_write(led->regmap, led->reg,
>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>   }
>
>
> Please use work queue for setting brightness. This is required for the
> driver to be compatible with led triggers. You can refer to the
> existing LED drivers on how to implement this.

Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
and doesn't need to be wrapped into work queue, does it?


[skipped]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-12 15:35       ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 15:35 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>
>> Adapt locomo leds driver to new locomo core setup.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>   drivers/leds/Kconfig       |   1 -
>>   drivers/leds/leds-locomo.c | 119
>> +++++++++++++++++++++++----------------------
>>   2 files changed, 61 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 966b960..4b4650b 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>   config LEDS_LOCOMO
>>         tristate "LED Support for Locomo device"
>>         depends on LEDS_CLASS
>> -       depends on SHARP_LOCOMO
>
>
> Why do you remove this dependency?

Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
device and regmap interfaces, so there is no direct dependency on main
LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

>
>>         help
>>           This option enables support for the LEDs on Sharp Locomo.
>>           Zaurus models SL-5500 and SL-5600.
>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>> index 80ba048..7fde812 100644
>> --- a/drivers/leds/leds-locomo.c
>> +++ b/drivers/leds/leds-locomo.c
>> @@ -9,89 +9,92 @@
>>    */
>>
>>   #include <linux/kernel.h>
>> -#include <linux/init.h>
>> -#include <linux/module.h>
>> -#include <linux/device.h>
>>   #include <linux/leds.h>
>> -
>> -#include <mach/hardware.h>
>> -#include <asm/hardware/locomo.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/locomo.h>
>
>
> Please keep alphabetical order.

Ack

>
>> +
>> +struct locomo_led {
>> +       struct led_classdev led;
>> +       struct regmap *regmap;
>> +       unsigned int reg;
>> +};
>>
>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>> -                               enum led_brightness value, int offset)
>> +                               enum led_brightness value)
>>   {
>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>> -       unsigned long flags;
>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>> led);
>>
>> -       local_irq_save(flags);
>> -       if (value)
>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>> offset);
>> -       else
>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>> offset);
>> -       local_irq_restore(flags);
>> +       regmap_write(led->regmap, led->reg,
>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>   }
>
>
> Please use work queue for setting brightness. This is required for the
> driver to be compatible with led triggers. You can refer to the
> existing LED drivers on how to implement this.

Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
and doesn't need to be wrapped into work queue, does it?


[skipped]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-12 15:35       ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 15:35 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>
>> Adapt locomo leds driver to new locomo core setup.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>   drivers/leds/Kconfig       |   1 -
>>   drivers/leds/leds-locomo.c | 119
>> +++++++++++++++++++++++----------------------
>>   2 files changed, 61 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 966b960..4b4650b 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>   config LEDS_LOCOMO
>>         tristate "LED Support for Locomo device"
>>         depends on LEDS_CLASS
>> -       depends on SHARP_LOCOMO
>
>
> Why do you remove this dependency?

Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
device and regmap interfaces, so there is no direct dependency on main
LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

>
>>         help
>>           This option enables support for the LEDs on Sharp Locomo.
>>           Zaurus models SL-5500 and SL-5600.
>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>> index 80ba048..7fde812 100644
>> --- a/drivers/leds/leds-locomo.c
>> +++ b/drivers/leds/leds-locomo.c
>> @@ -9,89 +9,92 @@
>>    */
>>
>>   #include <linux/kernel.h>
>> -#include <linux/init.h>
>> -#include <linux/module.h>
>> -#include <linux/device.h>
>>   #include <linux/leds.h>
>> -
>> -#include <mach/hardware.h>
>> -#include <asm/hardware/locomo.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/locomo.h>
>
>
> Please keep alphabetical order.

Ack

>
>> +
>> +struct locomo_led {
>> +       struct led_classdev led;
>> +       struct regmap *regmap;
>> +       unsigned int reg;
>> +};
>>
>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>> -                               enum led_brightness value, int offset)
>> +                               enum led_brightness value)
>>   {
>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>> -       unsigned long flags;
>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>> led);
>>
>> -       local_irq_save(flags);
>> -       if (value)
>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>> offset);
>> -       else
>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>> offset);
>> -       local_irq_restore(flags);
>> +       regmap_write(led->regmap, led->reg,
>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>   }
>
>
> Please use work queue for setting brightness. This is required for the
> driver to be compatible with led triggers. You can refer to the
> existing LED drivers on how to implement this.

Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
and doesn't need to be wrapped into work queue, does it?


[skipped]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-12 15:35       ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>
>> Adapt locomo leds driver to new locomo core setup.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>   drivers/leds/Kconfig       |   1 -
>>   drivers/leds/leds-locomo.c | 119
>> +++++++++++++++++++++++----------------------
>>   2 files changed, 61 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>> index 966b960..4b4650b 100644
>> --- a/drivers/leds/Kconfig
>> +++ b/drivers/leds/Kconfig
>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>   config LEDS_LOCOMO
>>         tristate "LED Support for Locomo device"
>>         depends on LEDS_CLASS
>> -       depends on SHARP_LOCOMO
>
>
> Why do you remove this dependency?

Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
device and regmap interfaces, so there is no direct dependency on main
LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

>
>>         help
>>           This option enables support for the LEDs on Sharp Locomo.
>>           Zaurus models SL-5500 and SL-5600.
>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>> index 80ba048..7fde812 100644
>> --- a/drivers/leds/leds-locomo.c
>> +++ b/drivers/leds/leds-locomo.c
>> @@ -9,89 +9,92 @@
>>    */
>>
>>   #include <linux/kernel.h>
>> -#include <linux/init.h>
>> -#include <linux/module.h>
>> -#include <linux/device.h>
>>   #include <linux/leds.h>
>> -
>> -#include <mach/hardware.h>
>> -#include <asm/hardware/locomo.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/mfd/locomo.h>
>
>
> Please keep alphabetical order.

Ack

>
>> +
>> +struct locomo_led {
>> +       struct led_classdev led;
>> +       struct regmap *regmap;
>> +       unsigned int reg;
>> +};
>>
>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>> -                               enum led_brightness value, int offset)
>> +                               enum led_brightness value)
>>   {
>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>> -       unsigned long flags;
>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>> led);
>>
>> -       local_irq_save(flags);
>> -       if (value)
>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>> offset);
>> -       else
>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>> offset);
>> -       local_irq_restore(flags);
>> +       regmap_write(led->regmap, led->reg,
>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>   }
>
>
> Please use work queue for setting brightness. This is required for the
> driver to be compatible with led triggers. You can refer to the
> existing LED drivers on how to implement this.

Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
and doesn't need to be wrapped into work queue, does it?


[skipped]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-12 19:24       ` Wolfram Sang
  -1 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:24 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> LoCoMo chip contains a tiny i2c controller destined to control
> M62332 DAC. Provide a separate I2C driver for this cell.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Thanks for the submission!

> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
> +
> +#include <linux/i2c.h>
> +#include <linux/i2c-algo-bit.h>

To avoid duplicates, I prefer the includes to be sorted. No need to
resend because of that, though.

Kudos for brushing up old code! Do you want the drivers go via the
subsystem trees? Or is there a dependency so it should go in via some
other tree in one go?


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:24       ` Wolfram Sang
  0 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:24 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> LoCoMo chip contains a tiny i2c controller destined to control
> M62332 DAC. Provide a separate I2C driver for this cell.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Thanks for the submission!

> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
> +
> +#include <linux/i2c.h>
> +#include <linux/i2c-algo-bit.h>

To avoid duplicates, I prefer the includes to be sorted. No need to
resend because of that, though.

Kudos for brushing up old code! Do you want the drivers go via the
subsystem trees? Or is there a dependency so it should go in via some
other tree in one go?


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:24       ` Wolfram Sang
  0 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> LoCoMo chip contains a tiny i2c controller destined to control
> M62332 DAC. Provide a separate I2C driver for this cell.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>

Thanks for the submission!

> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
> +
> +#include <linux/i2c.h>
> +#include <linux/i2c-algo-bit.h>

To avoid duplicates, I prefer the includes to be sorted. No need to
resend because of that, though.

Kudos for brushing up old code! Do you want the drivers go via the
subsystem trees? Or is there a dependency so it should go in via some
other tree in one go?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150512/231ff613/attachment.sig>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
  2015-05-12 19:24       ` Wolfram Sang
  (?)
  (?)
@ 2015-05-12 19:27         ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 19:27 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
>> LoCoMo chip contains a tiny i2c controller destined to control
>> M62332 DAC. Provide a separate I2C driver for this cell.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Thanks for the submission!
>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/mfd/locomo.h>
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/i2c-algo-bit.h>
>
> To avoid duplicates, I prefer the includes to be sorted. No need to
> resend because of that, though.
>
> Kudos for brushing up old code! Do you want the drivers go via the
> subsystem trees? Or is there a dependency so it should go in via some
> other tree in one go?

There is a header dependency -- <linux/mfd/locomo.h> is a new header.
I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
as a whole series (if that would be ok with respective maintainers).


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:27         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 19:27 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
>> LoCoMo chip contains a tiny i2c controller destined to control
>> M62332 DAC. Provide a separate I2C driver for this cell.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Thanks for the submission!
>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/mfd/locomo.h>
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/i2c-algo-bit.h>
>
> To avoid duplicates, I prefer the includes to be sorted. No need to
> resend because of that, though.
>
> Kudos for brushing up old code! Do you want the drivers go via the
> subsystem trees? Or is there a dependency so it should go in via some
> other tree in one go?

There is a header dependency -- <linux/mfd/locomo.h> is a new header.
I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
as a whole series (if that would be ok with respective maintainers).


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:27         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 19:27 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
>> LoCoMo chip contains a tiny i2c controller destined to control
>> M62332 DAC. Provide a separate I2C driver for this cell.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Thanks for the submission!
>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/mfd/locomo.h>
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/i2c-algo-bit.h>
>
> To avoid duplicates, I prefer the includes to be sorted. No need to
> resend because of that, though.
>
> Kudos for brushing up old code! Do you want the drivers go via the
> subsystem trees? Or is there a dependency so it should go in via some
> other tree in one go?

There is a header dependency -- <linux/mfd/locomo.h> is a new header.
I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
as a whole series (if that would be ok with respective maintainers).


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:27         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 19:27 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
>> LoCoMo chip contains a tiny i2c controller destined to control
>> M62332 DAC. Provide a separate I2C driver for this cell.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>
> Thanks for the submission!
>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/mfd/locomo.h>
>> +
>> +#include <linux/i2c.h>
>> +#include <linux/i2c-algo-bit.h>
>
> To avoid duplicates, I prefer the includes to be sorted. No need to
> resend because of that, though.
>
> Kudos for brushing up old code! Do you want the drivers go via the
> subsystem trees? Or is there a dependency so it should go in via some
> other tree in one go?

There is a header dependency -- <linux/mfd/locomo.h> is a new header.
I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
as a whole series (if that would be ok with respective maintainers).


-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
  2015-05-12 19:27         ` Dmitry Eremin-Solenikov
  (?)
  (?)
@ 2015-05-12 19:28           ` Wolfram Sang
  -1 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:28 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

[-- Attachment #1: Type: text/plain, Size: 1339 bytes --]

On Tue, May 12, 2015 at 10:27:07PM +0300, Dmitry Eremin-Solenikov wrote:
> 2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> > On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> >> LoCoMo chip contains a tiny i2c controller destined to control
> >> M62332 DAC. Provide a separate I2C driver for this cell.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >
> > Thanks for the submission!
> >
> >> +#include <linux/kernel.h>
> >> +#include <linux/module.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/regmap.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/mfd/locomo.h>
> >> +
> >> +#include <linux/i2c.h>
> >> +#include <linux/i2c-algo-bit.h>
> >
> > To avoid duplicates, I prefer the includes to be sorted. No need to
> > resend because of that, though.
> >
> > Kudos for brushing up old code! Do you want the drivers go via the
> > subsystem trees? Or is there a dependency so it should go in via some
> > other tree in one go?
> 
> There is a header dependency -- <linux/mfd/locomo.h> is a new header.
> I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
> as a whole series (if that would be ok with respective maintainers).

Fine with me.

Reviewed-by: Wolfram Sang <wsa@the-dreams.de>


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:28           ` Wolfram Sang
  0 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:28 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

[-- Attachment #1: Type: text/plain, Size: 1339 bytes --]

On Tue, May 12, 2015 at 10:27:07PM +0300, Dmitry Eremin-Solenikov wrote:
> 2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> > On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> >> LoCoMo chip contains a tiny i2c controller destined to control
> >> M62332 DAC. Provide a separate I2C driver for this cell.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >
> > Thanks for the submission!
> >
> >> +#include <linux/kernel.h>
> >> +#include <linux/module.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/regmap.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/mfd/locomo.h>
> >> +
> >> +#include <linux/i2c.h>
> >> +#include <linux/i2c-algo-bit.h>
> >
> > To avoid duplicates, I prefer the includes to be sorted. No need to
> > resend because of that, though.
> >
> > Kudos for brushing up old code! Do you want the drivers go via the
> > subsystem trees? Or is there a dependency so it should go in via some
> > other tree in one go?
> 
> There is a header dependency -- <linux/mfd/locomo.h> is a new header.
> I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
> as a whole series (if that would be ok with respective maintainers).

Fine with me.

Reviewed-by: Wolfram Sang <wsa@the-dreams.de>


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:28           ` Wolfram Sang
  0 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:28 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Dmitry Torokhov, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

[-- Attachment #1: Type: text/plain, Size: 1339 bytes --]

On Tue, May 12, 2015 at 10:27:07PM +0300, Dmitry Eremin-Solenikov wrote:
> 2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> > On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> >> LoCoMo chip contains a tiny i2c controller destined to control
> >> M62332 DAC. Provide a separate I2C driver for this cell.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >
> > Thanks for the submission!
> >
> >> +#include <linux/kernel.h>
> >> +#include <linux/module.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/regmap.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/mfd/locomo.h>
> >> +
> >> +#include <linux/i2c.h>
> >> +#include <linux/i2c-algo-bit.h>
> >
> > To avoid duplicates, I prefer the includes to be sorted. No need to
> > resend because of that, though.
> >
> > Kudos for brushing up old code! Do you want the drivers go via the
> > subsystem trees? Or is there a dependency so it should go in via some
> > other tree in one go?
> 
> There is a header dependency -- <linux/mfd/locomo.h> is a new header.
> I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
> as a whole series (if that would be ok with respective maintainers).

Fine with me.

Reviewed-by: Wolfram Sang <wsa@the-dreams.de>


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 10/17] i2c: add locomo i2c driver
@ 2015-05-12 19:28           ` Wolfram Sang
  0 siblings, 0 replies; 148+ messages in thread
From: Wolfram Sang @ 2015-05-12 19:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 12, 2015 at 10:27:07PM +0300, Dmitry Eremin-Solenikov wrote:
> 2015-05-12 22:24 GMT+03:00 Wolfram Sang <wsa@the-dreams.de>:
> > On Tue, Apr 28, 2015 at 02:55:47AM +0300, Dmitry Eremin-Solenikov wrote:
> >> LoCoMo chip contains a tiny i2c controller destined to control
> >> M62332 DAC. Provide a separate I2C driver for this cell.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >
> > Thanks for the submission!
> >
> >> +#include <linux/kernel.h>
> >> +#include <linux/module.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/regmap.h>
> >> +#include <linux/slab.h>
> >> +#include <linux/mfd/locomo.h>
> >> +
> >> +#include <linux/i2c.h>
> >> +#include <linux/i2c-algo-bit.h>
> >
> > To avoid duplicates, I prefer the includes to be sorted. No need to
> > resend because of that, though.
> >
> > Kudos for brushing up old code! Do you want the drivers go via the
> > subsystem trees? Or is there a dependency so it should go in via some
> > other tree in one go?
> 
> There is a header dependency -- <linux/mfd/locomo.h> is a new header.
> I'd prefer for these patches to go in via one of MFD, arm-soc or ARM trees
> as a whole series (if that would be ok with respective maintainers).

Fine with me.

Reviewed-by: Wolfram Sang <wsa@the-dreams.de>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150512/71aeee56/attachment.sig>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-12 20:12       ` Dmitry Torokhov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:12 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
> able to trigger sysrq functions directly. Add an option providing sysrq
> mapping for Contact-Home keys.

No, if you want to remap the keys please do it from usepspace; locomokbd
supports it (EVIOCSKEYCODE ioctl).

Thanks.

> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |  7 +++++++
>  drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 0a3d875..eb8b11b 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called locomokbd.
>  
> +config KEYBOARD_LOCOMO_SYSRQ
> +	bool "Provide SysRQ key on LoCoMo keyboard"
> +	depends on KEYBOARD_LOCOMO
> +	help
> +	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
> +	  Say N if you want to use them as usual keys.
> +
>  config KEYBOARD_LPC32XX
>  	tristate "LPC32XX matrix key scanner support"
>  	depends on ARCH_LPC32XX && OF
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index eed0a94..eb8dbe2 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -40,6 +40,14 @@
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
> +#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
> +#define LOCOMO_KEY_HOME		KEY_SYSRQ
> +#else
> +#define LOCOMO_KEY_CONTACT	KEY_CONTACT
> +#define LOCOMO_KEY_HOME		KEY_HOME
> +#endif
> +
>  #define KB_ROWS			16
>  #define KB_COLS			8
>  #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> @@ -48,7 +56,7 @@
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
> @@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
>  			sizeof(locomokbd->keycode));
>  
>  	if (machine_is_collie())
> -		locomokbd->keycode[18] = KEY_HOME;
> +		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
>  	else
> -		locomokbd->keycode[3] = KEY_HOME;
> +		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
>  
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
>  		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> -- 
> 2.1.4
> 

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-05-12 20:12       ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:12 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
> able to trigger sysrq functions directly. Add an option providing sysrq
> mapping for Contact-Home keys.

No, if you want to remap the keys please do it from usepspace; locomokbd
supports it (EVIOCSKEYCODE ioctl).

Thanks.

> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |  7 +++++++
>  drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 0a3d875..eb8b11b 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called locomokbd.
>  
> +config KEYBOARD_LOCOMO_SYSRQ
> +	bool "Provide SysRQ key on LoCoMo keyboard"
> +	depends on KEYBOARD_LOCOMO
> +	help
> +	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
> +	  Say N if you want to use them as usual keys.
> +
>  config KEYBOARD_LPC32XX
>  	tristate "LPC32XX matrix key scanner support"
>  	depends on ARCH_LPC32XX && OF
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index eed0a94..eb8dbe2 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -40,6 +40,14 @@
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
> +#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
> +#define LOCOMO_KEY_HOME		KEY_SYSRQ
> +#else
> +#define LOCOMO_KEY_CONTACT	KEY_CONTACT
> +#define LOCOMO_KEY_HOME		KEY_HOME
> +#endif
> +
>  #define KB_ROWS			16
>  #define KB_COLS			8
>  #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> @@ -48,7 +56,7 @@
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
> @@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
>  			sizeof(locomokbd->keycode));
>  
>  	if (machine_is_collie())
> -		locomokbd->keycode[18] = KEY_HOME;
> +		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
>  	else
> -		locomokbd->keycode[3] = KEY_HOME;
> +		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
>  
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
>  		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> -- 
> 2.1.4
> 

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-05-12 20:12       ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:12 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
> able to trigger sysrq functions directly. Add an option providing sysrq
> mapping for Contact-Home keys.

No, if you want to remap the keys please do it from usepspace; locomokbd
supports it (EVIOCSKEYCODE ioctl).

Thanks.

> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |  7 +++++++
>  drivers/input/keyboard/locomokbd.c | 14 +++++++++++---
>  2 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 0a3d875..eb8b11b 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -343,6 +343,13 @@ config KEYBOARD_LOCOMO
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called locomokbd.
>  
> +config KEYBOARD_LOCOMO_SYSRQ
> +	bool "Provide SysRQ key on LoCoMo keyboard"
> +	depends on KEYBOARD_LOCOMO
> +	help
> +	  Say Y here to be able to use Contact-Home as Alt-Sysrq combo.
> +	  Say N if you want to use them as usual keys.
> +
>  config KEYBOARD_LPC32XX
>  	tristate "LPC32XX matrix key scanner support"
>  	depends on ARCH_LPC32XX && OF
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index eed0a94..eb8dbe2 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -40,6 +40,14 @@
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#ifdef CONFIG_KEYBOARD_LOCOMOKBD_SYSRQ
> +#define LOCOMO_KEY_CONTACT	KEY_LEFTALT
> +#define LOCOMO_KEY_HOME		KEY_SYSRQ
> +#else
> +#define LOCOMO_KEY_CONTACT	KEY_CONTACT
> +#define LOCOMO_KEY_HOME		KEY_HOME
> +#endif
> +
>  #define KB_ROWS			16
>  #define KB_COLS			8
>  #define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> @@ -48,7 +56,7 @@
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, LOCOMO_KEY_CONTACT,			/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
> @@ -280,9 +288,9 @@ static int locomokbd_probe(struct platform_device *dev)
>  			sizeof(locomokbd->keycode));
>  
>  	if (machine_is_collie())
> -		locomokbd->keycode[18] = KEY_HOME;
> +		locomokbd->keycode[18] = LOCOMO_KEY_HOME;
>  	else
> -		locomokbd->keycode[3] = KEY_HOME;
> +		locomokbd->keycode[3] = LOCOMO_KEY_HOME;
>  
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
>  		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> -- 
> 2.1.4
> 

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
  2015-04-27 23:55     ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-12 20:21       ` Dmitry Torokhov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:21 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> As LoCoMo is switching to new device model, adapt keyboard driver to
> support new locomo core driver.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |   1 -
>  drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
>  2 files changed, 143 insertions(+), 129 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 106fbac..0a3d875 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -337,7 +337,6 @@ config KEYBOARD_LM8333
>  
>  config KEYBOARD_LOCOMO
>  	tristate "LoCoMo Keyboard Support"
> -	depends on SHARP_LOCOMO
>  	help
>  	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
>  
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index c94d610..eed0a94 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -23,37 +23,37 @@
>   *
>   */
>  
> -#include <linux/slab.h>
> -#include <linux/module.h>
> +#include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/input.h>
> -#include <linux/delay.h>
> -#include <linux/device.h>
>  #include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -
> -#include <asm/hardware/locomo.h>
> -#include <asm/irq.h>
> -
> -MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> -MODULE_DESCRIPTION("LoCoMo keyboard driver");
> -MODULE_LICENSE("GPL");
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
>  
> -#define LOCOMOKBD_NUMKEYS	128
> +/* There is one minor difference between mappings on poodle and collie */
> +#include <asm/mach-types.h>
>  
>  #define KEY_ACTIVITY		KEY_F16
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#define KB_ROWS			16
> +#define KB_COLS			8
> +#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> +#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
> +
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
>  	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
> -	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
> +	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
>  	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
>  	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
>  	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
> @@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
>  };
>  
> -#define KB_ROWS			16
> -#define KB_COLS			8
> -#define KB_ROWMASK(r)		(1 << (r))
> -#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
> -
>  #define KB_DELAY		8
> -#define SCAN_INTERVAL		(HZ/10)
>  
>  struct locomokbd {
>  	unsigned char keycode[LOCOMOKBD_NUMKEYS];
>  	struct input_dev *input;
> -	char phys[32];
>  
> -	unsigned long base;
> +	struct regmap *regmap;
> +	int irq;
>  	spinlock_t lock;
>  
>  	struct timer_list timer;
> @@ -84,37 +78,33 @@ struct locomokbd {
>  };
>  
>  /* helper functions for reading the keyboard matrix */
> -static inline void locomokbd_charge_all(unsigned long membase)
> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>  {
> -	locomo_writel(0x00FF, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>  }
>  
> -static inline void locomokbd_activate_all(unsigned long membase)
> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)

Drop "inline"s from the .c file please.

>  {
> -	unsigned long r;
> -
> -	locomo_writel(0, membase + LOCOMO_KSC);
> -	r = locomo_readl(membase + LOCOMO_KIC);
> -	r &= 0xFEFF;
> -	locomo_writel(r, membase + LOCOMO_KIC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>  }
>  
> -static inline void locomokbd_activate_col(unsigned long membase, int col)
> +static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nset;
>  	unsigned short nbset;
>  
> -	nset = 0xFF & ~(1 << col);
> +	nset = 0xFF & ~BIT(col);
>  	nbset = (nset << 8) + nset;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
> -static inline void locomokbd_reset_col(unsigned long membase, int col)
> +static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nbset;
>  
> -	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
>  /*
> @@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  	unsigned int row, col, rowd;
>  	unsigned long flags;
>  	unsigned int num_pressed;
> -	unsigned long membase = locomokbd->base;
> +	bool esc_pressed = false;
>  
>  	spin_lock_irqsave(&locomokbd->lock, flags);
>  
> -	locomokbd_charge_all(membase);
> +	locomokbd_charge_all(locomokbd);
>  
>  	num_pressed = 0;
>  	for (col = 0; col < KB_COLS; col++) {
> -
> -		locomokbd_activate_col(membase, col);
> +		udelay(KB_DELAY);
> +		locomokbd_activate_col(locomokbd, col);
>  		udelay(KB_DELAY);
>  
> -		rowd = ~locomo_readl(membase + LOCOMO_KIB);
> +		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
> +		rowd = ~rowd;
>  		for (row = 0; row < KB_ROWS; row++) {
>  			unsigned int scancode, pressed, key;
>  
>  			scancode = SCANCODE(col, row);
> -			pressed = rowd & KB_ROWMASK(row);
> +			pressed = rowd & BIT(row);
>  			key = locomokbd->keycode[scancode];
>  
>  			input_report_key(locomokbd->input, key, pressed);
> @@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  			/* The "Cancel/ESC" key is labeled "On/Off" on
>  			 * Collie and Poodle and should suspend the device
>  			 * if it was pressed for more than a second. */
> -			if (unlikely(key == KEY_ESC)) {
> -				if (!time_after(jiffies,
> -					locomokbd->suspend_jiffies + HZ))
> -					continue;
> -				if (locomokbd->count_cancel++
> -					!= (HZ/SCAN_INTERVAL + 1))
> -					continue;
> -				input_event(locomokbd->input, EV_PWR,
> -					KEY_SUSPEND, 1);
> -				locomokbd->suspend_jiffies = jiffies;
> -			} else
> -				locomokbd->count_cancel = 0;
> +			if (unlikely(key == KEY_ESC))
> +				esc_pressed = true;
>  		}
> -		locomokbd_reset_col(membase, col);
> +		locomokbd_reset_col(locomokbd, col);
>  	}
> -	locomokbd_activate_all(membase);
> +	locomokbd_activate_all(locomokbd);
>  
>  	input_sync(locomokbd->input);
>  
>  	/* if any keys are pressed, enable the timer */
>  	if (num_pressed)
> -		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
> +		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
>  	else
> +		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +
> +	if (esc_pressed && time_after(jiffies,
> +		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
> +		if (locomokbd->count_cancel++ > (20)) {

Why parentheses around 20?

> +			input_event(locomokbd->input, EV_PWR,
> +					KEY_SUSPEND, 1);
> +			locomokbd->suspend_jiffies = jiffies;
> +		}
> +	} else
>  		locomokbd->count_cancel = 0;

If one branch has curly braces the other should have them too.

>  
>  	spin_unlock_irqrestore(&locomokbd->lock, flags);
> @@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
>  {
>  	struct locomokbd *locomokbd = dev_id;
> -	u16 r;
> +	unsigned int r;
>  
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
>  	if ((r & 0x0001) == 0)
>  		return IRQ_HANDLED;
>  
> -	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
> +	/* Mask and Ack */
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
>  
> -	/** wait chattering delay **/
> -	udelay(100);
> +	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
>  
> -	locomokbd_scankeyboard(locomokbd);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
>  static int locomokbd_open(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> -	return 0;
> +
> +	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
>  }
>  
>  static void locomokbd_close(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  }
>  
> -static int locomokbd_probe(struct locomo_dev *dev)
> +static int locomokbd_probe(struct platform_device *dev)
>  {
>  	struct locomokbd *locomokbd;
>  	struct input_dev *input_dev;
>  	int i, err;
>  
> -	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
> -	input_dev = input_allocate_device();
> -	if (!locomokbd || !input_dev) {
> -		err = -ENOMEM;
> -		goto err_free_mem;
> -	}
> +	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
> +			GFP_KERNEL);
> +	if (!locomokbd)
> +		return -ENOMEM;
>  
> -	/* try and claim memory region */
> -	if (!request_mem_region((unsigned long) dev->mapbase,
> -				dev->length,
> -				LOCOMO_DRIVER_NAME(dev))) {
> -		err = -EBUSY;
> -		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
> -		goto err_free_mem;
> -	}
> +	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
> +	if (!locomokbd->regmap)
> +		return -EINVAL;
>  
> -	locomo_set_drvdata(dev, locomokbd);
> +	locomokbd->irq = platform_get_irq(dev, 0);
> +	if (locomokbd->irq < 0)
> +		return -ENXIO;
>  
> -	locomokbd->base = (unsigned long) dev->mapbase;
> +	platform_set_drvdata(dev, locomokbd);
>  
>  	spin_lock_init(&locomokbd->lock);
>  
> @@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	locomokbd->suspend_jiffies = jiffies;
>  
> -	locomokbd->input = input_dev;
> -	strcpy(locomokbd->phys, "locomokbd/input0");
> +	input_dev = input_allocate_device();

devm_input_allocate_device()?

> +	if (!input_dev)
> +		return -ENOMEM;
>  
> +	locomokbd->input = input_dev;
>  	input_dev->name = "LoCoMo keyboard";
> -	input_dev->phys = locomokbd->phys;
> +	input_dev->phys = "locomokbd/input0";
>  	input_dev->id.bustype = BUS_HOST;
>  	input_dev->id.vendor = 0x0001;
>  	input_dev->id.product = 0x0001;
> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	input_set_drvdata(input_dev, locomokbd);
>  
> -	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> +	memcpy(locomokbd->keycode,
> +			locomokbd_keycode,
> +			sizeof(locomokbd->keycode));
> +
> +	if (machine_is_collie())
> +		locomokbd->keycode[18] = KEY_HOME;
> +	else
> +		locomokbd->keycode[3] = KEY_HOME;

This seems like a new addition. Ideally keymap twiddling shoudl be done
from userspace.

> +
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
> -		set_bit(locomokbd->keycode[i], input_dev->keybit);
> -	clear_bit(0, input_dev->keybit);
> +		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> +	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
> +	__set_bit(EV_REP, input_dev->evbit);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
>  
>  	/* attempt to get the interrupt */
> -	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> +	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> +			"locomokbd", locomokbd);

devm_request_irq()?

>  	if (err) {
> -		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
> -		goto err_release_region;
> +		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
> +		goto err_free_mem;
>  	}
>  
>  	err = input_register_device(locomokbd->input);
> @@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	return 0;
>  
> - err_free_irq:
> -	free_irq(dev->irq[0], locomokbd);
> - err_release_region:
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> -	locomo_set_drvdata(dev, NULL);
> - err_free_mem:
> +err_free_irq:
> +	free_irq(locomokbd->irq, locomokbd);
> +err_free_mem:
>  	input_free_device(input_dev);
> -	kfree(locomokbd);
>  
>  	return err;
>  }
>  
> -static int locomokbd_remove(struct locomo_dev *dev)
> +static int locomokbd_remove(struct platform_device *dev)
>  {
> -	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> +	struct locomokbd *locomokbd = platform_get_drvdata(dev);
>  
> -	free_irq(dev->irq[0], locomokbd);
> +	free_irq(locomokbd->irq, locomokbd);

Is not needed with devm.

>  
>  	del_timer_sync(&locomokbd->timer);

Should likely to go into close().

>  
>  	input_unregister_device(locomokbd->input);

Is not needed with devm.

> -	locomo_set_drvdata(dev, NULL);
>  
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int locomokbd_suspend(struct device *dev)

Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  
> -	kfree(locomokbd);
> +	del_timer_sync(&locomokbd->timer);
>  
>  	return 0;
>  }
>  
> -static struct locomo_driver keyboard_driver = {
> -	.drv = {
> -		.name = "locomokbd"
> +static int locomokbd_resume(struct device *dev)

__maybe_unused as well.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +	locomokbd_scankeyboard(locomokbd);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
> +#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
> +#else
> +#define LOCOMO_KBD_PM	NULL
> +#endif

Just do

static SIMPLE_DEV_PM_OPS(locomo_kbd_pm,
			 locomokbd_suspend, locomokbd_resume);


outside of #ifdef, it will produce the right thing (an empty structure).

> +
> +static struct platform_driver locomokbd_driver = {
> +	.driver = {
> +		.name	= "locomo-kbd",
> +		.pm	= LOCOMO_KBD_PM,

		.pm	= &locomo_kbd_pm;
>  	},
> -	.devid	= LOCOMO_DEVID_KEYBOARD,
>  	.probe	= locomokbd_probe,
>  	.remove	= locomokbd_remove,
>  };
>  
> -static int __init locomokbd_init(void)
> -{
> -	return locomo_driver_register(&keyboard_driver);
> -}
> -
> -static void __exit locomokbd_exit(void)
> -{
> -	locomo_driver_unregister(&keyboard_driver);
> -}
> +module_platform_driver(locomokbd_driver);
>  
> -module_init(locomokbd_init);
> -module_exit(locomokbd_exit);
> +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> +MODULE_DESCRIPTION("LoCoMo keyboard driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-kbd");
> -- 
> 2.1.4
> 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 20:21       ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:21 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi, linux-fbdev, alsa-devel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> As LoCoMo is switching to new device model, adapt keyboard driver to
> support new locomo core driver.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |   1 -
>  drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
>  2 files changed, 143 insertions(+), 129 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 106fbac..0a3d875 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -337,7 +337,6 @@ config KEYBOARD_LM8333
>  
>  config KEYBOARD_LOCOMO
>  	tristate "LoCoMo Keyboard Support"
> -	depends on SHARP_LOCOMO
>  	help
>  	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
>  
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index c94d610..eed0a94 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -23,37 +23,37 @@
>   *
>   */
>  
> -#include <linux/slab.h>
> -#include <linux/module.h>
> +#include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/input.h>
> -#include <linux/delay.h>
> -#include <linux/device.h>
>  #include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -
> -#include <asm/hardware/locomo.h>
> -#include <asm/irq.h>
> -
> -MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> -MODULE_DESCRIPTION("LoCoMo keyboard driver");
> -MODULE_LICENSE("GPL");
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
>  
> -#define LOCOMOKBD_NUMKEYS	128
> +/* There is one minor difference between mappings on poodle and collie */
> +#include <asm/mach-types.h>
>  
>  #define KEY_ACTIVITY		KEY_F16
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#define KB_ROWS			16
> +#define KB_COLS			8
> +#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> +#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
> +
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
>  	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
> -	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
> +	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
>  	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
>  	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
>  	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
> @@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
>  };
>  
> -#define KB_ROWS			16
> -#define KB_COLS			8
> -#define KB_ROWMASK(r)		(1 << (r))
> -#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
> -
>  #define KB_DELAY		8
> -#define SCAN_INTERVAL		(HZ/10)
>  
>  struct locomokbd {
>  	unsigned char keycode[LOCOMOKBD_NUMKEYS];
>  	struct input_dev *input;
> -	char phys[32];
>  
> -	unsigned long base;
> +	struct regmap *regmap;
> +	int irq;
>  	spinlock_t lock;
>  
>  	struct timer_list timer;
> @@ -84,37 +78,33 @@ struct locomokbd {
>  };
>  
>  /* helper functions for reading the keyboard matrix */
> -static inline void locomokbd_charge_all(unsigned long membase)
> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>  {
> -	locomo_writel(0x00FF, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>  }
>  
> -static inline void locomokbd_activate_all(unsigned long membase)
> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)

Drop "inline"s from the .c file please.

>  {
> -	unsigned long r;
> -
> -	locomo_writel(0, membase + LOCOMO_KSC);
> -	r = locomo_readl(membase + LOCOMO_KIC);
> -	r &= 0xFEFF;
> -	locomo_writel(r, membase + LOCOMO_KIC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>  }
>  
> -static inline void locomokbd_activate_col(unsigned long membase, int col)
> +static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nset;
>  	unsigned short nbset;
>  
> -	nset = 0xFF & ~(1 << col);
> +	nset = 0xFF & ~BIT(col);
>  	nbset = (nset << 8) + nset;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
> -static inline void locomokbd_reset_col(unsigned long membase, int col)
> +static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nbset;
>  
> -	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
>  /*
> @@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  	unsigned int row, col, rowd;
>  	unsigned long flags;
>  	unsigned int num_pressed;
> -	unsigned long membase = locomokbd->base;
> +	bool esc_pressed = false;
>  
>  	spin_lock_irqsave(&locomokbd->lock, flags);
>  
> -	locomokbd_charge_all(membase);
> +	locomokbd_charge_all(locomokbd);
>  
>  	num_pressed = 0;
>  	for (col = 0; col < KB_COLS; col++) {
> -
> -		locomokbd_activate_col(membase, col);
> +		udelay(KB_DELAY);
> +		locomokbd_activate_col(locomokbd, col);
>  		udelay(KB_DELAY);
>  
> -		rowd = ~locomo_readl(membase + LOCOMO_KIB);
> +		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
> +		rowd = ~rowd;
>  		for (row = 0; row < KB_ROWS; row++) {
>  			unsigned int scancode, pressed, key;
>  
>  			scancode = SCANCODE(col, row);
> -			pressed = rowd & KB_ROWMASK(row);
> +			pressed = rowd & BIT(row);
>  			key = locomokbd->keycode[scancode];
>  
>  			input_report_key(locomokbd->input, key, pressed);
> @@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  			/* The "Cancel/ESC" key is labeled "On/Off" on
>  			 * Collie and Poodle and should suspend the device
>  			 * if it was pressed for more than a second. */
> -			if (unlikely(key = KEY_ESC)) {
> -				if (!time_after(jiffies,
> -					locomokbd->suspend_jiffies + HZ))
> -					continue;
> -				if (locomokbd->count_cancel++
> -					!= (HZ/SCAN_INTERVAL + 1))
> -					continue;
> -				input_event(locomokbd->input, EV_PWR,
> -					KEY_SUSPEND, 1);
> -				locomokbd->suspend_jiffies = jiffies;
> -			} else
> -				locomokbd->count_cancel = 0;
> +			if (unlikely(key = KEY_ESC))
> +				esc_pressed = true;
>  		}
> -		locomokbd_reset_col(membase, col);
> +		locomokbd_reset_col(locomokbd, col);
>  	}
> -	locomokbd_activate_all(membase);
> +	locomokbd_activate_all(locomokbd);
>  
>  	input_sync(locomokbd->input);
>  
>  	/* if any keys are pressed, enable the timer */
>  	if (num_pressed)
> -		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
> +		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
>  	else
> +		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +
> +	if (esc_pressed && time_after(jiffies,
> +		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
> +		if (locomokbd->count_cancel++ > (20)) {

Why parentheses around 20?

> +			input_event(locomokbd->input, EV_PWR,
> +					KEY_SUSPEND, 1);
> +			locomokbd->suspend_jiffies = jiffies;
> +		}
> +	} else
>  		locomokbd->count_cancel = 0;

If one branch has curly braces the other should have them too.

>  
>  	spin_unlock_irqrestore(&locomokbd->lock, flags);
> @@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
>  {
>  	struct locomokbd *locomokbd = dev_id;
> -	u16 r;
> +	unsigned int r;
>  
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
>  	if ((r & 0x0001) = 0)
>  		return IRQ_HANDLED;
>  
> -	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
> +	/* Mask and Ack */
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
>  
> -	/** wait chattering delay **/
> -	udelay(100);
> +	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
>  
> -	locomokbd_scankeyboard(locomokbd);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
>  static int locomokbd_open(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> -	return 0;
> +
> +	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
>  }
>  
>  static void locomokbd_close(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  }
>  
> -static int locomokbd_probe(struct locomo_dev *dev)
> +static int locomokbd_probe(struct platform_device *dev)
>  {
>  	struct locomokbd *locomokbd;
>  	struct input_dev *input_dev;
>  	int i, err;
>  
> -	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
> -	input_dev = input_allocate_device();
> -	if (!locomokbd || !input_dev) {
> -		err = -ENOMEM;
> -		goto err_free_mem;
> -	}
> +	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
> +			GFP_KERNEL);
> +	if (!locomokbd)
> +		return -ENOMEM;
>  
> -	/* try and claim memory region */
> -	if (!request_mem_region((unsigned long) dev->mapbase,
> -				dev->length,
> -				LOCOMO_DRIVER_NAME(dev))) {
> -		err = -EBUSY;
> -		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
> -		goto err_free_mem;
> -	}
> +	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
> +	if (!locomokbd->regmap)
> +		return -EINVAL;
>  
> -	locomo_set_drvdata(dev, locomokbd);
> +	locomokbd->irq = platform_get_irq(dev, 0);
> +	if (locomokbd->irq < 0)
> +		return -ENXIO;
>  
> -	locomokbd->base = (unsigned long) dev->mapbase;
> +	platform_set_drvdata(dev, locomokbd);
>  
>  	spin_lock_init(&locomokbd->lock);
>  
> @@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	locomokbd->suspend_jiffies = jiffies;
>  
> -	locomokbd->input = input_dev;
> -	strcpy(locomokbd->phys, "locomokbd/input0");
> +	input_dev = input_allocate_device();

devm_input_allocate_device()?

> +	if (!input_dev)
> +		return -ENOMEM;
>  
> +	locomokbd->input = input_dev;
>  	input_dev->name = "LoCoMo keyboard";
> -	input_dev->phys = locomokbd->phys;
> +	input_dev->phys = "locomokbd/input0";
>  	input_dev->id.bustype = BUS_HOST;
>  	input_dev->id.vendor = 0x0001;
>  	input_dev->id.product = 0x0001;
> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	input_set_drvdata(input_dev, locomokbd);
>  
> -	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> +	memcpy(locomokbd->keycode,
> +			locomokbd_keycode,
> +			sizeof(locomokbd->keycode));
> +
> +	if (machine_is_collie())
> +		locomokbd->keycode[18] = KEY_HOME;
> +	else
> +		locomokbd->keycode[3] = KEY_HOME;

This seems like a new addition. Ideally keymap twiddling shoudl be done
from userspace.

> +
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
> -		set_bit(locomokbd->keycode[i], input_dev->keybit);
> -	clear_bit(0, input_dev->keybit);
> +		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> +	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
> +	__set_bit(EV_REP, input_dev->evbit);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
>  
>  	/* attempt to get the interrupt */
> -	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> +	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> +			"locomokbd", locomokbd);

devm_request_irq()?

>  	if (err) {
> -		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
> -		goto err_release_region;
> +		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
> +		goto err_free_mem;
>  	}
>  
>  	err = input_register_device(locomokbd->input);
> @@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	return 0;
>  
> - err_free_irq:
> -	free_irq(dev->irq[0], locomokbd);
> - err_release_region:
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> -	locomo_set_drvdata(dev, NULL);
> - err_free_mem:
> +err_free_irq:
> +	free_irq(locomokbd->irq, locomokbd);
> +err_free_mem:
>  	input_free_device(input_dev);
> -	kfree(locomokbd);
>  
>  	return err;
>  }
>  
> -static int locomokbd_remove(struct locomo_dev *dev)
> +static int locomokbd_remove(struct platform_device *dev)
>  {
> -	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> +	struct locomokbd *locomokbd = platform_get_drvdata(dev);
>  
> -	free_irq(dev->irq[0], locomokbd);
> +	free_irq(locomokbd->irq, locomokbd);

Is not needed with devm.

>  
>  	del_timer_sync(&locomokbd->timer);

Should likely to go into close().

>  
>  	input_unregister_device(locomokbd->input);

Is not needed with devm.

> -	locomo_set_drvdata(dev, NULL);
>  
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int locomokbd_suspend(struct device *dev)

Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  
> -	kfree(locomokbd);
> +	del_timer_sync(&locomokbd->timer);
>  
>  	return 0;
>  }
>  
> -static struct locomo_driver keyboard_driver = {
> -	.drv = {
> -		.name = "locomokbd"
> +static int locomokbd_resume(struct device *dev)

__maybe_unused as well.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +	locomokbd_scankeyboard(locomokbd);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
> +#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
> +#else
> +#define LOCOMO_KBD_PM	NULL
> +#endif

Just do

static SIMPLE_DEV_PM_OPS(locomo_kbd_pm,
			 locomokbd_suspend, locomokbd_resume);


outside of #ifdef, it will produce the right thing (an empty structure).

> +
> +static struct platform_driver locomokbd_driver = {
> +	.driver = {
> +		.name	= "locomo-kbd",
> +		.pm	= LOCOMO_KBD_PM,

		.pm	= &locomo_kbd_pm;
>  	},
> -	.devid	= LOCOMO_DEVID_KEYBOARD,
>  	.probe	= locomokbd_probe,
>  	.remove	= locomokbd_remove,
>  };
>  
> -static int __init locomokbd_init(void)
> -{
> -	return locomo_driver_register(&keyboard_driver);
> -}
> -
> -static void __exit locomokbd_exit(void)
> -{
> -	locomo_driver_unregister(&keyboard_driver);
> -}
> +module_platform_driver(locomokbd_driver);
>  
> -module_init(locomokbd_init);
> -module_exit(locomokbd_exit);
> +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> +MODULE_DESCRIPTION("LoCoMo keyboard driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-kbd");
> -- 
> 2.1.4
> 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 20:21       ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 20:21 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Dmitry,

On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> As LoCoMo is switching to new device model, adapt keyboard driver to
> support new locomo core driver.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/Kconfig     |   1 -
>  drivers/input/keyboard/locomokbd.c | 271 +++++++++++++++++++------------------
>  2 files changed, 143 insertions(+), 129 deletions(-)
> 
> diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
> index 106fbac..0a3d875 100644
> --- a/drivers/input/keyboard/Kconfig
> +++ b/drivers/input/keyboard/Kconfig
> @@ -337,7 +337,6 @@ config KEYBOARD_LM8333
>  
>  config KEYBOARD_LOCOMO
>  	tristate "LoCoMo Keyboard Support"
> -	depends on SHARP_LOCOMO
>  	help
>  	  Say Y here if you are running Linux on a Sharp Zaurus Collie or Poodle based PDA
>  
> diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
> index c94d610..eed0a94 100644
> --- a/drivers/input/keyboard/locomokbd.c
> +++ b/drivers/input/keyboard/locomokbd.c
> @@ -23,37 +23,37 @@
>   *
>   */
>  
> -#include <linux/slab.h>
> -#include <linux/module.h>
> +#include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/input.h>
> -#include <linux/delay.h>
> -#include <linux/device.h>
>  #include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -
> -#include <asm/hardware/locomo.h>
> -#include <asm/irq.h>
> -
> -MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> -MODULE_DESCRIPTION("LoCoMo keyboard driver");
> -MODULE_LICENSE("GPL");
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/mfd/locomo.h>
>  
> -#define LOCOMOKBD_NUMKEYS	128
> +/* There is one minor difference between mappings on poodle and collie */
> +#include <asm/mach-types.h>
>  
>  #define KEY_ACTIVITY		KEY_F16
>  #define KEY_CONTACT		KEY_F18
>  #define KEY_CENTER		KEY_F15
>  
> +#define KB_ROWS			16
> +#define KB_COLS			8
> +#define LOCOMOKBD_NUMKEYS	(KB_ROWS * KB_COLS)
> +#define SCANCODE(c, r)		(((c)<<4) + (r) + 1)
> +
>  static const unsigned char
>  locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	0, KEY_ESC, KEY_ACTIVITY, 0, 0, 0, 0, 0, 0, 0,				/* 0 - 9 */
> -	0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_HOME, KEY_CONTACT,			/* 10 - 19 */
> +	0, 0, 0, 0, 0, 0, 0, KEY_MENU, 0, KEY_CONTACT,				/* 10 - 19 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,						/* 20 - 29 */
>  	0, 0, 0, KEY_CENTER, 0, KEY_MAIL, 0, 0, 0, 0,				/* 30 - 39 */
>  	0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RIGHT,					/* 40 - 49 */
>  	KEY_UP, KEY_LEFT, 0, 0, KEY_P, 0, KEY_O, KEY_I, KEY_Y, KEY_T,		/* 50 - 59 */
> -	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_ENTER, 0, 0,			/* 60 - 69 */
> +	KEY_E, KEY_W, 0, 0, 0, 0, KEY_DOWN, KEY_KPENTER, 0, 0,			/* 60 - 69 */
>  	KEY_BACKSPACE, 0, KEY_L, KEY_U, KEY_H, KEY_R, KEY_D, KEY_Q, 0, 0,	/* 70 - 79 */
>  	0, 0, 0, 0, 0, 0, KEY_ENTER, KEY_RIGHTSHIFT, KEY_K, KEY_J,		/* 80 - 89 */
>  	KEY_G, KEY_F, KEY_X, KEY_S, 0, 0, 0, 0, 0, 0,				/* 90 - 99 */
> @@ -62,20 +62,14 @@ locomokbd_keycode[LOCOMOKBD_NUMKEYS] = {
>  	KEY_M, KEY_SPACE, KEY_V, KEY_APOSTROPHE, KEY_SLASH, 0, 0, 0		/* 120 - 128 */
>  };
>  
> -#define KB_ROWS			16
> -#define KB_COLS			8
> -#define KB_ROWMASK(r)		(1 << (r))
> -#define SCANCODE(c,r)		( ((c)<<4) + (r) + 1 )
> -
>  #define KB_DELAY		8
> -#define SCAN_INTERVAL		(HZ/10)
>  
>  struct locomokbd {
>  	unsigned char keycode[LOCOMOKBD_NUMKEYS];
>  	struct input_dev *input;
> -	char phys[32];
>  
> -	unsigned long base;
> +	struct regmap *regmap;
> +	int irq;
>  	spinlock_t lock;
>  
>  	struct timer_list timer;
> @@ -84,37 +78,33 @@ struct locomokbd {
>  };
>  
>  /* helper functions for reading the keyboard matrix */
> -static inline void locomokbd_charge_all(unsigned long membase)
> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>  {
> -	locomo_writel(0x00FF, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>  }
>  
> -static inline void locomokbd_activate_all(unsigned long membase)
> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)

Drop "inline"s from the .c file please.

>  {
> -	unsigned long r;
> -
> -	locomo_writel(0, membase + LOCOMO_KSC);
> -	r = locomo_readl(membase + LOCOMO_KIC);
> -	r &= 0xFEFF;
> -	locomo_writel(r, membase + LOCOMO_KIC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>  }
>  
> -static inline void locomokbd_activate_col(unsigned long membase, int col)
> +static inline void locomokbd_activate_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nset;
>  	unsigned short nbset;
>  
> -	nset = 0xFF & ~(1 << col);
> +	nset = 0xFF & ~BIT(col);
>  	nbset = (nset << 8) + nset;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
> -static inline void locomokbd_reset_col(unsigned long membase, int col)
> +static inline void locomokbd_reset_col(struct locomokbd *locomokbd, int col)
>  {
>  	unsigned short nbset;
>  
> -	nbset = ((0xFF & ~(1 << col)) << 8) + 0xFF;
> -	locomo_writel(nbset, membase + LOCOMO_KSC);
> +	nbset = ((0xFF & ~BIT(col)) << 8) + 0xFF;
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, nbset);
>  }
>  
>  /*
> @@ -129,24 +119,25 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  	unsigned int row, col, rowd;
>  	unsigned long flags;
>  	unsigned int num_pressed;
> -	unsigned long membase = locomokbd->base;
> +	bool esc_pressed = false;
>  
>  	spin_lock_irqsave(&locomokbd->lock, flags);
>  
> -	locomokbd_charge_all(membase);
> +	locomokbd_charge_all(locomokbd);
>  
>  	num_pressed = 0;
>  	for (col = 0; col < KB_COLS; col++) {
> -
> -		locomokbd_activate_col(membase, col);
> +		udelay(KB_DELAY);
> +		locomokbd_activate_col(locomokbd, col);
>  		udelay(KB_DELAY);
>  
> -		rowd = ~locomo_readl(membase + LOCOMO_KIB);
> +		regmap_read(locomokbd->regmap, LOCOMO_KIB, &rowd);
> +		rowd = ~rowd;
>  		for (row = 0; row < KB_ROWS; row++) {
>  			unsigned int scancode, pressed, key;
>  
>  			scancode = SCANCODE(col, row);
> -			pressed = rowd & KB_ROWMASK(row);
> +			pressed = rowd & BIT(row);
>  			key = locomokbd->keycode[scancode];
>  
>  			input_report_key(locomokbd->input, key, pressed);
> @@ -158,29 +149,30 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  			/* The "Cancel/ESC" key is labeled "On/Off" on
>  			 * Collie and Poodle and should suspend the device
>  			 * if it was pressed for more than a second. */
> -			if (unlikely(key == KEY_ESC)) {
> -				if (!time_after(jiffies,
> -					locomokbd->suspend_jiffies + HZ))
> -					continue;
> -				if (locomokbd->count_cancel++
> -					!= (HZ/SCAN_INTERVAL + 1))
> -					continue;
> -				input_event(locomokbd->input, EV_PWR,
> -					KEY_SUSPEND, 1);
> -				locomokbd->suspend_jiffies = jiffies;
> -			} else
> -				locomokbd->count_cancel = 0;
> +			if (unlikely(key == KEY_ESC))
> +				esc_pressed = true;
>  		}
> -		locomokbd_reset_col(membase, col);
> +		locomokbd_reset_col(locomokbd, col);
>  	}
> -	locomokbd_activate_all(membase);
> +	locomokbd_activate_all(locomokbd);
>  
>  	input_sync(locomokbd->input);
>  
>  	/* if any keys are pressed, enable the timer */
>  	if (num_pressed)
> -		mod_timer(&locomokbd->timer, jiffies + SCAN_INTERVAL);
> +		mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(100));
>  	else
> +		regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +
> +	if (esc_pressed && time_after(jiffies,
> +		    locomokbd->suspend_jiffies + msecs_to_jiffies(1000))) {
> +		if (locomokbd->count_cancel++ > (20)) {

Why parentheses around 20?

> +			input_event(locomokbd->input, EV_PWR,
> +					KEY_SUSPEND, 1);
> +			locomokbd->suspend_jiffies = jiffies;
> +		}
> +	} else
>  		locomokbd->count_cancel = 0;

If one branch has curly braces the other should have them too.

>  
>  	spin_unlock_irqrestore(&locomokbd->lock, flags);
> @@ -192,18 +184,18 @@ static void locomokbd_scankeyboard(struct locomokbd *locomokbd)
>  static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
>  {
>  	struct locomokbd *locomokbd = dev_id;
> -	u16 r;
> +	unsigned int r;
>  
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_read(locomokbd->regmap, LOCOMO_KIC, &r);
>  	if ((r & 0x0001) == 0)
>  		return IRQ_HANDLED;
>  
> -	locomo_writel(r & ~0x0100, locomokbd->base + LOCOMO_KIC); /* Ack */
> +	/* Mask and Ack */
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, r & ~0x110);
>  
> -	/** wait chattering delay **/
> -	udelay(100);
> +	mod_timer(&locomokbd->timer, jiffies + msecs_to_jiffies(1));
>  
> -	locomokbd_scankeyboard(locomokbd);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -220,47 +212,37 @@ static void locomokbd_timer_callback(unsigned long data)
>  static int locomokbd_open(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) | 0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> -	return 0;
> +
> +	return regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
>  }
>  
>  static void locomokbd_close(struct input_dev *dev)
>  {
>  	struct locomokbd *locomokbd = input_get_drvdata(dev);
> -	u16 r;
> -	
> -	r = locomo_readl(locomokbd->base + LOCOMO_KIC) & ~0x0010;
> -	locomo_writel(r, locomokbd->base + LOCOMO_KIC);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  }
>  
> -static int locomokbd_probe(struct locomo_dev *dev)
> +static int locomokbd_probe(struct platform_device *dev)
>  {
>  	struct locomokbd *locomokbd;
>  	struct input_dev *input_dev;
>  	int i, err;
>  
> -	locomokbd = kzalloc(sizeof(struct locomokbd), GFP_KERNEL);
> -	input_dev = input_allocate_device();
> -	if (!locomokbd || !input_dev) {
> -		err = -ENOMEM;
> -		goto err_free_mem;
> -	}
> +	locomokbd = devm_kzalloc(&dev->dev, sizeof(struct locomokbd),
> +			GFP_KERNEL);
> +	if (!locomokbd)
> +		return -ENOMEM;
>  
> -	/* try and claim memory region */
> -	if (!request_mem_region((unsigned long) dev->mapbase,
> -				dev->length,
> -				LOCOMO_DRIVER_NAME(dev))) {
> -		err = -EBUSY;
> -		printk(KERN_ERR "locomokbd: Can't acquire access to io memory for keyboard\n");
> -		goto err_free_mem;
> -	}
> +	locomokbd->regmap = dev_get_regmap(dev->dev.parent, NULL);
> +	if (!locomokbd->regmap)
> +		return -EINVAL;
>  
> -	locomo_set_drvdata(dev, locomokbd);
> +	locomokbd->irq = platform_get_irq(dev, 0);
> +	if (locomokbd->irq < 0)
> +		return -ENXIO;
>  
> -	locomokbd->base = (unsigned long) dev->mapbase;
> +	platform_set_drvdata(dev, locomokbd);
>  
>  	spin_lock_init(&locomokbd->lock);
>  
> @@ -270,11 +252,13 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	locomokbd->suspend_jiffies = jiffies;
>  
> -	locomokbd->input = input_dev;
> -	strcpy(locomokbd->phys, "locomokbd/input0");
> +	input_dev = input_allocate_device();

devm_input_allocate_device()?

> +	if (!input_dev)
> +		return -ENOMEM;
>  
> +	locomokbd->input = input_dev;
>  	input_dev->name = "LoCoMo keyboard";
> -	input_dev->phys = locomokbd->phys;
> +	input_dev->phys = "locomokbd/input0";
>  	input_dev->id.bustype = BUS_HOST;
>  	input_dev->id.vendor = 0x0001;
>  	input_dev->id.product = 0x0001;
> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	input_set_drvdata(input_dev, locomokbd);
>  
> -	memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> +	memcpy(locomokbd->keycode,
> +			locomokbd_keycode,
> +			sizeof(locomokbd->keycode));
> +
> +	if (machine_is_collie())
> +		locomokbd->keycode[18] = KEY_HOME;
> +	else
> +		locomokbd->keycode[3] = KEY_HOME;

This seems like a new addition. Ideally keymap twiddling shoudl be done
from userspace.

> +
>  	for (i = 0; i < LOCOMOKBD_NUMKEYS; i++)
> -		set_bit(locomokbd->keycode[i], input_dev->keybit);
> -	clear_bit(0, input_dev->keybit);
> +		input_set_capability(input_dev, EV_KEY, locomokbd->keycode[i]);
> +	input_set_capability(input_dev, EV_PWR, KEY_SUSPEND);
> +	__set_bit(EV_REP, input_dev->evbit);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x0);
> +	regmap_write(locomokbd->regmap, LOCOMO_KIC, 0x0);
>  
>  	/* attempt to get the interrupt */
> -	err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> +	err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> +			"locomokbd", locomokbd);

devm_request_irq()?

>  	if (err) {
> -		printk(KERN_ERR "locomokbd: Can't get irq for keyboard\n");
> -		goto err_release_region;
> +		dev_err(&dev->dev, "locomokbd: Can't get irq for keyboard\n");
> +		goto err_free_mem;
>  	}
>  
>  	err = input_register_device(locomokbd->input);
> @@ -309,54 +307,71 @@ static int locomokbd_probe(struct locomo_dev *dev)
>  
>  	return 0;
>  
> - err_free_irq:
> -	free_irq(dev->irq[0], locomokbd);
> - err_release_region:
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> -	locomo_set_drvdata(dev, NULL);
> - err_free_mem:
> +err_free_irq:
> +	free_irq(locomokbd->irq, locomokbd);
> +err_free_mem:
>  	input_free_device(input_dev);
> -	kfree(locomokbd);
>  
>  	return err;
>  }
>  
> -static int locomokbd_remove(struct locomo_dev *dev)
> +static int locomokbd_remove(struct platform_device *dev)
>  {
> -	struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> +	struct locomokbd *locomokbd = platform_get_drvdata(dev);
>  
> -	free_irq(dev->irq[0], locomokbd);
> +	free_irq(locomokbd->irq, locomokbd);

Is not needed with devm.

>  
>  	del_timer_sync(&locomokbd->timer);

Should likely to go into close().

>  
>  	input_unregister_device(locomokbd->input);

Is not needed with devm.

> -	locomo_set_drvdata(dev, NULL);
>  
> -	release_mem_region((unsigned long) dev->mapbase, dev->length);
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int locomokbd_suspend(struct device *dev)

Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x0);
>  
> -	kfree(locomokbd);
> +	del_timer_sync(&locomokbd->timer);
>  
>  	return 0;
>  }
>  
> -static struct locomo_driver keyboard_driver = {
> -	.drv = {
> -		.name = "locomokbd"
> +static int locomokbd_resume(struct device *dev)

__maybe_unused as well.

> +{
> +	struct locomokbd *locomokbd = dev_get_drvdata(dev);
> +
> +	regmap_write(locomokbd->regmap, LOCOMO_KCMD, 1);
> +	regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> +	regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x10, 0x10);
> +
> +	locomokbd_scankeyboard(locomokbd);
> +
> +	return 0;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(locomo_kbd_pm, locomokbd_suspend, locomokbd_resume);
> +#define LOCOMO_KBD_PM	(&locomo_kbd_pm)
> +#else
> +#define LOCOMO_KBD_PM	NULL
> +#endif

Just do

static SIMPLE_DEV_PM_OPS(locomo_kbd_pm,
			 locomokbd_suspend, locomokbd_resume);


outside of #ifdef, it will produce the right thing (an empty structure).

> +
> +static struct platform_driver locomokbd_driver = {
> +	.driver = {
> +		.name	= "locomo-kbd",
> +		.pm	= LOCOMO_KBD_PM,

		.pm	= &locomo_kbd_pm;
>  	},
> -	.devid	= LOCOMO_DEVID_KEYBOARD,
>  	.probe	= locomokbd_probe,
>  	.remove	= locomokbd_remove,
>  };
>  
> -static int __init locomokbd_init(void)
> -{
> -	return locomo_driver_register(&keyboard_driver);
> -}
> -
> -static void __exit locomokbd_exit(void)
> -{
> -	locomo_driver_unregister(&keyboard_driver);
> -}
> +module_platform_driver(locomokbd_driver);
>  
> -module_init(locomokbd_init);
> -module_exit(locomokbd_exit);
> +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>");
> +MODULE_DESCRIPTION("LoCoMo keyboard driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:locomo-kbd");
> -- 
> 2.1.4
> 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
  2015-04-28 18:45       ` Lee Jones
  (?)
  (?)
@ 2015-05-12 20:39         ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:39 UTC (permalink / raw)
  To: Lee Jones
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
>
>> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
>> several design issues (special bus instead of platform bus, doesn't use
>> mfd-core, etc).
>>
>> Implement 'core' parts of locomo support as an mfd driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review. I agree (and have implemented) with most of
your comments.
However I have few questions. See below.

>
>> +/* the following is the overall data for the locomo chip */
>> +struct locomo {
>> +     struct device *dev;
>> +     unsigned int irq;
>> +     spinlock_t lock;
>> +     struct irq_domain *domain;
>> +     struct regmap *regmap;
>> +};
>> +
>> +static struct resource locomo_kbd_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
>> +};
>> +
>> +static struct resource locomo_gpio_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> I'd prefer you didn't use globals for this.

Just for platform data, or for all the structures?

>> +static struct resource locomo_lt_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
>> +};
>> +
>> +static struct resource locomo_spi_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
>> +
>> +static struct mfd_cell locomo_cells[] = {
>> +     {
>> +             .name = "locomo-kbd",
>> +             .resources = locomo_kbd_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
>> +     },
>> +     {
>> +             .name = "locomo-gpio",
>> +             .resources = locomo_gpio_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
>> +             .platform_data = &locomo_gpio_pdata,
>> +             .pdata_size = sizeof(locomo_gpio_pdata),
>> +     },
>> +     {
>> +             .name = "locomo-lt", /* Long time timer */
>> +             .resources = locomo_lt_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
>> +     },
>> +     {
>> +             .name = "locomo-spi",
>> +             .resources = locomo_spi_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
>> +     },
>> +     {
>> +             .name = "locomo-led",
>> +     },
>> +     {
>> +             .name = "locomo-backlight",
>> +     },
>
> Please make these:
>
>> +     { .name = "locomo-led" },
>> +     { .name = "locomo-backlight" },
>
> ... and put them at the bottom.

They will be populated by of_compatible lines, so it makes little sense
to me. What about adding of compatibility lines to this patch?

>> +     while (1) {
>> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
>> +             req &= 0x0f00;
>
> What is this magic number?  Please #define it.

Adding comments to this function instead.

>
>> +             if (!req)
>> +                     break;
>> +
>> +             irq = ffs(req) - 9;
>
> Minus another random number?  Either define it or enter a comment.
>
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomo_suspend(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>> +
>> +     /* AUDIO */
>
> WHY ARE YOU SHOUTING?  Ironic eh? ;)
>
>> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
>> +
>> +     /*
>> +      * Original code disabled the clock depending on leds settings
>> +      * However we disable leds before suspend, thus it's safe
>> +      * to just assume this setting.
>> +      */
>> +     /* CLK32 off */
>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     /* 22MHz/24MHz clock off */
>> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
>> +
>> +     return 0;
>> +}
>> +
>> +static int locomo_resume(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>
> Do audio and clk sort themselves out?

PAIF and ACC registers are used only by audio parts of the device. However
there is no current Linux driver for those parts. The registers are cleared
in case the firmware has set something in them, but in future it will
be the task
of the audio driver to properly clear and restore them.

>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     return 0;
>> +}
>> +

[skipped]
>> +
>> +     if (pdata) {
>> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
>> +             locomo_lcd_pdata.comadj = pdata->comadj;
>> +     } else {
>> +             locomo_gpio_pdata.gpio_base = -1;
>> +             locomo_lcd_pdata.comadj = 128;
>> +     }
>
> struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> locomo_gpio_pdata = devm_kzalloc(<blah>);
>
> locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

I do not quite agree with you at this place. The passed platform_data
will be kmemdup()'ed inside platform core. So the whole struct will be
duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
the whole platform_data busyness, but that requires switching to DTS
first.

>> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
>> new file mode 100644
>> index 0000000..6729767
>> --- /dev/null
>> +++ b/include/linux/mfd/locomo.h

>> +/* MCS decoder for boot selecting */
>> +#define LOCOMO_MCSX0 0x10
>> +#define LOCOMO_MCSX1 0x14
>> +#define LOCOMO_MCSX2 0x18
>> +#define LOCOMO_MCSX3 0x1c
>
> These are pretty cryptic.  Any way of making them easier to identify.

No way. The names are based on old Sharp code. The drivers do not use
them, but I'd like to still keep the registers for the reference purposes.

>> +struct locomo_gpio_platform_data {
>> +     unsigned int gpio_base;
>> +};
>
> A struct for a single int seems overkill.
>
>> +struct locomo_lcd_platform_data {
>> +     u8 comadj;
>> +};
>> +
>> +struct locomo_platform_data {
>> +     unsigned int gpio_base;
>> +     u8 comadj;
>> +};
>
> Why do you need to pass gpio_base twice?

First: machine file -> core driver
Second: core driver -> gpio driver

The other way to do the same would be:

struct locomo_gpio_platform_data {
     unsigned int gpio_base;
};

struct locomo_lcd_platform_data {
     u8 comadj;
};

struct locomo_platform_data {
     struct locomo_gpio_platform_data gpio_pdata;
     struct locomo_lcd_platform_data lcd_pdata;
};

And to assign pointers to the passed data in the mfd_cells
during locomo_probe. Does that look better to you?

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-12 20:39         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:39 UTC (permalink / raw)
  To: Lee Jones
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
>
>> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
>> several design issues (special bus instead of platform bus, doesn't use
>> mfd-core, etc).
>>
>> Implement 'core' parts of locomo support as an mfd driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review. I agree (and have implemented) with most of
your comments.
However I have few questions. See below.

>
>> +/* the following is the overall data for the locomo chip */
>> +struct locomo {
>> +     struct device *dev;
>> +     unsigned int irq;
>> +     spinlock_t lock;
>> +     struct irq_domain *domain;
>> +     struct regmap *regmap;
>> +};
>> +
>> +static struct resource locomo_kbd_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
>> +};
>> +
>> +static struct resource locomo_gpio_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> I'd prefer you didn't use globals for this.

Just for platform data, or for all the structures?

>> +static struct resource locomo_lt_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
>> +};
>> +
>> +static struct resource locomo_spi_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
>> +
>> +static struct mfd_cell locomo_cells[] = {
>> +     {
>> +             .name = "locomo-kbd",
>> +             .resources = locomo_kbd_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
>> +     },
>> +     {
>> +             .name = "locomo-gpio",
>> +             .resources = locomo_gpio_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
>> +             .platform_data = &locomo_gpio_pdata,
>> +             .pdata_size = sizeof(locomo_gpio_pdata),
>> +     },
>> +     {
>> +             .name = "locomo-lt", /* Long time timer */
>> +             .resources = locomo_lt_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
>> +     },
>> +     {
>> +             .name = "locomo-spi",
>> +             .resources = locomo_spi_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
>> +     },
>> +     {
>> +             .name = "locomo-led",
>> +     },
>> +     {
>> +             .name = "locomo-backlight",
>> +     },
>
> Please make these:
>
>> +     { .name = "locomo-led" },
>> +     { .name = "locomo-backlight" },
>
> ... and put them at the bottom.

They will be populated by of_compatible lines, so it makes little sense
to me. What about adding of compatibility lines to this patch?

>> +     while (1) {
>> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
>> +             req &= 0x0f00;
>
> What is this magic number?  Please #define it.

Adding comments to this function instead.

>
>> +             if (!req)
>> +                     break;
>> +
>> +             irq = ffs(req) - 9;
>
> Minus another random number?  Either define it or enter a comment.
>
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomo_suspend(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>> +
>> +     /* AUDIO */
>
> WHY ARE YOU SHOUTING?  Ironic eh? ;)
>
>> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
>> +
>> +     /*
>> +      * Original code disabled the clock depending on leds settings
>> +      * However we disable leds before suspend, thus it's safe
>> +      * to just assume this setting.
>> +      */
>> +     /* CLK32 off */
>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     /* 22MHz/24MHz clock off */
>> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
>> +
>> +     return 0;
>> +}
>> +
>> +static int locomo_resume(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>
> Do audio and clk sort themselves out?

PAIF and ACC registers are used only by audio parts of the device. However
there is no current Linux driver for those parts. The registers are cleared
in case the firmware has set something in them, but in future it will
be the task
of the audio driver to properly clear and restore them.

>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     return 0;
>> +}
>> +

[skipped]
>> +
>> +     if (pdata) {
>> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
>> +             locomo_lcd_pdata.comadj = pdata->comadj;
>> +     } else {
>> +             locomo_gpio_pdata.gpio_base = -1;
>> +             locomo_lcd_pdata.comadj = 128;
>> +     }
>
> struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> locomo_gpio_pdata = devm_kzalloc(<blah>);
>
> locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

I do not quite agree with you at this place. The passed platform_data
will be kmemdup()'ed inside platform core. So the whole struct will be
duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
the whole platform_data busyness, but that requires switching to DTS
first.

>> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
>> new file mode 100644
>> index 0000000..6729767
>> --- /dev/null
>> +++ b/include/linux/mfd/locomo.h

>> +/* MCS decoder for boot selecting */
>> +#define LOCOMO_MCSX0 0x10
>> +#define LOCOMO_MCSX1 0x14
>> +#define LOCOMO_MCSX2 0x18
>> +#define LOCOMO_MCSX3 0x1c
>
> These are pretty cryptic.  Any way of making them easier to identify.

No way. The names are based on old Sharp code. The drivers do not use
them, but I'd like to still keep the registers for the reference purposes.

>> +struct locomo_gpio_platform_data {
>> +     unsigned int gpio_base;
>> +};
>
> A struct for a single int seems overkill.
>
>> +struct locomo_lcd_platform_data {
>> +     u8 comadj;
>> +};
>> +
>> +struct locomo_platform_data {
>> +     unsigned int gpio_base;
>> +     u8 comadj;
>> +};
>
> Why do you need to pass gpio_base twice?

First: machine file -> core driver
Second: core driver -> gpio driver

The other way to do the same would be:

struct locomo_gpio_platform_data {
     unsigned int gpio_base;
};

struct locomo_lcd_platform_data {
     u8 comadj;
};

struct locomo_platform_data {
     struct locomo_gpio_platform_data gpio_pdata;
     struct locomo_lcd_platform_data lcd_pdata;
};

And to assign pointers to the passed data in the mfd_cells
during locomo_probe. Does that look better to you?

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-12 20:39         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:39 UTC (permalink / raw)
  To: Lee Jones
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
>
>> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
>> several design issues (special bus instead of platform bus, doesn't use
>> mfd-core, etc).
>>
>> Implement 'core' parts of locomo support as an mfd driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review. I agree (and have implemented) with most of
your comments.
However I have few questions. See below.

>
>> +/* the following is the overall data for the locomo chip */
>> +struct locomo {
>> +     struct device *dev;
>> +     unsigned int irq;
>> +     spinlock_t lock;
>> +     struct irq_domain *domain;
>> +     struct regmap *regmap;
>> +};
>> +
>> +static struct resource locomo_kbd_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
>> +};
>> +
>> +static struct resource locomo_gpio_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> I'd prefer you didn't use globals for this.

Just for platform data, or for all the structures?

>> +static struct resource locomo_lt_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
>> +};
>> +
>> +static struct resource locomo_spi_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
>> +
>> +static struct mfd_cell locomo_cells[] = {
>> +     {
>> +             .name = "locomo-kbd",
>> +             .resources = locomo_kbd_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
>> +     },
>> +     {
>> +             .name = "locomo-gpio",
>> +             .resources = locomo_gpio_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
>> +             .platform_data = &locomo_gpio_pdata,
>> +             .pdata_size = sizeof(locomo_gpio_pdata),
>> +     },
>> +     {
>> +             .name = "locomo-lt", /* Long time timer */
>> +             .resources = locomo_lt_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
>> +     },
>> +     {
>> +             .name = "locomo-spi",
>> +             .resources = locomo_spi_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
>> +     },
>> +     {
>> +             .name = "locomo-led",
>> +     },
>> +     {
>> +             .name = "locomo-backlight",
>> +     },
>
> Please make these:
>
>> +     { .name = "locomo-led" },
>> +     { .name = "locomo-backlight" },
>
> ... and put them at the bottom.

They will be populated by of_compatible lines, so it makes little sense
to me. What about adding of compatibility lines to this patch?

>> +     while (1) {
>> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
>> +             req &= 0x0f00;
>
> What is this magic number?  Please #define it.

Adding comments to this function instead.

>
>> +             if (!req)
>> +                     break;
>> +
>> +             irq = ffs(req) - 9;
>
> Minus another random number?  Either define it or enter a comment.
>
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomo_suspend(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>> +
>> +     /* AUDIO */
>
> WHY ARE YOU SHOUTING?  Ironic eh? ;)
>
>> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
>> +
>> +     /*
>> +      * Original code disabled the clock depending on leds settings
>> +      * However we disable leds before suspend, thus it's safe
>> +      * to just assume this setting.
>> +      */
>> +     /* CLK32 off */
>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     /* 22MHz/24MHz clock off */
>> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
>> +
>> +     return 0;
>> +}
>> +
>> +static int locomo_resume(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>
> Do audio and clk sort themselves out?

PAIF and ACC registers are used only by audio parts of the device. However
there is no current Linux driver for those parts. The registers are cleared
in case the firmware has set something in them, but in future it will
be the task
of the audio driver to properly clear and restore them.

>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     return 0;
>> +}
>> +

[skipped]
>> +
>> +     if (pdata) {
>> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
>> +             locomo_lcd_pdata.comadj = pdata->comadj;
>> +     } else {
>> +             locomo_gpio_pdata.gpio_base = -1;
>> +             locomo_lcd_pdata.comadj = 128;
>> +     }
>
> struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> locomo_gpio_pdata = devm_kzalloc(<blah>);
>
> locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

I do not quite agree with you at this place. The passed platform_data
will be kmemdup()'ed inside platform core. So the whole struct will be
duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
the whole platform_data busyness, but that requires switching to DTS
first.

>> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
>> new file mode 100644
>> index 0000000..6729767
>> --- /dev/null
>> +++ b/include/linux/mfd/locomo.h

>> +/* MCS decoder for boot selecting */
>> +#define LOCOMO_MCSX0 0x10
>> +#define LOCOMO_MCSX1 0x14
>> +#define LOCOMO_MCSX2 0x18
>> +#define LOCOMO_MCSX3 0x1c
>
> These are pretty cryptic.  Any way of making them easier to identify.

No way. The names are based on old Sharp code. The drivers do not use
them, but I'd like to still keep the registers for the reference purposes.

>> +struct locomo_gpio_platform_data {
>> +     unsigned int gpio_base;
>> +};
>
> A struct for a single int seems overkill.
>
>> +struct locomo_lcd_platform_data {
>> +     u8 comadj;
>> +};
>> +
>> +struct locomo_platform_data {
>> +     unsigned int gpio_base;
>> +     u8 comadj;
>> +};
>
> Why do you need to pass gpio_base twice?

First: machine file -> core driver
Second: core driver -> gpio driver

The other way to do the same would be:

struct locomo_gpio_platform_data {
     unsigned int gpio_base;
};

struct locomo_lcd_platform_data {
     u8 comadj;
};

struct locomo_platform_data {
     struct locomo_gpio_platform_data gpio_pdata;
     struct locomo_lcd_platform_data lcd_pdata;
};

And to assign pointers to the passed data in the mfd_cells
during locomo_probe. Does that look better to you?

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-12 20:39         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:39 UTC (permalink / raw)
  To: linux-arm-kernel

2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
>
>> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
>> several design issues (special bus instead of platform bus, doesn't use
>> mfd-core, etc).
>>
>> Implement 'core' parts of locomo support as an mfd driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review. I agree (and have implemented) with most of
your comments.
However I have few questions. See below.

>
>> +/* the following is the overall data for the locomo chip */
>> +struct locomo {
>> +     struct device *dev;
>> +     unsigned int irq;
>> +     spinlock_t lock;
>> +     struct irq_domain *domain;
>> +     struct regmap *regmap;
>> +};
>> +
>> +static struct resource locomo_kbd_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
>> +};
>> +
>> +static struct resource locomo_gpio_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> I'd prefer you didn't use globals for this.

Just for platform data, or for all the structures?

>> +static struct resource locomo_lt_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
>> +};
>> +
>> +static struct resource locomo_spi_resources[] = {
>> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
>> +};
>> +
>> +/* Filled in locomo_probe() function. */
>> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
>> +
>> +static struct mfd_cell locomo_cells[] = {
>> +     {
>> +             .name = "locomo-kbd",
>> +             .resources = locomo_kbd_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
>> +     },
>> +     {
>> +             .name = "locomo-gpio",
>> +             .resources = locomo_gpio_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
>> +             .platform_data = &locomo_gpio_pdata,
>> +             .pdata_size = sizeof(locomo_gpio_pdata),
>> +     },
>> +     {
>> +             .name = "locomo-lt", /* Long time timer */
>> +             .resources = locomo_lt_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
>> +     },
>> +     {
>> +             .name = "locomo-spi",
>> +             .resources = locomo_spi_resources,
>> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
>> +     },
>> +     {
>> +             .name = "locomo-led",
>> +     },
>> +     {
>> +             .name = "locomo-backlight",
>> +     },
>
> Please make these:
>
>> +     { .name = "locomo-led" },
>> +     { .name = "locomo-backlight" },
>
> ... and put them at the bottom.

They will be populated by of_compatible lines, so it makes little sense
to me. What about adding of compatibility lines to this patch?

>> +     while (1) {
>> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
>> +             req &= 0x0f00;
>
> What is this magic number?  Please #define it.

Adding comments to this function instead.

>
>> +             if (!req)
>> +                     break;
>> +
>> +             irq = ffs(req) - 9;
>
> Minus another random number?  Either define it or enter a comment.
>
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomo_suspend(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>> +
>> +     /* AUDIO */
>
> WHY ARE YOU SHOUTING?  Ironic eh? ;)
>
>> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
>> +
>> +     /*
>> +      * Original code disabled the clock depending on leds settings
>> +      * However we disable leds before suspend, thus it's safe
>> +      * to just assume this setting.
>> +      */
>> +     /* CLK32 off */
>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     /* 22MHz/24MHz clock off */
>> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
>> +
>> +     return 0;
>> +}
>> +
>> +static int locomo_resume(struct device *dev)
>> +{
>> +     struct locomo *lchip = dev_get_drvdata(dev);
>
> Do audio and clk sort themselves out?

PAIF and ACC registers are used only by audio parts of the device. However
there is no current Linux driver for those parts. The registers are cleared
in case the firmware has set something in them, but in future it will
be the task
of the audio driver to properly clear and restore them.

>> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
>> +
>> +     return 0;
>> +}
>> +

[skipped]
>> +
>> +     if (pdata) {
>> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
>> +             locomo_lcd_pdata.comadj = pdata->comadj;
>> +     } else {
>> +             locomo_gpio_pdata.gpio_base = -1;
>> +             locomo_lcd_pdata.comadj = 128;
>> +     }
>
> struct locomo_gpio_platform_data locomo_gpio_pdata;
>
> locomo_gpio_pdata = devm_kzalloc(<blah>);
>
> locomo_cells[GPIO].platform_data = locomo_gpio_pdata;

I do not quite agree with you at this place. The passed platform_data
will be kmemdup()'ed inside platform core. So the whole struct will be
duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
the whole platform_data busyness, but that requires switching to DTS
first.

>> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
>> new file mode 100644
>> index 0000000..6729767
>> --- /dev/null
>> +++ b/include/linux/mfd/locomo.h

>> +/* MCS decoder for boot selecting */
>> +#define LOCOMO_MCSX0 0x10
>> +#define LOCOMO_MCSX1 0x14
>> +#define LOCOMO_MCSX2 0x18
>> +#define LOCOMO_MCSX3 0x1c
>
> These are pretty cryptic.  Any way of making them easier to identify.

No way. The names are based on old Sharp code. The drivers do not use
them, but I'd like to still keep the registers for the reference purposes.

>> +struct locomo_gpio_platform_data {
>> +     unsigned int gpio_base;
>> +};
>
> A struct for a single int seems overkill.
>
>> +struct locomo_lcd_platform_data {
>> +     u8 comadj;
>> +};
>> +
>> +struct locomo_platform_data {
>> +     unsigned int gpio_base;
>> +     u8 comadj;
>> +};
>
> Why do you need to pass gpio_base twice?

First: machine file -> core driver
Second: core driver -> gpio driver

The other way to do the same would be:

struct locomo_gpio_platform_data {
     unsigned int gpio_base;
};

struct locomo_lcd_platform_data {
     u8 comadj;
};

struct locomo_platform_data {
     struct locomo_gpio_platform_data gpio_pdata;
     struct locomo_lcd_platform_data lcd_pdata;
};

And to assign pointers to the passed data in the mfd_cells
during locomo_probe. Does that look better to you?

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
  2015-05-12 20:12       ` Dmitry Torokhov
  (?)
  (?)
@ 2015-05-12 20:40         ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:40 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds,
	linux-spi

2015-05-12 23:12 GMT+03:00 Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
>> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
>> able to trigger sysrq functions directly. Add an option providing sysrq
>> mapping for Contact-Home keys.
>
> No, if you want to remap the keys please do it from usepspace; locomokbd
> supports it (EVIOCSKEYCODE ioctl).

OK, this was useful to boot kernels with minimal to no userspace (tiny
initramfs)
and still have the SysRQ at hand. I'll keep this as a local/OE patch instead.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-05-12 20:40         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:40 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds,
	linux-spi,

2015-05-12 23:12 GMT+03:00 Dmitry Torokhov <dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
>> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
>> able to trigger sysrq functions directly. Add an option providing sysrq
>> mapping for Contact-Home keys.
>
> No, if you want to remap the keys please do it from usepspace; locomokbd
> supports it (EVIOCSKEYCODE ioctl).

OK, this was useful to boot kernels with minimal to no userspace (tiny
initramfs)
and still have the SysRQ at hand. I'll keep this as a local/OE patch instead.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-05-12 20:40         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:40 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds,
	linux-spi

2015-05-12 23:12 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
>> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
>> able to trigger sysrq functions directly. Add an option providing sysrq
>> mapping for Contact-Home keys.
>
> No, if you want to remap the keys please do it from usepspace; locomokbd
> supports it (EVIOCSKEYCODE ioctl).

OK, this was useful to boot kernels with minimal to no userspace (tiny
initramfs)
and still have the SysRQ at hand. I'll keep this as a local/OE patch instead.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination
@ 2015-05-12 20:40         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 20:40 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-12 23:12 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:41AM +0300, Dmitry Eremin-Solenikov wrote:
>> It is usefull sometimes to have an Alt-SysRQ combo on the keyboard to be
>> able to trigger sysrq functions directly. Add an option providing sysrq
>> mapping for Contact-Home keys.
>
> No, if you want to remap the keys please do it from usepspace; locomokbd
> supports it (EVIOCSKEYCODE ioctl).

OK, this was useful to boot kernels with minimal to no userspace (tiny
initramfs)
and still have the SysRQ at hand. I'll keep this as a local/OE patch instead.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
  2015-05-12 20:21       ` Dmitry Torokhov
  (?)
  (?)
@ 2015-05-12 21:01         ` Dmitry Eremin-Solenikov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 21:01 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

Hello,

2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
>> As LoCoMo is switching to new device model, adapt keyboard driver to
>> support new locomo core driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review.

>>  /* helper functions for reading the keyboard matrix */
>> -static inline void locomokbd_charge_all(unsigned long membase)
>> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>>  {
>> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>>  }
>>
>> -static inline void locomokbd_activate_all(unsigned long membase)
>> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
>
> Drop "inline"s from the .c file please.

Why?

>
>>  {
>> -     unsigned long r;
>> -
>> -     locomo_writel(0, membase + LOCOMO_KSC);
>> -     r = locomo_readl(membase + LOCOMO_KIC);
>> -     r &= 0xFEFF;
>> -     locomo_writel(r, membase + LOCOMO_KIC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
>> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>>  }
>>

[skipped]

>> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>>
>>       input_set_drvdata(input_dev, locomokbd);
>>
>> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
>> +     memcpy(locomokbd->keycode,
>> +                     locomokbd_keycode,
>> +                     sizeof(locomokbd->keycode));
>> +
>> +     if (machine_is_collie())
>> +             locomokbd->keycode[18] = KEY_HOME;
>> +     else
>> +             locomokbd->keycode[3] = KEY_HOME;
>
> This seems like a new addition. Ideally keymap twiddling shoudl be done
> from userspace.

This fixes a hardware issue. Home key is wired differently on two
devices using this driver.
I'd prefer to have such setting in board file or in DTS in future,
however that looks like an
overkill. What would be your suggestion?

>>       /* attempt to get the interrupt */
>> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
>> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
>> +                     "locomokbd", locomokbd);
>
> devm_request_irq()?
>
[skipped]

>> -static int locomokbd_remove(struct locomo_dev *dev)
>> +static int locomokbd_remove(struct platform_device *dev)
>>  {
>> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
>> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
>>
>> -     free_irq(dev->irq[0], locomokbd);
>> +     free_irq(locomokbd->irq, locomokbd);
>
> Is not needed with devm.

Not quite. There will be a possibility for the IRQ to happen after deleting
a timer in locomokbd_remove() and before freeing the IRQ through the devres
core. Oops.

>
>>
>>       del_timer_sync(&locomokbd->timer);
>
> Should likely to go into close().

Hmm. I will rethink this part, thank you.

>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomokbd_suspend(struct device *dev)
>
> Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

Fine, however I thought that #ifdef's here are a typical pattern.

[skipped the rest]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:01         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 21:01 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi,

Hello,

2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
>> As LoCoMo is switching to new device model, adapt keyboard driver to
>> support new locomo core driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review.

>>  /* helper functions for reading the keyboard matrix */
>> -static inline void locomokbd_charge_all(unsigned long membase)
>> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>>  {
>> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>>  }
>>
>> -static inline void locomokbd_activate_all(unsigned long membase)
>> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
>
> Drop "inline"s from the .c file please.

Why?

>
>>  {
>> -     unsigned long r;
>> -
>> -     locomo_writel(0, membase + LOCOMO_KSC);
>> -     r = locomo_readl(membase + LOCOMO_KIC);
>> -     r &= 0xFEFF;
>> -     locomo_writel(r, membase + LOCOMO_KIC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
>> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>>  }
>>

[skipped]

>> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>>
>>       input_set_drvdata(input_dev, locomokbd);
>>
>> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
>> +     memcpy(locomokbd->keycode,
>> +                     locomokbd_keycode,
>> +                     sizeof(locomokbd->keycode));
>> +
>> +     if (machine_is_collie())
>> +             locomokbd->keycode[18] = KEY_HOME;
>> +     else
>> +             locomokbd->keycode[3] = KEY_HOME;
>
> This seems like a new addition. Ideally keymap twiddling shoudl be done
> from userspace.

This fixes a hardware issue. Home key is wired differently on two
devices using this driver.
I'd prefer to have such setting in board file or in DTS in future,
however that looks like an
overkill. What would be your suggestion?

>>       /* attempt to get the interrupt */
>> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
>> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
>> +                     "locomokbd", locomokbd);
>
> devm_request_irq()?
>
[skipped]

>> -static int locomokbd_remove(struct locomo_dev *dev)
>> +static int locomokbd_remove(struct platform_device *dev)
>>  {
>> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
>> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
>>
>> -     free_irq(dev->irq[0], locomokbd);
>> +     free_irq(locomokbd->irq, locomokbd);
>
> Is not needed with devm.

Not quite. There will be a possibility for the IRQ to happen after deleting
a timer in locomokbd_remove() and before freeing the IRQ through the devres
core. Oops.

>
>>
>>       del_timer_sync(&locomokbd->timer);
>
> Should likely to go into close().

Hmm. I will rethink this part, thank you.

>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomokbd_suspend(struct device *dev)
>
> Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

Fine, however I thought that #ifdef's here are a typical pattern.

[skipped the rest]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:01         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 21:01 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

Hello,

2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
>> As LoCoMo is switching to new device model, adapt keyboard driver to
>> support new locomo core driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review.

>>  /* helper functions for reading the keyboard matrix */
>> -static inline void locomokbd_charge_all(unsigned long membase)
>> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>>  {
>> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>>  }
>>
>> -static inline void locomokbd_activate_all(unsigned long membase)
>> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
>
> Drop "inline"s from the .c file please.

Why?

>
>>  {
>> -     unsigned long r;
>> -
>> -     locomo_writel(0, membase + LOCOMO_KSC);
>> -     r = locomo_readl(membase + LOCOMO_KIC);
>> -     r &= 0xFEFF;
>> -     locomo_writel(r, membase + LOCOMO_KIC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
>> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>>  }
>>

[skipped]

>> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>>
>>       input_set_drvdata(input_dev, locomokbd);
>>
>> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
>> +     memcpy(locomokbd->keycode,
>> +                     locomokbd_keycode,
>> +                     sizeof(locomokbd->keycode));
>> +
>> +     if (machine_is_collie())
>> +             locomokbd->keycode[18] = KEY_HOME;
>> +     else
>> +             locomokbd->keycode[3] = KEY_HOME;
>
> This seems like a new addition. Ideally keymap twiddling shoudl be done
> from userspace.

This fixes a hardware issue. Home key is wired differently on two
devices using this driver.
I'd prefer to have such setting in board file or in DTS in future,
however that looks like an
overkill. What would be your suggestion?

>>       /* attempt to get the interrupt */
>> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
>> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
>> +                     "locomokbd", locomokbd);
>
> devm_request_irq()?
>
[skipped]

>> -static int locomokbd_remove(struct locomo_dev *dev)
>> +static int locomokbd_remove(struct platform_device *dev)
>>  {
>> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
>> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
>>
>> -     free_irq(dev->irq[0], locomokbd);
>> +     free_irq(locomokbd->irq, locomokbd);
>
> Is not needed with devm.

Not quite. There will be a possibility for the IRQ to happen after deleting
a timer in locomokbd_remove() and before freeing the IRQ through the devres
core. Oops.

>
>>
>>       del_timer_sync(&locomokbd->timer);
>
> Should likely to go into close().

Hmm. I will rethink this part, thank you.

>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomokbd_suspend(struct device *dev)
>
> Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

Fine, however I thought that #ifdef's here are a typical pattern.

[skipped the rest]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:01         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-12 21:01 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> Hi Dmitry,
>
> On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
>> As LoCoMo is switching to new device model, adapt keyboard driver to
>> support new locomo core driver.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---

Thanks for the review.

>>  /* helper functions for reading the keyboard matrix */
>> -static inline void locomokbd_charge_all(unsigned long membase)
>> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
>>  {
>> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
>>  }
>>
>> -static inline void locomokbd_activate_all(unsigned long membase)
>> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
>
> Drop "inline"s from the .c file please.

Why?

>
>>  {
>> -     unsigned long r;
>> -
>> -     locomo_writel(0, membase + LOCOMO_KSC);
>> -     r = locomo_readl(membase + LOCOMO_KIC);
>> -     r &= 0xFEFF;
>> -     locomo_writel(r, membase + LOCOMO_KIC);
>> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
>> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
>>  }
>>

[skipped]

>> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
>>
>>       input_set_drvdata(input_dev, locomokbd);
>>
>> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
>> +     memcpy(locomokbd->keycode,
>> +                     locomokbd_keycode,
>> +                     sizeof(locomokbd->keycode));
>> +
>> +     if (machine_is_collie())
>> +             locomokbd->keycode[18] = KEY_HOME;
>> +     else
>> +             locomokbd->keycode[3] = KEY_HOME;
>
> This seems like a new addition. Ideally keymap twiddling shoudl be done
> from userspace.

This fixes a hardware issue. Home key is wired differently on two
devices using this driver.
I'd prefer to have such setting in board file or in DTS in future,
however that looks like an
overkill. What would be your suggestion?

>>       /* attempt to get the interrupt */
>> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
>> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
>> +                     "locomokbd", locomokbd);
>
> devm_request_irq()?
>
[skipped]

>> -static int locomokbd_remove(struct locomo_dev *dev)
>> +static int locomokbd_remove(struct platform_device *dev)
>>  {
>> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
>> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
>>
>> -     free_irq(dev->irq[0], locomokbd);
>> +     free_irq(locomokbd->irq, locomokbd);
>
> Is not needed with devm.

Not quite. There will be a possibility for the IRQ to happen after deleting
a timer in locomokbd_remove() and before freeing the IRQ through the devres
core. Oops.

>
>>
>>       del_timer_sync(&locomokbd->timer);
>
> Should likely to go into close().

Hmm. I will rethink this part, thank you.

>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int locomokbd_suspend(struct device *dev)
>
> Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.

Fine, however I thought that #ifdef's here are a typical pattern.

[skipped the rest]

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
  2015-05-12 21:01         ` Dmitry Eremin-Solenikov
  (?)
  (?)
@ 2015-05-12 21:13           ` Dmitry Torokhov
  -1 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 21:13 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

On Wed, May 13, 2015 at 12:01:23AM +0300, Dmitry Eremin-Solenikov wrote:
> Hello,
> 
> 2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> > Hi Dmitry,
> >
> > On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> >> As LoCoMo is switching to new device model, adapt keyboard driver to
> >> support new locomo core driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review.
> 
> >>  /* helper functions for reading the keyboard matrix */
> >> -static inline void locomokbd_charge_all(unsigned long membase)
> >> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
> >>  {
> >> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
> >>  }
> >>
> >> -static inline void locomokbd_activate_all(unsigned long membase)
> >> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
> >
> > Drop "inline"s from the .c file please.
> 
> Why?

Because compiler usually knows better whether a function should be
inlined or not as it keeps track of available registers, so leave the
decision to it.

> 
> >
> >>  {
> >> -     unsigned long r;
> >> -
> >> -     locomo_writel(0, membase + LOCOMO_KSC);
> >> -     r = locomo_readl(membase + LOCOMO_KIC);
> >> -     r &= 0xFEFF;
> >> -     locomo_writel(r, membase + LOCOMO_KIC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> >> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> >>  }
> >>
> 
> [skipped]
> 
> >> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
> >>
> >>       input_set_drvdata(input_dev, locomokbd);
> >>
> >> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> >> +     memcpy(locomokbd->keycode,
> >> +                     locomokbd_keycode,
> >> +                     sizeof(locomokbd->keycode));
> >> +
> >> +     if (machine_is_collie())
> >> +             locomokbd->keycode[18] = KEY_HOME;
> >> +     else
> >> +             locomokbd->keycode[3] = KEY_HOME;
> >
> > This seems like a new addition. Ideally keymap twiddling shoudl be done
> > from userspace.
> 
> This fixes a hardware issue. Home key is wired differently on two
> devices using this driver.
> I'd prefer to have such setting in board file or in DTS in future,
> however that looks like an
> overkill. What would be your suggestion?

I am OK with doing this in driver, just as a separate patch please.

> 
> >>       /* attempt to get the interrupt */
> >> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> >> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> >> +                     "locomokbd", locomokbd);
> >
> > devm_request_irq()?
> >
> [skipped]
> 
> >> -static int locomokbd_remove(struct locomo_dev *dev)
> >> +static int locomokbd_remove(struct platform_device *dev)
> >>  {
> >> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> >> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
> >>
> >> -     free_irq(dev->irq[0], locomokbd);
> >> +     free_irq(locomokbd->irq, locomokbd);
> >
> > Is not needed with devm.
> 
> Not quite. There will be a possibility for the IRQ to happen after deleting
> a timer in locomokbd_remove() and before freeing the IRQ through the devres
> core. Oops.

Right, but if you make sure that device does not generate interrupts in
probe() until open() is called and do the same in close(), then it
should be OK.

> 
> >
> >>
> >>       del_timer_sync(&locomokbd->timer);
> >
> > Should likely to go into close().
> 
> Hmm. I will rethink this part, thank you.
> 
> >> +
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomokbd_suspend(struct device *dev)
> >
> > Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.
> 
> Fine, however I thought that #ifdef's here are a typical pattern.

It is up to subsystems, __maybe_unused provides better compile coverage.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:13           ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 21:13 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi,

On Wed, May 13, 2015 at 12:01:23AM +0300, Dmitry Eremin-Solenikov wrote:
> Hello,
> 
> 2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> > Hi Dmitry,
> >
> > On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> >> As LoCoMo is switching to new device model, adapt keyboard driver to
> >> support new locomo core driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review.
> 
> >>  /* helper functions for reading the keyboard matrix */
> >> -static inline void locomokbd_charge_all(unsigned long membase)
> >> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
> >>  {
> >> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
> >>  }
> >>
> >> -static inline void locomokbd_activate_all(unsigned long membase)
> >> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
> >
> > Drop "inline"s from the .c file please.
> 
> Why?

Because compiler usually knows better whether a function should be
inlined or not as it keeps track of available registers, so leave the
decision to it.

> 
> >
> >>  {
> >> -     unsigned long r;
> >> -
> >> -     locomo_writel(0, membase + LOCOMO_KSC);
> >> -     r = locomo_readl(membase + LOCOMO_KIC);
> >> -     r &= 0xFEFF;
> >> -     locomo_writel(r, membase + LOCOMO_KIC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> >> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> >>  }
> >>
> 
> [skipped]
> 
> >> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
> >>
> >>       input_set_drvdata(input_dev, locomokbd);
> >>
> >> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> >> +     memcpy(locomokbd->keycode,
> >> +                     locomokbd_keycode,
> >> +                     sizeof(locomokbd->keycode));
> >> +
> >> +     if (machine_is_collie())
> >> +             locomokbd->keycode[18] = KEY_HOME;
> >> +     else
> >> +             locomokbd->keycode[3] = KEY_HOME;
> >
> > This seems like a new addition. Ideally keymap twiddling shoudl be done
> > from userspace.
> 
> This fixes a hardware issue. Home key is wired differently on two
> devices using this driver.
> I'd prefer to have such setting in board file or in DTS in future,
> however that looks like an
> overkill. What would be your suggestion?

I am OK with doing this in driver, just as a separate patch please.

> 
> >>       /* attempt to get the interrupt */
> >> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> >> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> >> +                     "locomokbd", locomokbd);
> >
> > devm_request_irq()?
> >
> [skipped]
> 
> >> -static int locomokbd_remove(struct locomo_dev *dev)
> >> +static int locomokbd_remove(struct platform_device *dev)
> >>  {
> >> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> >> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
> >>
> >> -     free_irq(dev->irq[0], locomokbd);
> >> +     free_irq(locomokbd->irq, locomokbd);
> >
> > Is not needed with devm.
> 
> Not quite. There will be a possibility for the IRQ to happen after deleting
> a timer in locomokbd_remove() and before freeing the IRQ through the devres
> core. Oops.

Right, but if you make sure that device does not generate interrupts in
probe() until open() is called and do the same in close(), then it
should be OK.

> 
> >
> >>
> >>       del_timer_sync(&locomokbd->timer);
> >
> > Should likely to go into close().
> 
> Hmm. I will rethink this part, thank you.
> 
> >> +
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomokbd_suspend(struct device *dev)
> >
> > Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.
> 
> Fine, however I thought that #ifdef's here are a typical pattern.

It is up to subsystems, __maybe_unused provides better compile coverage.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:13           ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 21:13 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Bryan Wu, Richard Purdie,
	Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

On Wed, May 13, 2015 at 12:01:23AM +0300, Dmitry Eremin-Solenikov wrote:
> Hello,
> 
> 2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> > Hi Dmitry,
> >
> > On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> >> As LoCoMo is switching to new device model, adapt keyboard driver to
> >> support new locomo core driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review.
> 
> >>  /* helper functions for reading the keyboard matrix */
> >> -static inline void locomokbd_charge_all(unsigned long membase)
> >> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
> >>  {
> >> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
> >>  }
> >>
> >> -static inline void locomokbd_activate_all(unsigned long membase)
> >> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
> >
> > Drop "inline"s from the .c file please.
> 
> Why?

Because compiler usually knows better whether a function should be
inlined or not as it keeps track of available registers, so leave the
decision to it.

> 
> >
> >>  {
> >> -     unsigned long r;
> >> -
> >> -     locomo_writel(0, membase + LOCOMO_KSC);
> >> -     r = locomo_readl(membase + LOCOMO_KIC);
> >> -     r &= 0xFEFF;
> >> -     locomo_writel(r, membase + LOCOMO_KIC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> >> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> >>  }
> >>
> 
> [skipped]
> 
> >> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
> >>
> >>       input_set_drvdata(input_dev, locomokbd);
> >>
> >> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> >> +     memcpy(locomokbd->keycode,
> >> +                     locomokbd_keycode,
> >> +                     sizeof(locomokbd->keycode));
> >> +
> >> +     if (machine_is_collie())
> >> +             locomokbd->keycode[18] = KEY_HOME;
> >> +     else
> >> +             locomokbd->keycode[3] = KEY_HOME;
> >
> > This seems like a new addition. Ideally keymap twiddling shoudl be done
> > from userspace.
> 
> This fixes a hardware issue. Home key is wired differently on two
> devices using this driver.
> I'd prefer to have such setting in board file or in DTS in future,
> however that looks like an
> overkill. What would be your suggestion?

I am OK with doing this in driver, just as a separate patch please.

> 
> >>       /* attempt to get the interrupt */
> >> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> >> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> >> +                     "locomokbd", locomokbd);
> >
> > devm_request_irq()?
> >
> [skipped]
> 
> >> -static int locomokbd_remove(struct locomo_dev *dev)
> >> +static int locomokbd_remove(struct platform_device *dev)
> >>  {
> >> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> >> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
> >>
> >> -     free_irq(dev->irq[0], locomokbd);
> >> +     free_irq(locomokbd->irq, locomokbd);
> >
> > Is not needed with devm.
> 
> Not quite. There will be a possibility for the IRQ to happen after deleting
> a timer in locomokbd_remove() and before freeing the IRQ through the devres
> core. Oops.

Right, but if you make sure that device does not generate interrupts in
probe() until open() is called and do the same in close(), then it
should be OK.

> 
> >
> >>
> >>       del_timer_sync(&locomokbd->timer);
> >
> > Should likely to go into close().
> 
> Hmm. I will rethink this part, thank you.
> 
> >> +
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomokbd_suspend(struct device *dev)
> >
> > Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.
> 
> Fine, however I thought that #ifdef's here are a typical pattern.

It is up to subsystems, __maybe_unused provides better compile coverage.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core
@ 2015-05-12 21:13           ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-12 21:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 13, 2015 at 12:01:23AM +0300, Dmitry Eremin-Solenikov wrote:
> Hello,
> 
> 2015-05-12 23:21 GMT+03:00 Dmitry Torokhov <dmitry.torokhov@gmail.com>:
> > Hi Dmitry,
> >
> > On Tue, Apr 28, 2015 at 02:55:40AM +0300, Dmitry Eremin-Solenikov wrote:
> >> As LoCoMo is switching to new device model, adapt keyboard driver to
> >> support new locomo core driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review.
> 
> >>  /* helper functions for reading the keyboard matrix */
> >> -static inline void locomokbd_charge_all(unsigned long membase)
> >> +static inline void locomokbd_charge_all(struct locomokbd *locomokbd)
> >>  {
> >> -     locomo_writel(0x00FF, membase + LOCOMO_KSC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0x00ff);
> >>  }
> >>
> >> -static inline void locomokbd_activate_all(unsigned long membase)
> >> +static inline void locomokbd_activate_all(struct locomokbd *locomokbd)
> >
> > Drop "inline"s from the .c file please.
> 
> Why?

Because compiler usually knows better whether a function should be
inlined or not as it keeps track of available registers, so leave the
decision to it.

> 
> >
> >>  {
> >> -     unsigned long r;
> >> -
> >> -     locomo_writel(0, membase + LOCOMO_KSC);
> >> -     r = locomo_readl(membase + LOCOMO_KIC);
> >> -     r &= 0xFEFF;
> >> -     locomo_writel(r, membase + LOCOMO_KIC);
> >> +     regmap_write(locomokbd->regmap, LOCOMO_KSC, 0);
> >> +     regmap_update_bits(locomokbd->regmap, LOCOMO_KIC, 0x100, 0);
> >>  }
> >>
> 
> [skipped]
> 
> >> @@ -291,16 +275,30 @@ static int locomokbd_probe(struct locomo_dev *dev)
> >>
> >>       input_set_drvdata(input_dev, locomokbd);
> >>
> >> -     memcpy(locomokbd->keycode, locomokbd_keycode, sizeof(locomokbd->keycode));
> >> +     memcpy(locomokbd->keycode,
> >> +                     locomokbd_keycode,
> >> +                     sizeof(locomokbd->keycode));
> >> +
> >> +     if (machine_is_collie())
> >> +             locomokbd->keycode[18] = KEY_HOME;
> >> +     else
> >> +             locomokbd->keycode[3] = KEY_HOME;
> >
> > This seems like a new addition. Ideally keymap twiddling shoudl be done
> > from userspace.
> 
> This fixes a hardware issue. Home key is wired differently on two
> devices using this driver.
> I'd prefer to have such setting in board file or in DTS in future,
> however that looks like an
> overkill. What would be your suggestion?

I am OK with doing this in driver, just as a separate patch please.

> 
> >>       /* attempt to get the interrupt */
> >> -     err = request_irq(dev->irq[0], locomokbd_interrupt, 0, "locomokbd", locomokbd);
> >> +     err = request_irq(locomokbd->irq, locomokbd_interrupt, 0,
> >> +                     "locomokbd", locomokbd);
> >
> > devm_request_irq()?
> >
> [skipped]
> 
> >> -static int locomokbd_remove(struct locomo_dev *dev)
> >> +static int locomokbd_remove(struct platform_device *dev)
> >>  {
> >> -     struct locomokbd *locomokbd = locomo_get_drvdata(dev);
> >> +     struct locomokbd *locomokbd = platform_get_drvdata(dev);
> >>
> >> -     free_irq(dev->irq[0], locomokbd);
> >> +     free_irq(locomokbd->irq, locomokbd);
> >
> > Is not needed with devm.
> 
> Not quite. There will be a possibility for the IRQ to happen after deleting
> a timer in locomokbd_remove() and before freeing the IRQ through the devres
> core. Oops.

Right, but if you make sure that device does not generate interrupts in
probe() until open() is called and do the same in close(), then it
should be OK.

> 
> >
> >>
> >>       del_timer_sync(&locomokbd->timer);
> >
> > Should likely to go into close().
> 
> Hmm. I will rethink this part, thank you.
> 
> >> +
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomokbd_suspend(struct device *dev)
> >
> > Mark as __maybe_unused instead of giarding with CONFIG_PM_SLEEP.
> 
> Fine, however I thought that #ifdef's here are a typical pattern.

It is up to subsystems, __maybe_unused provides better compile coverage.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
  2015-05-12 20:39         ` Dmitry Eremin-Solenikov
  (?)
  (?)
@ 2015-05-13  9:41           ` Lee Jones
  -1 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-05-13  9:41 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

On Tue, 12 May 2015, Dmitry Eremin-Solenikov wrote:

> 2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> > On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
> >
> >> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> >> several design issues (special bus instead of platform bus, doesn't use
> >> mfd-core, etc).
> >>
> >> Implement 'core' parts of locomo support as an mfd driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review. I agree (and have implemented) with most of
> your comments.
> However I have few questions. See below.
> 
> >
> >> +/* the following is the overall data for the locomo chip */
> >> +struct locomo {
> >> +     struct device *dev;
> >> +     unsigned int irq;
> >> +     spinlock_t lock;
> >> +     struct irq_domain *domain;
> >> +     struct regmap *regmap;
> >> +};
> >> +
> >> +static struct resource locomo_kbd_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> >> +};
> >> +
> >> +static struct resource locomo_gpio_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > I'd prefer you didn't use globals for this.
> 
> Just for platform data, or for all the structures?

Just for this.  The remainder are standard.

> >> +static struct resource locomo_lt_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> >> +};
> >> +
> >> +static struct resource locomo_spi_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> >> +
> >> +static struct mfd_cell locomo_cells[] = {
> >> +     {
> >> +             .name = "locomo-kbd",
> >> +             .resources = locomo_kbd_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-gpio",
> >> +             .resources = locomo_gpio_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
> >> +             .platform_data = &locomo_gpio_pdata,
> >> +             .pdata_size = sizeof(locomo_gpio_pdata),
> >> +     },
> >> +     {
> >> +             .name = "locomo-lt", /* Long time timer */
> >> +             .resources = locomo_lt_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-spi",
> >> +             .resources = locomo_spi_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-led",
> >> +     },
> >> +     {
> >> +             .name = "locomo-backlight",
> >> +     },
> >
> > Please make these:
> >
> >> +     { .name = "locomo-led" },
> >> +     { .name = "locomo-backlight" },
> >
> > ... and put them at the bottom.
> 
> They will be populated by of_compatible lines, so it makes little sense
> to me. What about adding of compatibility lines to this patch?

Also fine.

Although if you assure me you will do it, you can add them separately.

> >> +     while (1) {
> >> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> >> +             req &= 0x0f00;
> >
> > What is this magic number?  Please #define it.
> 
> Adding comments to this function instead.

Also acceptable.

> >> +             if (!req)
> >> +                     break;
> >> +
> >> +             irq = ffs(req) - 9;
> >
> > Minus another random number?  Either define it or enter a comment.
> >
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomo_suspend(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >> +
> >> +     /* AUDIO */
> >
> > WHY ARE YOU SHOUTING?  Ironic eh? ;)
> >
> >> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> >> +
> >> +     /*
> >> +      * Original code disabled the clock depending on leds settings
> >> +      * However we disable leds before suspend, thus it's safe
> >> +      * to just assume this setting.
> >> +      */
> >> +     /* CLK32 off */
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     /* 22MHz/24MHz clock off */
> >> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int locomo_resume(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >
> > Do audio and clk sort themselves out?
> 
> PAIF and ACC registers are used only by audio parts of the device. However
> there is no current Linux driver for those parts. The registers are cleared
> in case the firmware has set something in them, but in future it will
> be the task
> of the audio driver to properly clear and restore them.
> 
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> 
> [skipped]
> >> +
> >> +     if (pdata) {
> >> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> >> +             locomo_lcd_pdata.comadj = pdata->comadj;
> >> +     } else {
> >> +             locomo_gpio_pdata.gpio_base = -1;
> >> +             locomo_lcd_pdata.comadj = 128;
> >> +     }
> >
> > struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > locomo_gpio_pdata = devm_kzalloc(<blah>);
> >
> > locomo_cells[GPIO].platform_data = locomo_gpio_pdata;
> 
> I do not quite agree with you at this place. The passed platform_data
> will be kmemdup()'ed inside platform core. So the whole struct will be
> duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
> the whole platform_data busyness, but that requires switching to DTS
> first.

Sounds reasonable.

> >> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> >> new file mode 100644
> >> index 0000000..6729767
> >> --- /dev/null
> >> +++ b/include/linux/mfd/locomo.h
> 
> >> +/* MCS decoder for boot selecting */
> >> +#define LOCOMO_MCSX0 0x10
> >> +#define LOCOMO_MCSX1 0x14
> >> +#define LOCOMO_MCSX2 0x18
> >> +#define LOCOMO_MCSX3 0x1c
> >
> > These are pretty cryptic.  Any way of making them easier to identify.
> 
> No way. The names are based on old Sharp code. The drivers do not use
> them, but I'd like to still keep the registers for the reference purposes.

So they are not used at all?  Then why do you want to keep them?

> >> +struct locomo_gpio_platform_data {
> >> +     unsigned int gpio_base;
> >> +};
> >
> > A struct for a single int seems overkill.
> >
> >> +struct locomo_lcd_platform_data {
> >> +     u8 comadj;
> >> +};
> >> +
> >> +struct locomo_platform_data {
> >> +     unsigned int gpio_base;
> >> +     u8 comadj;
> >> +};
> >
> > Why do you need to pass gpio_base twice?
> 
> First: machine file -> core driver
> Second: core driver -> gpio driver
> 
> The other way to do the same would be:
> 
> struct locomo_gpio_platform_data {
>      unsigned int gpio_base;
> };
> 
> struct locomo_lcd_platform_data {
>      u8 comadj;
> };
> 
> struct locomo_platform_data {
>      struct locomo_gpio_platform_data gpio_pdata;
>      struct locomo_lcd_platform_data lcd_pdata;
> };
> 
> And to assign pointers to the passed data in the mfd_cells
> during locomo_probe. Does that look better to you?

Bingo.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-13  9:41           ` Lee Jones
  0 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-05-13  9:41 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

On Tue, 12 May 2015, Dmitry Eremin-Solenikov wrote:

> 2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> > On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
> >
> >> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> >> several design issues (special bus instead of platform bus, doesn't use
> >> mfd-core, etc).
> >>
> >> Implement 'core' parts of locomo support as an mfd driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review. I agree (and have implemented) with most of
> your comments.
> However I have few questions. See below.
> 
> >
> >> +/* the following is the overall data for the locomo chip */
> >> +struct locomo {
> >> +     struct device *dev;
> >> +     unsigned int irq;
> >> +     spinlock_t lock;
> >> +     struct irq_domain *domain;
> >> +     struct regmap *regmap;
> >> +};
> >> +
> >> +static struct resource locomo_kbd_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> >> +};
> >> +
> >> +static struct resource locomo_gpio_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > I'd prefer you didn't use globals for this.
> 
> Just for platform data, or for all the structures?

Just for this.  The remainder are standard.

> >> +static struct resource locomo_lt_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> >> +};
> >> +
> >> +static struct resource locomo_spi_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> >> +
> >> +static struct mfd_cell locomo_cells[] = {
> >> +     {
> >> +             .name = "locomo-kbd",
> >> +             .resources = locomo_kbd_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-gpio",
> >> +             .resources = locomo_gpio_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
> >> +             .platform_data = &locomo_gpio_pdata,
> >> +             .pdata_size = sizeof(locomo_gpio_pdata),
> >> +     },
> >> +     {
> >> +             .name = "locomo-lt", /* Long time timer */
> >> +             .resources = locomo_lt_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-spi",
> >> +             .resources = locomo_spi_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-led",
> >> +     },
> >> +     {
> >> +             .name = "locomo-backlight",
> >> +     },
> >
> > Please make these:
> >
> >> +     { .name = "locomo-led" },
> >> +     { .name = "locomo-backlight" },
> >
> > ... and put them at the bottom.
> 
> They will be populated by of_compatible lines, so it makes little sense
> to me. What about adding of compatibility lines to this patch?

Also fine.

Although if you assure me you will do it, you can add them separately.

> >> +     while (1) {
> >> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> >> +             req &= 0x0f00;
> >
> > What is this magic number?  Please #define it.
> 
> Adding comments to this function instead.

Also acceptable.

> >> +             if (!req)
> >> +                     break;
> >> +
> >> +             irq = ffs(req) - 9;
> >
> > Minus another random number?  Either define it or enter a comment.
> >
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomo_suspend(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >> +
> >> +     /* AUDIO */
> >
> > WHY ARE YOU SHOUTING?  Ironic eh? ;)
> >
> >> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> >> +
> >> +     /*
> >> +      * Original code disabled the clock depending on leds settings
> >> +      * However we disable leds before suspend, thus it's safe
> >> +      * to just assume this setting.
> >> +      */
> >> +     /* CLK32 off */
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     /* 22MHz/24MHz clock off */
> >> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int locomo_resume(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >
> > Do audio and clk sort themselves out?
> 
> PAIF and ACC registers are used only by audio parts of the device. However
> there is no current Linux driver for those parts. The registers are cleared
> in case the firmware has set something in them, but in future it will
> be the task
> of the audio driver to properly clear and restore them.
> 
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> 
> [skipped]
> >> +
> >> +     if (pdata) {
> >> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> >> +             locomo_lcd_pdata.comadj = pdata->comadj;
> >> +     } else {
> >> +             locomo_gpio_pdata.gpio_base = -1;
> >> +             locomo_lcd_pdata.comadj = 128;
> >> +     }
> >
> > struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > locomo_gpio_pdata = devm_kzalloc(<blah>);
> >
> > locomo_cells[GPIO].platform_data = locomo_gpio_pdata;
> 
> I do not quite agree with you at this place. The passed platform_data
> will be kmemdup()'ed inside platform core. So the whole struct will be
> duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
> the whole platform_data busyness, but that requires switching to DTS
> first.

Sounds reasonable.

> >> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> >> new file mode 100644
> >> index 0000000..6729767
> >> --- /dev/null
> >> +++ b/include/linux/mfd/locomo.h
> 
> >> +/* MCS decoder for boot selecting */
> >> +#define LOCOMO_MCSX0 0x10
> >> +#define LOCOMO_MCSX1 0x14
> >> +#define LOCOMO_MCSX2 0x18
> >> +#define LOCOMO_MCSX3 0x1c
> >
> > These are pretty cryptic.  Any way of making them easier to identify.
> 
> No way. The names are based on old Sharp code. The drivers do not use
> them, but I'd like to still keep the registers for the reference purposes.

So they are not used at all?  Then why do you want to keep them?

> >> +struct locomo_gpio_platform_data {
> >> +     unsigned int gpio_base;
> >> +};
> >
> > A struct for a single int seems overkill.
> >
> >> +struct locomo_lcd_platform_data {
> >> +     u8 comadj;
> >> +};
> >> +
> >> +struct locomo_platform_data {
> >> +     unsigned int gpio_base;
> >> +     u8 comadj;
> >> +};
> >
> > Why do you need to pass gpio_base twice?
> 
> First: machine file -> core driver
> Second: core driver -> gpio driver
> 
> The other way to do the same would be:
> 
> struct locomo_gpio_platform_data {
>      unsigned int gpio_base;
> };
> 
> struct locomo_lcd_platform_data {
>      u8 comadj;
> };
> 
> struct locomo_platform_data {
>      struct locomo_gpio_platform_data gpio_pdata;
>      struct locomo_lcd_platform_data lcd_pdata;
> };
> 
> And to assign pointers to the passed data in the mfd_cells
> during locomo_probe. Does that look better to you?

Bingo.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-13  9:41           ` Lee Jones
  0 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-05-13  9:41 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds, linux-spi

On Tue, 12 May 2015, Dmitry Eremin-Solenikov wrote:

> 2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> > On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
> >
> >> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> >> several design issues (special bus instead of platform bus, doesn't use
> >> mfd-core, etc).
> >>
> >> Implement 'core' parts of locomo support as an mfd driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review. I agree (and have implemented) with most of
> your comments.
> However I have few questions. See below.
> 
> >
> >> +/* the following is the overall data for the locomo chip */
> >> +struct locomo {
> >> +     struct device *dev;
> >> +     unsigned int irq;
> >> +     spinlock_t lock;
> >> +     struct irq_domain *domain;
> >> +     struct regmap *regmap;
> >> +};
> >> +
> >> +static struct resource locomo_kbd_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> >> +};
> >> +
> >> +static struct resource locomo_gpio_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > I'd prefer you didn't use globals for this.
> 
> Just for platform data, or for all the structures?

Just for this.  The remainder are standard.

> >> +static struct resource locomo_lt_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> >> +};
> >> +
> >> +static struct resource locomo_spi_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> >> +
> >> +static struct mfd_cell locomo_cells[] = {
> >> +     {
> >> +             .name = "locomo-kbd",
> >> +             .resources = locomo_kbd_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-gpio",
> >> +             .resources = locomo_gpio_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
> >> +             .platform_data = &locomo_gpio_pdata,
> >> +             .pdata_size = sizeof(locomo_gpio_pdata),
> >> +     },
> >> +     {
> >> +             .name = "locomo-lt", /* Long time timer */
> >> +             .resources = locomo_lt_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-spi",
> >> +             .resources = locomo_spi_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-led",
> >> +     },
> >> +     {
> >> +             .name = "locomo-backlight",
> >> +     },
> >
> > Please make these:
> >
> >> +     { .name = "locomo-led" },
> >> +     { .name = "locomo-backlight" },
> >
> > ... and put them at the bottom.
> 
> They will be populated by of_compatible lines, so it makes little sense
> to me. What about adding of compatibility lines to this patch?

Also fine.

Although if you assure me you will do it, you can add them separately.

> >> +     while (1) {
> >> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> >> +             req &= 0x0f00;
> >
> > What is this magic number?  Please #define it.
> 
> Adding comments to this function instead.

Also acceptable.

> >> +             if (!req)
> >> +                     break;
> >> +
> >> +             irq = ffs(req) - 9;
> >
> > Minus another random number?  Either define it or enter a comment.
> >
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomo_suspend(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >> +
> >> +     /* AUDIO */
> >
> > WHY ARE YOU SHOUTING?  Ironic eh? ;)
> >
> >> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> >> +
> >> +     /*
> >> +      * Original code disabled the clock depending on leds settings
> >> +      * However we disable leds before suspend, thus it's safe
> >> +      * to just assume this setting.
> >> +      */
> >> +     /* CLK32 off */
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     /* 22MHz/24MHz clock off */
> >> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int locomo_resume(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >
> > Do audio and clk sort themselves out?
> 
> PAIF and ACC registers are used only by audio parts of the device. However
> there is no current Linux driver for those parts. The registers are cleared
> in case the firmware has set something in them, but in future it will
> be the task
> of the audio driver to properly clear and restore them.
> 
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> 
> [skipped]
> >> +
> >> +     if (pdata) {
> >> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> >> +             locomo_lcd_pdata.comadj = pdata->comadj;
> >> +     } else {
> >> +             locomo_gpio_pdata.gpio_base = -1;
> >> +             locomo_lcd_pdata.comadj = 128;
> >> +     }
> >
> > struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > locomo_gpio_pdata = devm_kzalloc(<blah>);
> >
> > locomo_cells[GPIO].platform_data = locomo_gpio_pdata;
> 
> I do not quite agree with you at this place. The passed platform_data
> will be kmemdup()'ed inside platform core. So the whole struct will be
> duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
> the whole platform_data busyness, but that requires switching to DTS
> first.

Sounds reasonable.

> >> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> >> new file mode 100644
> >> index 0000000..6729767
> >> --- /dev/null
> >> +++ b/include/linux/mfd/locomo.h
> 
> >> +/* MCS decoder for boot selecting */
> >> +#define LOCOMO_MCSX0 0x10
> >> +#define LOCOMO_MCSX1 0x14
> >> +#define LOCOMO_MCSX2 0x18
> >> +#define LOCOMO_MCSX3 0x1c
> >
> > These are pretty cryptic.  Any way of making them easier to identify.
> 
> No way. The names are based on old Sharp code. The drivers do not use
> them, but I'd like to still keep the registers for the reference purposes.

So they are not used at all?  Then why do you want to keep them?

> >> +struct locomo_gpio_platform_data {
> >> +     unsigned int gpio_base;
> >> +};
> >
> > A struct for a single int seems overkill.
> >
> >> +struct locomo_lcd_platform_data {
> >> +     u8 comadj;
> >> +};
> >> +
> >> +struct locomo_platform_data {
> >> +     unsigned int gpio_base;
> >> +     u8 comadj;
> >> +};
> >
> > Why do you need to pass gpio_base twice?
> 
> First: machine file -> core driver
> Second: core driver -> gpio driver
> 
> The other way to do the same would be:
> 
> struct locomo_gpio_platform_data {
>      unsigned int gpio_base;
> };
> 
> struct locomo_lcd_platform_data {
>      u8 comadj;
> };
> 
> struct locomo_platform_data {
>      struct locomo_gpio_platform_data gpio_pdata;
>      struct locomo_lcd_platform_data lcd_pdata;
> };
> 
> And to assign pointers to the passed data in the mfd_cells
> during locomo_probe. Does that look better to you?

Bingo.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo
@ 2015-05-13  9:41           ` Lee Jones
  0 siblings, 0 replies; 148+ messages in thread
From: Lee Jones @ 2015-05-13  9:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 12 May 2015, Dmitry Eremin-Solenikov wrote:

> 2015-04-28 21:45 GMT+03:00 Lee Jones <lee.jones@linaro.org>:
> > On Tue, 28 Apr 2015, Dmitry Eremin-Solenikov wrote:
> >
> >> LoCoMo is a GA used on Sharp Zaurus SL-5x00. Current driver does has
> >> several design issues (special bus instead of platform bus, doesn't use
> >> mfd-core, etc).
> >>
> >> Implement 'core' parts of locomo support as an mfd driver.
> >>
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> 
> Thanks for the review. I agree (and have implemented) with most of
> your comments.
> However I have few questions. See below.
> 
> >
> >> +/* the following is the overall data for the locomo chip */
> >> +struct locomo {
> >> +     struct device *dev;
> >> +     unsigned int irq;
> >> +     spinlock_t lock;
> >> +     struct irq_domain *domain;
> >> +     struct regmap *regmap;
> >> +};
> >> +
> >> +static struct resource locomo_kbd_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_KEY),
> >> +};
> >> +
> >> +static struct resource locomo_gpio_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_GPIO),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > I'd prefer you didn't use globals for this.
> 
> Just for platform data, or for all the structures?

Just for this.  The remainder are standard.

> >> +static struct resource locomo_lt_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_LT),
> >> +};
> >> +
> >> +static struct resource locomo_spi_resources[] = {
> >> +     DEFINE_RES_IRQ(IRQ_LOCOMO_SPI),
> >> +};
> >> +
> >> +/* Filled in locomo_probe() function. */
> >> +static struct locomo_lcd_platform_data locomo_lcd_pdata;
> >> +
> >> +static struct mfd_cell locomo_cells[] = {
> >> +     {
> >> +             .name = "locomo-kbd",
> >> +             .resources = locomo_kbd_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_kbd_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-gpio",
> >> +             .resources = locomo_gpio_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_gpio_resources),
> >> +             .platform_data = &locomo_gpio_pdata,
> >> +             .pdata_size = sizeof(locomo_gpio_pdata),
> >> +     },
> >> +     {
> >> +             .name = "locomo-lt", /* Long time timer */
> >> +             .resources = locomo_lt_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_lt_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-spi",
> >> +             .resources = locomo_spi_resources,
> >> +             .num_resources = ARRAY_SIZE(locomo_spi_resources),
> >> +     },
> >> +     {
> >> +             .name = "locomo-led",
> >> +     },
> >> +     {
> >> +             .name = "locomo-backlight",
> >> +     },
> >
> > Please make these:
> >
> >> +     { .name = "locomo-led" },
> >> +     { .name = "locomo-backlight" },
> >
> > ... and put them at the bottom.
> 
> They will be populated by of_compatible lines, so it makes little sense
> to me. What about adding of compatibility lines to this patch?

Also fine.

Although if you assure me you will do it, you can add them separately.

> >> +     while (1) {
> >> +             regmap_read(lchip->regmap, LOCOMO_ICR, &req);
> >> +             req &= 0x0f00;
> >
> > What is this magic number?  Please #define it.
> 
> Adding comments to this function instead.

Also acceptable.

> >> +             if (!req)
> >> +                     break;
> >> +
> >> +             irq = ffs(req) - 9;
> >
> > Minus another random number?  Either define it or enter a comment.
> >
> >> +#ifdef CONFIG_PM_SLEEP
> >> +static int locomo_suspend(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >> +
> >> +     /* AUDIO */
> >
> > WHY ARE YOU SHOUTING?  Ironic eh? ;)
> >
> >> +     regmap_write(lchip->regmap, LOCOMO_PAIF, 0x00);
> >> +
> >> +     /*
> >> +      * Original code disabled the clock depending on leds settings
> >> +      * However we disable leds before suspend, thus it's safe
> >> +      * to just assume this setting.
> >> +      */
> >> +     /* CLK32 off */
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     /* 22MHz/24MHz clock off */
> >> +     regmap_write(lchip->regmap, LOCOMO_ACC, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int locomo_resume(struct device *dev)
> >> +{
> >> +     struct locomo *lchip = dev_get_drvdata(dev);
> >
> > Do audio and clk sort themselves out?
> 
> PAIF and ACC registers are used only by audio parts of the device. However
> there is no current Linux driver for those parts. The registers are cleared
> in case the firmware has set something in them, but in future it will
> be the task
> of the audio driver to properly clear and restore them.
> 
> >> +     regmap_write(lchip->regmap, LOCOMO_C32K, 0x00);
> >> +
> >> +     return 0;
> >> +}
> >> +
> 
> [skipped]
> >> +
> >> +     if (pdata) {
> >> +             locomo_gpio_pdata.gpio_base = pdata->gpio_base;
> >> +             locomo_lcd_pdata.comadj = pdata->comadj;
> >> +     } else {
> >> +             locomo_gpio_pdata.gpio_base = -1;
> >> +             locomo_lcd_pdata.comadj = 128;
> >> +     }
> >
> > struct locomo_gpio_platform_data locomo_gpio_pdata;
> >
> > locomo_gpio_pdata = devm_kzalloc(<blah>);
> >
> > locomo_cells[GPIO].platform_data = locomo_gpio_pdata;
> 
> I do not quite agree with you at this place. The passed platform_data
> will be kmemdup()'ed inside platform core. So the whole struct will be
> duplicated twice inside kmallocate'd memory. Ideally I'd like to drop
> the whole platform_data busyness, but that requires switching to DTS
> first.

Sounds reasonable.

> >> diff --git a/include/linux/mfd/locomo.h b/include/linux/mfd/locomo.h
> >> new file mode 100644
> >> index 0000000..6729767
> >> --- /dev/null
> >> +++ b/include/linux/mfd/locomo.h
> 
> >> +/* MCS decoder for boot selecting */
> >> +#define LOCOMO_MCSX0 0x10
> >> +#define LOCOMO_MCSX1 0x14
> >> +#define LOCOMO_MCSX2 0x18
> >> +#define LOCOMO_MCSX3 0x1c
> >
> > These are pretty cryptic.  Any way of making them easier to identify.
> 
> No way. The names are based on old Sharp code. The drivers do not use
> them, but I'd like to still keep the registers for the reference purposes.

So they are not used at all?  Then why do you want to keep them?

> >> +struct locomo_gpio_platform_data {
> >> +     unsigned int gpio_base;
> >> +};
> >
> > A struct for a single int seems overkill.
> >
> >> +struct locomo_lcd_platform_data {
> >> +     u8 comadj;
> >> +};
> >> +
> >> +struct locomo_platform_data {
> >> +     unsigned int gpio_base;
> >> +     u8 comadj;
> >> +};
> >
> > Why do you need to pass gpio_base twice?
> 
> First: machine file -> core driver
> Second: core driver -> gpio driver
> 
> The other way to do the same would be:
> 
> struct locomo_gpio_platform_data {
>      unsigned int gpio_base;
> };
> 
> struct locomo_lcd_platform_data {
>      u8 comadj;
> };
> 
> struct locomo_platform_data {
>      struct locomo_gpio_platform_data gpio_pdata;
>      struct locomo_lcd_platform_data lcd_pdata;
> };
> 
> And to assign pointers to the passed data in the mfd_cells
> during locomo_probe. Does that look better to you?

Bingo.

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
       [not found]       ` <CALT56yNJWapNw1XLrzfbUDUz1LF_BB9DfF94H6GhbnBUEP80_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2015-05-13 10:31           ` Jacek Anaszewski
  (?)
@ 2015-05-13 10:31           ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 10:31 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>
>>> Adapt locomo leds driver to new locomo core setup.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>> ---
>>>    drivers/leds/Kconfig       |   1 -
>>>    drivers/leds/leds-locomo.c | 119
>>> +++++++++++++++++++++++----------------------
>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>
>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>> index 966b960..4b4650b 100644
>>> --- a/drivers/leds/Kconfig
>>> +++ b/drivers/leds/Kconfig
>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>    config LEDS_LOCOMO
>>>          tristate "LED Support for Locomo device"
>>>          depends on LEDS_CLASS
>>> -       depends on SHARP_LOCOMO
>>
>>
>> Why do you remove this dependency?
>
> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> device and regmap interfaces, so there is no direct dependency on main
> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

Ack. Shouldn't you also need "select REGMAP_MMIO" ?

>>
>>>          help
>>>            This option enables support for the LEDs on Sharp Locomo.
>>>            Zaurus models SL-5500 and SL-5600.
>>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>>> index 80ba048..7fde812 100644
>>> --- a/drivers/leds/leds-locomo.c
>>> +++ b/drivers/leds/leds-locomo.c
>>> @@ -9,89 +9,92 @@
>>>     */
>>>
>>>    #include <linux/kernel.h>
>>> -#include <linux/init.h>
>>> -#include <linux/module.h>
>>> -#include <linux/device.h>
>>>    #include <linux/leds.h>
>>> -
>>> -#include <mach/hardware.h>
>>> -#include <asm/hardware/locomo.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/mfd/locomo.h>
>>
>>
>> Please keep alphabetical order.
>
> Ack
>
>>
>>> +
>>> +struct locomo_led {
>>> +       struct led_classdev led;
>>> +       struct regmap *regmap;
>>> +       unsigned int reg;
>>> +};
>>>
>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>> -                               enum led_brightness value, int offset)
>>> +                               enum led_brightness value)
>>>    {
>>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>>> -       unsigned long flags;
>>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>>> led);
>>>
>>> -       local_irq_save(flags);
>>> -       if (value)
>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>> offset);
>>> -       else
>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>> offset);
>>> -       local_irq_restore(flags);
>>> +       regmap_write(led->regmap, led->reg,
>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>    }
>>
>>
>> Please use work queue for setting brightness. This is required for the
>> driver to be compatible with led triggers. You can refer to the
>> existing LED drivers on how to implement this.
>
> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
> and doesn't need to be wrapped into work queue, does it?

Triggers can call brightness_set op in the interrupt context, so it
cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
I am inferring that it can sleep.

I am not sure if regmap implements its 'lock' op when using MMIO.

The best way to figure this out is turning "LED Timer Trigger" on
in the config and execute:

echo "timer" > trigger

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 10:31           ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 10:31 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>
>>> Adapt locomo leds driver to new locomo core setup.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>> ---
>>>    drivers/leds/Kconfig       |   1 -
>>>    drivers/leds/leds-locomo.c | 119
>>> +++++++++++++++++++++++----------------------
>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>
>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>> index 966b960..4b4650b 100644
>>> --- a/drivers/leds/Kconfig
>>> +++ b/drivers/leds/Kconfig
>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>    config LEDS_LOCOMO
>>>          tristate "LED Support for Locomo device"
>>>          depends on LEDS_CLASS
>>> -       depends on SHARP_LOCOMO
>>
>>
>> Why do you remove this dependency?
>
> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> device and regmap interfaces, so there is no direct dependency on main
> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

Ack. Shouldn't you also need "select REGMAP_MMIO" ?

>>
>>>          help
>>>            This option enables support for the LEDs on Sharp Locomo.
>>>            Zaurus models SL-5500 and SL-5600.
>>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>>> index 80ba048..7fde812 100644
>>> --- a/drivers/leds/leds-locomo.c
>>> +++ b/drivers/leds/leds-locomo.c
>>> @@ -9,89 +9,92 @@
>>>     */
>>>
>>>    #include <linux/kernel.h>
>>> -#include <linux/init.h>
>>> -#include <linux/module.h>
>>> -#include <linux/device.h>
>>>    #include <linux/leds.h>
>>> -
>>> -#include <mach/hardware.h>
>>> -#include <asm/hardware/locomo.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/mfd/locomo.h>
>>
>>
>> Please keep alphabetical order.
>
> Ack
>
>>
>>> +
>>> +struct locomo_led {
>>> +       struct led_classdev led;
>>> +       struct regmap *regmap;
>>> +       unsigned int reg;
>>> +};
>>>
>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>> -                               enum led_brightness value, int offset)
>>> +                               enum led_brightness value)
>>>    {
>>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>>> -       unsigned long flags;
>>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>>> led);
>>>
>>> -       local_irq_save(flags);
>>> -       if (value)
>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>> offset);
>>> -       else
>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>> offset);
>>> -       local_irq_restore(flags);
>>> +       regmap_write(led->regmap, led->reg,
>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>    }
>>
>>
>> Please use work queue for setting brightness. This is required for the
>> driver to be compatible with led triggers. You can refer to the
>> existing LED drivers on how to implement this.
>
> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
> and doesn't need to be wrapped into work queue, does it?

Triggers can call brightness_set op in the interrupt context, so it
cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
I am inferring that it can sleep.

I am not sure if regmap implements its 'lock' op when using MMIO.

The best way to figure this out is turning "LED Timer Trigger" on
in the config and execute:

echo "timer" > trigger

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 10:31           ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 10:31 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>
>>> Adapt locomo leds driver to new locomo core setup.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>> ---
>>>    drivers/leds/Kconfig       |   1 -
>>>    drivers/leds/leds-locomo.c | 119
>>> +++++++++++++++++++++++----------------------
>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>
>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>> index 966b960..4b4650b 100644
>>> --- a/drivers/leds/Kconfig
>>> +++ b/drivers/leds/Kconfig
>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>    config LEDS_LOCOMO
>>>          tristate "LED Support for Locomo device"
>>>          depends on LEDS_CLASS
>>> -       depends on SHARP_LOCOMO
>>
>>
>> Why do you remove this dependency?
>
> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> device and regmap interfaces, so there is no direct dependency on main
> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

Ack. Shouldn't you also need "select REGMAP_MMIO" ?

>>
>>>          help
>>>            This option enables support for the LEDs on Sharp Locomo.
>>>            Zaurus models SL-5500 and SL-5600.
>>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>>> index 80ba048..7fde812 100644
>>> --- a/drivers/leds/leds-locomo.c
>>> +++ b/drivers/leds/leds-locomo.c
>>> @@ -9,89 +9,92 @@
>>>     */
>>>
>>>    #include <linux/kernel.h>
>>> -#include <linux/init.h>
>>> -#include <linux/module.h>
>>> -#include <linux/device.h>
>>>    #include <linux/leds.h>
>>> -
>>> -#include <mach/hardware.h>
>>> -#include <asm/hardware/locomo.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/mfd/locomo.h>
>>
>>
>> Please keep alphabetical order.
>
> Ack
>
>>
>>> +
>>> +struct locomo_led {
>>> +       struct led_classdev led;
>>> +       struct regmap *regmap;
>>> +       unsigned int reg;
>>> +};
>>>
>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>> -                               enum led_brightness value, int offset)
>>> +                               enum led_brightness value)
>>>    {
>>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>>> -       unsigned long flags;
>>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>>> led);
>>>
>>> -       local_irq_save(flags);
>>> -       if (value)
>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>> offset);
>>> -       else
>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>> offset);
>>> -       local_irq_restore(flags);
>>> +       regmap_write(led->regmap, led->reg,
>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>    }
>>
>>
>> Please use work queue for setting brightness. This is required for the
>> driver to be compatible with led triggers. You can refer to the
>> existing LED drivers on how to implement this.
>
> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
> and doesn't need to be wrapped into work queue, does it?

Triggers can call brightness_set op in the interrupt context, so it
cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
I am inferring that it can sleep.

I am not sure if regmap implements its 'lock' op when using MMIO.

The best way to figure this out is turning "LED Timer Trigger" on
in the config and execute:

echo "timer" > trigger

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 10:31           ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>
>>> Adapt locomo leds driver to new locomo core setup.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>> ---
>>>    drivers/leds/Kconfig       |   1 -
>>>    drivers/leds/leds-locomo.c | 119
>>> +++++++++++++++++++++++----------------------
>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>
>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>> index 966b960..4b4650b 100644
>>> --- a/drivers/leds/Kconfig
>>> +++ b/drivers/leds/Kconfig
>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>    config LEDS_LOCOMO
>>>          tristate "LED Support for Locomo device"
>>>          depends on LEDS_CLASS
>>> -       depends on SHARP_LOCOMO
>>
>>
>> Why do you remove this dependency?
>
> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> device and regmap interfaces, so there is no direct dependency on main
> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.

Ack. Shouldn't you also need "select REGMAP_MMIO" ?

>>
>>>          help
>>>            This option enables support for the LEDs on Sharp Locomo.
>>>            Zaurus models SL-5500 and SL-5600.
>>> diff --git a/drivers/leds/leds-locomo.c b/drivers/leds/leds-locomo.c
>>> index 80ba048..7fde812 100644
>>> --- a/drivers/leds/leds-locomo.c
>>> +++ b/drivers/leds/leds-locomo.c
>>> @@ -9,89 +9,92 @@
>>>     */
>>>
>>>    #include <linux/kernel.h>
>>> -#include <linux/init.h>
>>> -#include <linux/module.h>
>>> -#include <linux/device.h>
>>>    #include <linux/leds.h>
>>> -
>>> -#include <mach/hardware.h>
>>> -#include <asm/hardware/locomo.h>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/mfd/locomo.h>
>>
>>
>> Please keep alphabetical order.
>
> Ack
>
>>
>>> +
>>> +struct locomo_led {
>>> +       struct led_classdev led;
>>> +       struct regmap *regmap;
>>> +       unsigned int reg;
>>> +};
>>>
>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>> -                               enum led_brightness value, int offset)
>>> +                               enum led_brightness value)
>>>    {
>>> -       struct locomo_dev *locomo_dev = LOCOMO_DEV(led_cdev->dev->parent);
>>> -       unsigned long flags;
>>> +       struct locomo_led *led = container_of(led_cdev, struct locomo_led,
>>> led);
>>>
>>> -       local_irq_save(flags);
>>> -       if (value)
>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>> offset);
>>> -       else
>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>> offset);
>>> -       local_irq_restore(flags);
>>> +       regmap_write(led->regmap, led->reg,
>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>    }
>>
>>
>> Please use work queue for setting brightness. This is required for the
>> driver to be compatible with led triggers. You can refer to the
>> existing LED drivers on how to implement this.
>
> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
> and doesn't need to be wrapped into work queue, does it?

Triggers can call brightness_set op in the interrupt context, so it
cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
I am inferring that it can sleep.

I am not sure if regmap implements its 'lock' op when using MMIO.

The best way to figure this out is turning "LED Timer Trigger" on
in the config and execute:

echo "timer" > trigger

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
       [not found]           ` <555327EA.5060402-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  (?)
@ 2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-13 14:14 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>
>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
>>>
>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>
>>>>
>>>> Adapt locomo leds driver to new locomo core setup.
>>>>
>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>>> ---
>>>>    drivers/leds/Kconfig       |   1 -
>>>>    drivers/leds/leds-locomo.c | 119
>>>> +++++++++++++++++++++++----------------------
>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>>
>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>> index 966b960..4b4650b 100644
>>>> --- a/drivers/leds/Kconfig
>>>> +++ b/drivers/leds/Kconfig
>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>    config LEDS_LOCOMO
>>>>          tristate "LED Support for Locomo device"
>>>>          depends on LEDS_CLASS
>>>> -       depends on SHARP_LOCOMO
>>>
>>>
>>>
>>> Why do you remove this dependency?
>>
>>
>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>> device and regmap interfaces, so there is no direct dependency on main
>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>
>
> Ack. Shouldn't you also need "select REGMAP_MMIO" ?

No. Maybe I should add "select REGMAP" instead.

>>>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>> -                               enum led_brightness value, int offset)
>>>> +                               enum led_brightness value)
>>>>    {
>>>> -       struct locomo_dev *locomo_dev =
>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>> -       unsigned long flags;
>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>> locomo_led,
>>>> led);
>>>>
>>>> -       local_irq_save(flags);
>>>> -       if (value)
>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>> offset);
>>>> -       else
>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>> offset);
>>>> -       local_irq_restore(flags);
>>>> +       regmap_write(led->regmap, led->reg,
>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>    }
>>>
>>>
>>>
>>> Please use work queue for setting brightness. This is required for the
>>> driver to be compatible with led triggers. You can refer to the
>>> existing LED drivers on how to implement this.
>>
>>
>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>> and doesn't need to be wrapped into work queue, does it?
>
>
> Triggers can call brightness_set op in the interrupt context, so it
> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
> I am inferring that it can sleep.
>
> I am not sure if regmap implements its 'lock' op when using MMIO.
>
> The best way to figure this out is turning "LED Timer Trigger" on
> in the config and execute:
>
> echo "timer" > trigger

It works without any "might sleep/sleeping in atomic context" warnings.

Technically I'd agree with you. If I'm using regmaps, ideally I should not
depend on the exact backend and put working with it to the work queue.
However as this is a driver for quite old IP block, it is not used with
regmap backends other than MMIO, I'd deduce, it's ok to do things
in a more relaxed way and to call regmap_write even from atomic
contexts.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-13 14:14 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>
>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
>>>
>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>
>>>>
>>>> Adapt locomo leds driver to new locomo core setup.
>>>>
>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>>> ---
>>>>    drivers/leds/Kconfig       |   1 -
>>>>    drivers/leds/leds-locomo.c | 119
>>>> +++++++++++++++++++++++----------------------
>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>>
>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>> index 966b960..4b4650b 100644
>>>> --- a/drivers/leds/Kconfig
>>>> +++ b/drivers/leds/Kconfig
>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>    config LEDS_LOCOMO
>>>>          tristate "LED Support for Locomo device"
>>>>          depends on LEDS_CLASS
>>>> -       depends on SHARP_LOCOMO
>>>
>>>
>>>
>>> Why do you remove this dependency?
>>
>>
>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>> device and regmap interfaces, so there is no direct dependency on main
>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>
>
> Ack. Shouldn't you also need "select REGMAP_MMIO" ?

No. Maybe I should add "select REGMAP" instead.

>>>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>> -                               enum led_brightness value, int offset)
>>>> +                               enum led_brightness value)
>>>>    {
>>>> -       struct locomo_dev *locomo_dev =
>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>> -       unsigned long flags;
>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>> locomo_led,
>>>> led);
>>>>
>>>> -       local_irq_save(flags);
>>>> -       if (value)
>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>> offset);
>>>> -       else
>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>> offset);
>>>> -       local_irq_restore(flags);
>>>> +       regmap_write(led->regmap, led->reg,
>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>    }
>>>
>>>
>>>
>>> Please use work queue for setting brightness. This is required for the
>>> driver to be compatible with led triggers. You can refer to the
>>> existing LED drivers on how to implement this.
>>
>>
>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>> and doesn't need to be wrapped into work queue, does it?
>
>
> Triggers can call brightness_set op in the interrupt context, so it
> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
> I am inferring that it can sleep.
>
> I am not sure if regmap implements its 'lock' op when using MMIO.
>
> The best way to figure this out is turning "LED Timer Trigger" on
> in the config and execute:
>
> echo "timer" > trigger

It works without any "might sleep/sleeping in atomic context" warnings.

Technically I'd agree with you. If I'm using regmaps, ideally I should not
depend on the exact backend and put working with it to the work queue.
However as this is a driver for quite old IP block, it is not used with
regmap backends other than MMIO, I'd deduce, it's ok to do things
in a more relaxed way and to call regmap_write even from atomic
contexts.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-13 14:14 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>
>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>
>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>
>>>>
>>>> Adapt locomo leds driver to new locomo core setup.
>>>>
>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>> ---
>>>>    drivers/leds/Kconfig       |   1 -
>>>>    drivers/leds/leds-locomo.c | 119
>>>> +++++++++++++++++++++++----------------------
>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>>
>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>> index 966b960..4b4650b 100644
>>>> --- a/drivers/leds/Kconfig
>>>> +++ b/drivers/leds/Kconfig
>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>    config LEDS_LOCOMO
>>>>          tristate "LED Support for Locomo device"
>>>>          depends on LEDS_CLASS
>>>> -       depends on SHARP_LOCOMO
>>>
>>>
>>>
>>> Why do you remove this dependency?
>>
>>
>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>> device and regmap interfaces, so there is no direct dependency on main
>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>
>
> Ack. Shouldn't you also need "select REGMAP_MMIO" ?

No. Maybe I should add "select REGMAP" instead.

>>>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>> -                               enum led_brightness value, int offset)
>>>> +                               enum led_brightness value)
>>>>    {
>>>> -       struct locomo_dev *locomo_dev >>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>> -       unsigned long flags;
>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>> locomo_led,
>>>> led);
>>>>
>>>> -       local_irq_save(flags);
>>>> -       if (value)
>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>> offset);
>>>> -       else
>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>> offset);
>>>> -       local_irq_restore(flags);
>>>> +       regmap_write(led->regmap, led->reg,
>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>    }
>>>
>>>
>>>
>>> Please use work queue for setting brightness. This is required for the
>>> driver to be compatible with led triggers. You can refer to the
>>> existing LED drivers on how to implement this.
>>
>>
>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>> and doesn't need to be wrapped into work queue, does it?
>
>
> Triggers can call brightness_set op in the interrupt context, so it
> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
> I am inferring that it can sleep.
>
> I am not sure if regmap implements its 'lock' op when using MMIO.
>
> The best way to figure this out is turning "LED Timer Trigger" on
> in the config and execute:
>
> echo "timer" > trigger

It works without any "might sleep/sleeping in atomic context" warnings.

Technically I'd agree with you. If I'm using regmaps, ideally I should not
depend on the exact backend and put working with it to the work queue.
However as this is a driver for quite old IP block, it is not used with
regmap backends other than MMIO, I'd deduce, it's ok to do things
in a more relaxed way and to call regmap_write even from atomic
contexts.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-05-13 14:14 UTC (permalink / raw)
  To: linux-arm-kernel

2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>
>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>
>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>
>>>>
>>>> Adapt locomo leds driver to new locomo core setup.
>>>>
>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>> ---
>>>>    drivers/leds/Kconfig       |   1 -
>>>>    drivers/leds/leds-locomo.c | 119
>>>> +++++++++++++++++++++++----------------------
>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
>>>>
>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>> index 966b960..4b4650b 100644
>>>> --- a/drivers/leds/Kconfig
>>>> +++ b/drivers/leds/Kconfig
>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>    config LEDS_LOCOMO
>>>>          tristate "LED Support for Locomo device"
>>>>          depends on LEDS_CLASS
>>>> -       depends on SHARP_LOCOMO
>>>
>>>
>>>
>>> Why do you remove this dependency?
>>
>>
>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>> device and regmap interfaces, so there is no direct dependency on main
>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>
>
> Ack. Shouldn't you also need "select REGMAP_MMIO" ?

No. Maybe I should add "select REGMAP" instead.

>>>>   static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>> -                               enum led_brightness value, int offset)
>>>> +                               enum led_brightness value)
>>>>    {
>>>> -       struct locomo_dev *locomo_dev =
>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>> -       unsigned long flags;
>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>> locomo_led,
>>>> led);
>>>>
>>>> -       local_irq_save(flags);
>>>> -       if (value)
>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>> offset);
>>>> -       else
>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>> offset);
>>>> -       local_irq_restore(flags);
>>>> +       regmap_write(led->regmap, led->reg,
>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>    }
>>>
>>>
>>>
>>> Please use work queue for setting brightness. This is required for the
>>> driver to be compatible with led triggers. You can refer to the
>>> existing LED drivers on how to implement this.
>>
>>
>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>> and doesn't need to be wrapped into work queue, does it?
>
>
> Triggers can call brightness_set op in the interrupt context, so it
> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
> I am inferring that it can sleep.
>
> I am not sure if regmap implements its 'lock' op when using MMIO.
>
> The best way to figure this out is turning "LED Timer Trigger" on
> in the config and execute:
>
> echo "timer" > trigger

It works without any "might sleep/sleeping in atomic context" warnings.

Technically I'd agree with you. If I'm using regmaps, ideally I should not
depend on the exact backend and put working with it to the work queue.
However as this is a driver for quite old IP block, it is not used with
regmap backends other than MMIO, I'd deduce, it's ok to do things
in a more relaxed way and to call regmap_write even from atomic
contexts.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
  2015-05-13 14:14               ` Dmitry Eremin-Solenikov
  (?)
  (?)
@ 2015-05-13 14:53                 ` Jacek Anaszewski
  -1 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 14:53 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>
>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>
>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>>
>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>
>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>> ---
>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>     drivers/leds/leds-locomo.c | 119
>>>>> +++++++++++++++++++++++----------------------
>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>
>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>> index 966b960..4b4650b 100644
>>>>> --- a/drivers/leds/Kconfig
>>>>> +++ b/drivers/leds/Kconfig
>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>     config LEDS_LOCOMO
>>>>>           tristate "LED Support for Locomo device"
>>>>>           depends on LEDS_CLASS
>>>>> -       depends on SHARP_LOCOMO
>>>>
>>>>
>>>>
>>>> Why do you remove this dependency?
>>>
>>>
>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>> device and regmap interfaces, so there is no direct dependency on main
>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>
>>
>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>
> No. Maybe I should add "select REGMAP" instead.

REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
REGMAP_MMIO selected would also allow to notice at first glance which
regmap backend is used. This would in turn provide a straightforward
explanation on why brightness_set op is not delegated to work queue.

>>>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>>> -                               enum led_brightness value, int offset)
>>>>> +                               enum led_brightness value)
>>>>>     {
>>>>> -       struct locomo_dev *locomo_dev =
>>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>>> -       unsigned long flags;
>>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>>> locomo_led,
>>>>> led);
>>>>>
>>>>> -       local_irq_save(flags);
>>>>> -       if (value)
>>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       else
>>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       local_irq_restore(flags);
>>>>> +       regmap_write(led->regmap, led->reg,
>>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>>     }
>>>>
>>>>
>>>>
>>>> Please use work queue for setting brightness. This is required for the
>>>> driver to be compatible with led triggers. You can refer to the
>>>> existing LED drivers on how to implement this.
>>>
>>>
>>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>>> and doesn't need to be wrapped into work queue, does it?
>>
>>
>> Triggers can call brightness_set op in the interrupt context, so it
>> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
>> I am inferring that it can sleep.
>>
>> I am not sure if regmap implements its 'lock' op when using MMIO.
>>
>> The best way to figure this out is turning "LED Timer Trigger" on
>> in the config and execute:
>>
>> echo "timer" > trigger
>
> It works without any "might sleep/sleeping in atomic context" warnings.
>
> Technically I'd agree with you. If I'm using regmaps, ideally I should not
> depend on the exact backend and put working with it to the work queue.
> However as this is a driver for quite old IP block, it is not used with
> regmap backends other than MMIO, I'd deduce, it's ok to do things
> in a more relaxed way and to call regmap_write even from atomic
> contexts.

Ack.

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:53                 ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 14:53 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>
>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>
>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>>
>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>
>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>> ---
>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>     drivers/leds/leds-locomo.c | 119
>>>>> +++++++++++++++++++++++----------------------
>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>
>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>> index 966b960..4b4650b 100644
>>>>> --- a/drivers/leds/Kconfig
>>>>> +++ b/drivers/leds/Kconfig
>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>     config LEDS_LOCOMO
>>>>>           tristate "LED Support for Locomo device"
>>>>>           depends on LEDS_CLASS
>>>>> -       depends on SHARP_LOCOMO
>>>>
>>>>
>>>>
>>>> Why do you remove this dependency?
>>>
>>>
>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>> device and regmap interfaces, so there is no direct dependency on main
>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>
>>
>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>
> No. Maybe I should add "select REGMAP" instead.

REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
REGMAP_MMIO selected would also allow to notice at first glance which
regmap backend is used. This would in turn provide a straightforward
explanation on why brightness_set op is not delegated to work queue.

>>>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>>> -                               enum led_brightness value, int offset)
>>>>> +                               enum led_brightness value)
>>>>>     {
>>>>> -       struct locomo_dev *locomo_dev =
>>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>>> -       unsigned long flags;
>>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>>> locomo_led,
>>>>> led);
>>>>>
>>>>> -       local_irq_save(flags);
>>>>> -       if (value)
>>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       else
>>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       local_irq_restore(flags);
>>>>> +       regmap_write(led->regmap, led->reg,
>>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>>     }
>>>>
>>>>
>>>>
>>>> Please use work queue for setting brightness. This is required for the
>>>> driver to be compatible with led triggers. You can refer to the
>>>> existing LED drivers on how to implement this.
>>>
>>>
>>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>>> and doesn't need to be wrapped into work queue, does it?
>>
>>
>> Triggers can call brightness_set op in the interrupt context, so it
>> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
>> I am inferring that it can sleep.
>>
>> I am not sure if regmap implements its 'lock' op when using MMIO.
>>
>> The best way to figure this out is turning "LED Timer Trigger" on
>> in the config and execute:
>>
>> echo "timer" > trigger
>
> It works without any "might sleep/sleeping in atomic context" warnings.
>
> Technically I'd agree with you. If I'm using regmaps, ideally I should not
> depend on the exact backend and put working with it to the work queue.
> However as this is a driver for quite old IP block, it is not used with
> regmap backends other than MMIO, I'd deduce, it's ok to do things
> in a more relaxed way and to call regmap_write even from atomic
> contexts.

Ack.

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:53                 ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 14:53 UTC (permalink / raw)
  To: Dmitry Eremin-Solenikov
  Cc: Russell King, Daniel Mack, Robert Jarzmik, Linus Walleij,
	Alexandre Courbot, Wolfram Sang, Dmitry Torokhov, Bryan Wu,
	Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown, Jingoo Han,
	Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Liam Girdwood,
	Andrea Adami, linux-arm-kernel, linux-gpio, linux-i2c,
	linux-input, linux-leds

On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>
>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>
>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>>
>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>
>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>> ---
>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>     drivers/leds/leds-locomo.c | 119
>>>>> +++++++++++++++++++++++----------------------
>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>
>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>> index 966b960..4b4650b 100644
>>>>> --- a/drivers/leds/Kconfig
>>>>> +++ b/drivers/leds/Kconfig
>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>     config LEDS_LOCOMO
>>>>>           tristate "LED Support for Locomo device"
>>>>>           depends on LEDS_CLASS
>>>>> -       depends on SHARP_LOCOMO
>>>>
>>>>
>>>>
>>>> Why do you remove this dependency?
>>>
>>>
>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>> device and regmap interfaces, so there is no direct dependency on main
>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>
>>
>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>
> No. Maybe I should add "select REGMAP" instead.

REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
REGMAP_MMIO selected would also allow to notice at first glance which
regmap backend is used. This would in turn provide a straightforward
explanation on why brightness_set op is not delegated to work queue.

>>>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>>> -                               enum led_brightness value, int offset)
>>>>> +                               enum led_brightness value)
>>>>>     {
>>>>> -       struct locomo_dev *locomo_dev >>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>>> -       unsigned long flags;
>>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>>> locomo_led,
>>>>> led);
>>>>>
>>>>> -       local_irq_save(flags);
>>>>> -       if (value)
>>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       else
>>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       local_irq_restore(flags);
>>>>> +       regmap_write(led->regmap, led->reg,
>>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>>     }
>>>>
>>>>
>>>>
>>>> Please use work queue for setting brightness. This is required for the
>>>> driver to be compatible with led triggers. You can refer to the
>>>> existing LED drivers on how to implement this.
>>>
>>>
>>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>>> and doesn't need to be wrapped into work queue, does it?
>>
>>
>> Triggers can call brightness_set op in the interrupt context, so it
>> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
>> I am inferring that it can sleep.
>>
>> I am not sure if regmap implements its 'lock' op when using MMIO.
>>
>> The best way to figure this out is turning "LED Timer Trigger" on
>> in the config and execute:
>>
>> echo "timer" > trigger
>
> It works without any "might sleep/sleeping in atomic context" warnings.
>
> Technically I'd agree with you. If I'm using regmaps, ideally I should not
> depend on the exact backend and put working with it to the work queue.
> However as this is a driver for quite old IP block, it is not used with
> regmap backends other than MMIO, I'd deduce, it's ok to do things
> in a more relaxed way and to call regmap_write even from atomic
> contexts.

Ack.

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 14:53                 ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-13 14:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>
>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>
>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>>
>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>
>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>> ---
>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>     drivers/leds/leds-locomo.c | 119
>>>>> +++++++++++++++++++++++----------------------
>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>
>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>> index 966b960..4b4650b 100644
>>>>> --- a/drivers/leds/Kconfig
>>>>> +++ b/drivers/leds/Kconfig
>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>     config LEDS_LOCOMO
>>>>>           tristate "LED Support for Locomo device"
>>>>>           depends on LEDS_CLASS
>>>>> -       depends on SHARP_LOCOMO
>>>>
>>>>
>>>>
>>>> Why do you remove this dependency?
>>>
>>>
>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>> device and regmap interfaces, so there is no direct dependency on main
>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>
>>
>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>
> No. Maybe I should add "select REGMAP" instead.

REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
REGMAP_MMIO selected would also allow to notice at first glance which
regmap backend is used. This would in turn provide a straightforward
explanation on why brightness_set op is not delegated to work queue.

>>>>>    static void locomoled_brightness_set(struct led_classdev *led_cdev,
>>>>> -                               enum led_brightness value, int offset)
>>>>> +                               enum led_brightness value)
>>>>>     {
>>>>> -       struct locomo_dev *locomo_dev =
>>>>> LOCOMO_DEV(led_cdev->dev->parent);
>>>>> -       unsigned long flags;
>>>>> +       struct locomo_led *led = container_of(led_cdev, struct
>>>>> locomo_led,
>>>>> led);
>>>>>
>>>>> -       local_irq_save(flags);
>>>>> -       if (value)
>>>>> -               locomo_writel(LOCOMO_LPT_TOFH, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       else
>>>>> -               locomo_writel(LOCOMO_LPT_TOFL, locomo_dev->mapbase +
>>>>> offset);
>>>>> -       local_irq_restore(flags);
>>>>> +       regmap_write(led->regmap, led->reg,
>>>>> +                       value ? LOCOMO_LPT_TOFH : LOCOMO_LPT_TOFL);
>>>>>     }
>>>>
>>>>
>>>>
>>>> Please use work queue for setting brightness. This is required for the
>>>> driver to be compatible with led triggers. You can refer to the
>>>> existing LED drivers on how to implement this.
>>>
>>>
>>> Hmm. Why? The regmap here uses MMIO access, so it is atomic operation
>>> and doesn't need to be wrapped into work queue, does it?
>>
>>
>> Triggers can call brightness_set op in the interrupt context, so it
>> cannot sleep. I see "map->lock(map->lock_arg)" in regmap_write, thus
>> I am inferring that it can sleep.
>>
>> I am not sure if regmap implements its 'lock' op when using MMIO.
>>
>> The best way to figure this out is turning "LED Timer Trigger" on
>> in the config and execute:
>>
>> echo "timer" > trigger
>
> It works without any "might sleep/sleeping in atomic context" warnings.
>
> Technically I'd agree with you. If I'm using regmaps, ideally I should not
> depend on the exact backend and put working with it to the work queue.
> However as this is a driver for quite old IP block, it is not used with
> regmap backends other than MMIO, I'd deduce, it's ok to do things
> in a more relaxed way and to call regmap_write even from atomic
> contexts.

Ack.

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
       [not found]                 ` <5553654F.4010608-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
  2015-05-13 16:42                     ` Dmitry Torokhov
  (?)
@ 2015-05-13 16:42                     ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-13 16:42 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> >2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> >>On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> >>>
> >>>2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> >>>>
> >>>>On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> >>>>>
> >>>>>
> >>>>>Adapt locomo leds driver to new locomo core setup.
> >>>>>
> >>>>>Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> >>>>>---
> >>>>>    drivers/leds/Kconfig       |   1 -
> >>>>>    drivers/leds/leds-locomo.c | 119
> >>>>>+++++++++++++++++++++++----------------------
> >>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
> >>>>>
> >>>>>diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> >>>>>index 966b960..4b4650b 100644
> >>>>>--- a/drivers/leds/Kconfig
> >>>>>+++ b/drivers/leds/Kconfig
> >>>>>@@ -79,7 +79,6 @@ config LEDS_LM3642
> >>>>>    config LEDS_LOCOMO
> >>>>>          tristate "LED Support for Locomo device"
> >>>>>          depends on LEDS_CLASS
> >>>>>-       depends on SHARP_LOCOMO
> >>>>
> >>>>
> >>>>
> >>>>Why do you remove this dependency?
> >>>
> >>>
> >>>Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> >>>uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> >>>device and regmap interfaces, so there is no direct dependency on main
> >>>LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
> >>
> >>
> >>Ack. Shouldn't you also need "select REGMAP_MMIO" ?
> >
> >No. Maybe I should add "select REGMAP" instead.
> 
> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having

That is unfortunately not how select works: it does not automatically
select parents for the selected symbol.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 16:42                     ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-13 16:42 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> >2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> >>On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> >>>
> >>>2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>:
> >>>>
> >>>>On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> >>>>>
> >>>>>
> >>>>>Adapt locomo leds driver to new locomo core setup.
> >>>>>
> >>>>>Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> >>>>>---
> >>>>>    drivers/leds/Kconfig       |   1 -
> >>>>>    drivers/leds/leds-locomo.c | 119
> >>>>>+++++++++++++++++++++++----------------------
> >>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
> >>>>>
> >>>>>diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> >>>>>index 966b960..4b4650b 100644
> >>>>>--- a/drivers/leds/Kconfig
> >>>>>+++ b/drivers/leds/Kconfig
> >>>>>@@ -79,7 +79,6 @@ config LEDS_LM3642
> >>>>>    config LEDS_LOCOMO
> >>>>>          tristate "LED Support for Locomo device"
> >>>>>          depends on LEDS_CLASS
> >>>>>-       depends on SHARP_LOCOMO
> >>>>
> >>>>
> >>>>
> >>>>Why do you remove this dependency?
> >>>
> >>>
> >>>Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> >>>uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> >>>device and regmap interfaces, so there is no direct dependency on main
> >>>LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
> >>
> >>
> >>Ack. Shouldn't you also need "select REGMAP_MMIO" ?
> >
> >No. Maybe I should add "select REGMAP" instead.
> 
> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having

That is unfortunately not how select works: it does not automatically
select parents for the selected symbol.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 16:42                     ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-13 16:42 UTC (permalink / raw)
  To: Jacek Anaszewski
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA, linux-input, linux-leds

On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> >2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> >>On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> >>>
> >>>2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> >>>>
> >>>>On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> >>>>>
> >>>>>
> >>>>>Adapt locomo leds driver to new locomo core setup.
> >>>>>
> >>>>>Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >>>>>---
> >>>>>    drivers/leds/Kconfig       |   1 -
> >>>>>    drivers/leds/leds-locomo.c | 119
> >>>>>+++++++++++++++++++++++----------------------
> >>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
> >>>>>
> >>>>>diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> >>>>>index 966b960..4b4650b 100644
> >>>>>--- a/drivers/leds/Kconfig
> >>>>>+++ b/drivers/leds/Kconfig
> >>>>>@@ -79,7 +79,6 @@ config LEDS_LM3642
> >>>>>    config LEDS_LOCOMO
> >>>>>          tristate "LED Support for Locomo device"
> >>>>>          depends on LEDS_CLASS
> >>>>>-       depends on SHARP_LOCOMO
> >>>>
> >>>>
> >>>>
> >>>>Why do you remove this dependency?
> >>>
> >>>
> >>>Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> >>>uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> >>>device and regmap interfaces, so there is no direct dependency on main
> >>>LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
> >>
> >>
> >>Ack. Shouldn't you also need "select REGMAP_MMIO" ?
> >
> >No. Maybe I should add "select REGMAP" instead.
> 
> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having

That is unfortunately not how select works: it does not automatically
select parents for the selected symbol.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-13 16:42                     ` Dmitry Torokhov
  0 siblings, 0 replies; 148+ messages in thread
From: Dmitry Torokhov @ 2015-05-13 16:42 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
> >2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> >>On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
> >>>
> >>>2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
> >>>>
> >>>>On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
> >>>>>
> >>>>>
> >>>>>Adapt locomo leds driver to new locomo core setup.
> >>>>>
> >>>>>Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >>>>>---
> >>>>>    drivers/leds/Kconfig       |   1 -
> >>>>>    drivers/leds/leds-locomo.c | 119
> >>>>>+++++++++++++++++++++++----------------------
> >>>>>    2 files changed, 61 insertions(+), 59 deletions(-)
> >>>>>
> >>>>>diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
> >>>>>index 966b960..4b4650b 100644
> >>>>>--- a/drivers/leds/Kconfig
> >>>>>+++ b/drivers/leds/Kconfig
> >>>>>@@ -79,7 +79,6 @@ config LEDS_LM3642
> >>>>>    config LEDS_LOCOMO
> >>>>>          tristate "LED Support for Locomo device"
> >>>>>          depends on LEDS_CLASS
> >>>>>-       depends on SHARP_LOCOMO
> >>>>
> >>>>
> >>>>
> >>>>Why do you remove this dependency?
> >>>
> >>>
> >>>Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
> >>>uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
> >>>device and regmap interfaces, so there is no direct dependency on main
> >>>LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
> >>
> >>
> >>Ack. Shouldn't you also need "select REGMAP_MMIO" ?
> >
> >No. Maybe I should add "select REGMAP" instead.
> 
> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having

That is unfortunately not how select works: it does not automatically
select parents for the selected symbol.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
  2015-05-13 16:42                     ` Dmitry Torokhov
  (?)
  (?)
@ 2015-05-14  6:35                       ` Jacek Anaszewski
  -1 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-14  6:35 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel, linux-gpio,
	linux-i2c, linux-input, linux-leds

On 05/13/2015 06:42 PM, Dmitry Torokhov wrote:
> On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
>> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
>>> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>>>
>>>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>>>
>>>>>>>
>>>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>>>> ---
>>>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>>>     drivers/leds/leds-locomo.c | 119
>>>>>>> +++++++++++++++++++++++----------------------
>>>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>>>> index 966b960..4b4650b 100644
>>>>>>> --- a/drivers/leds/Kconfig
>>>>>>> +++ b/drivers/leds/Kconfig
>>>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>>>     config LEDS_LOCOMO
>>>>>>>           tristate "LED Support for Locomo device"
>>>>>>>           depends on LEDS_CLASS
>>>>>>> -       depends on SHARP_LOCOMO
>>>>>>
>>>>>>
>>>>>>
>>>>>> Why do you remove this dependency?
>>>>>
>>>>>
>>>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>>>> device and regmap interfaces, so there is no direct dependency on main
>>>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>>>
>>>>
>>>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>>>
>>> No. Maybe I should add "select REGMAP" instead.
>>
>> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
>
> That is unfortunately not how select works: it does not automatically
> select parents for the selected symbol.

Please look at config REGMAP declaration in the file
drivers/base/regmap/Kconfig:

config REGMAP
         default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || 
REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
         select LZO_COMPRESS
         select LZO_DECOMPRESS
         select IRQ_DOMAIN if REGMAP_IRQ
         bool

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-14  6:35                       ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-14  6:35 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel, linux-gpio,
	linux-i2c, linux-input, linux-leds

On 05/13/2015 06:42 PM, Dmitry Torokhov wrote:
> On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
>> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
>>> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>>>
>>>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>>>
>>>>>>>
>>>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>>>> ---
>>>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>>>     drivers/leds/leds-locomo.c | 119
>>>>>>> +++++++++++++++++++++++----------------------
>>>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>>>> index 966b960..4b4650b 100644
>>>>>>> --- a/drivers/leds/Kconfig
>>>>>>> +++ b/drivers/leds/Kconfig
>>>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>>>     config LEDS_LOCOMO
>>>>>>>           tristate "LED Support for Locomo device"
>>>>>>>           depends on LEDS_CLASS
>>>>>>> -       depends on SHARP_LOCOMO
>>>>>>
>>>>>>
>>>>>>
>>>>>> Why do you remove this dependency?
>>>>>
>>>>>
>>>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>>>> device and regmap interfaces, so there is no direct dependency on main
>>>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>>>
>>>>
>>>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>>>
>>> No. Maybe I should add "select REGMAP" instead.
>>
>> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
>
> That is unfortunately not how select works: it does not automatically
> select parents for the selected symbol.

Please look at config REGMAP declaration in the file
drivers/base/regmap/Kconfig:

config REGMAP
         default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || 
REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
         select LZO_COMPRESS
         select LZO_DECOMPRESS
         select IRQ_DOMAIN if REGMAP_IRQ
         bool

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-14  6:35                       ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-14  6:35 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Dmitry Eremin-Solenikov, Russell King, Daniel Mack,
	Robert Jarzmik, Linus Walleij, Alexandre Courbot, Wolfram Sang,
	Bryan Wu, Richard Purdie, Samuel Ortiz, Lee Jones, Mark Brown,
	Jingoo Han, Jean-Christophe Plagniol-Villard, Tomi Valkeinen,
	Liam Girdwood, Andrea Adami, linux-arm-kernel, linux-gpio,
	linux-i2c, linux-input, linux-leds

On 05/13/2015 06:42 PM, Dmitry Torokhov wrote:
> On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
>> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
>>> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>>>
>>>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>>>
>>>>>>>
>>>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>>>> ---
>>>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>>>     drivers/leds/leds-locomo.c | 119
>>>>>>> +++++++++++++++++++++++----------------------
>>>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>>>> index 966b960..4b4650b 100644
>>>>>>> --- a/drivers/leds/Kconfig
>>>>>>> +++ b/drivers/leds/Kconfig
>>>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>>>     config LEDS_LOCOMO
>>>>>>>           tristate "LED Support for Locomo device"
>>>>>>>           depends on LEDS_CLASS
>>>>>>> -       depends on SHARP_LOCOMO
>>>>>>
>>>>>>
>>>>>>
>>>>>> Why do you remove this dependency?
>>>>>
>>>>>
>>>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>>>> device and regmap interfaces, so there is no direct dependency on main
>>>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>>>
>>>>
>>>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>>>
>>> No. Maybe I should add "select REGMAP" instead.
>>
>> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
>
> That is unfortunately not how select works: it does not automatically
> select parents for the selected symbol.

Please look at config REGMAP declaration in the file
drivers/base/regmap/Kconfig:

config REGMAP
         default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || 
REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
         select LZO_COMPRESS
         select LZO_DECOMPRESS
         select IRQ_DOMAIN if REGMAP_IRQ
         bool

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [PATCH v2 02/17] leds: port locomo leds driver to new locomo core
@ 2015-05-14  6:35                       ` Jacek Anaszewski
  0 siblings, 0 replies; 148+ messages in thread
From: Jacek Anaszewski @ 2015-05-14  6:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 05/13/2015 06:42 PM, Dmitry Torokhov wrote:
> On Wed, May 13, 2015 at 04:53:03PM +0200, Jacek Anaszewski wrote:
>> On 05/13/2015 04:14 PM, Dmitry Eremin-Solenikov wrote:
>>> 2015-05-13 13:31 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>> On 05/12/2015 05:35 PM, Dmitry Eremin-Solenikov wrote:
>>>>>
>>>>> 2015-05-06 18:05 GMT+03:00 Jacek Anaszewski <j.anaszewski@samsung.com>:
>>>>>>
>>>>>> On 04/28/2015 01:55 AM, Dmitry Eremin-Solenikov wrote:
>>>>>>>
>>>>>>>
>>>>>>> Adapt locomo leds driver to new locomo core setup.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>>>> ---
>>>>>>>     drivers/leds/Kconfig       |   1 -
>>>>>>>     drivers/leds/leds-locomo.c | 119
>>>>>>> +++++++++++++++++++++++----------------------
>>>>>>>     2 files changed, 61 insertions(+), 59 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
>>>>>>> index 966b960..4b4650b 100644
>>>>>>> --- a/drivers/leds/Kconfig
>>>>>>> +++ b/drivers/leds/Kconfig
>>>>>>> @@ -79,7 +79,6 @@ config LEDS_LM3642
>>>>>>>     config LEDS_LOCOMO
>>>>>>>           tristate "LED Support for Locomo device"
>>>>>>>           depends on LEDS_CLASS
>>>>>>> -       depends on SHARP_LOCOMO
>>>>>>
>>>>>>
>>>>>>
>>>>>> Why do you remove this dependency?
>>>>>
>>>>>
>>>>> Because SHARP_LOCOMO is a Kconfig symbol for the old driver. New driver
>>>>> uses MFD_LOCOMO Kconfig entry. Also the driver now uses generic platform
>>>>> device and regmap interfaces, so there is no direct dependency on main
>>>>> LoCoMo driver. And the policy (IIRC) was not to have such dependencies.
>>>>
>>>>
>>>> Ack. Shouldn't you also need "select REGMAP_MMIO" ?
>>>
>>> No. Maybe I should add "select REGMAP" instead.
>>
>> REGMAP is enabled by default if REGMAP_MMIO is enabled. Having
>
> That is unfortunately not how select works: it does not automatically
> select parents for the selected symbol.

Please look at config REGMAP declaration in the file
drivers/base/regmap/Kconfig:

config REGMAP
         default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || 
REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ)
         select LZO_COMPRESS
         select LZO_DECOMPRESS
         select IRQ_DOMAIN if REGMAP_IRQ
         bool

-- 
Best Regards,
Jacek Anaszewski

^ permalink raw reply	[flat|nested] 148+ messages in thread

end of thread, other threads:[~2015-05-14  6:35 UTC | newest]

Thread overview: 148+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-27 23:55 [PATCH v2 00/17] new locomo driver set Dmitry Eremin-Solenikov
2015-04-27 23:55 ` Dmitry Eremin-Solenikov
2015-04-27 23:55 ` Dmitry Eremin-Solenikov
2015-04-27 23:55 ` [PATCH v2 01/17] mfd: add new driver for Sharp LoCoMo Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
     [not found]   ` <1430178954-11138-2-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-04-28 18:45     ` Lee Jones
2015-04-28 18:45       ` Lee Jones
2015-05-12 20:39       ` Dmitry Eremin-Solenikov
2015-05-12 20:39         ` Dmitry Eremin-Solenikov
2015-05-12 20:39         ` Dmitry Eremin-Solenikov
2015-05-12 20:39         ` Dmitry Eremin-Solenikov
2015-05-13  9:41         ` Lee Jones
2015-05-13  9:41           ` Lee Jones
2015-05-13  9:41           ` Lee Jones
2015-05-13  9:41           ` Lee Jones
2015-04-27 23:55 ` [PATCH v2 02/17] leds: port locomo leds driver to new locomo core Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-05-06 15:05   ` Jacek Anaszewski
2015-05-06 15:05     ` Jacek Anaszewski
2015-05-06 15:05     ` Jacek Anaszewski
2015-05-12 15:35     ` Dmitry Eremin-Solenikov
2015-05-12 15:35       ` Dmitry Eremin-Solenikov
2015-05-12 15:35       ` Dmitry Eremin-Solenikov
2015-05-12 15:35       ` Dmitry Eremin-Solenikov
     [not found]       ` <CALT56yNJWapNw1XLrzfbUDUz1LF_BB9DfF94H6GhbnBUEP80_w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-05-13 10:31         ` Jacek Anaszewski
2015-05-13 10:31           ` Jacek Anaszewski
2015-05-13 10:31           ` Jacek Anaszewski
2015-05-13 10:31           ` Jacek Anaszewski
     [not found]           ` <555327EA.5060402-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-13 14:14             ` Dmitry Eremin-Solenikov
2015-05-13 14:14               ` Dmitry Eremin-Solenikov
2015-05-13 14:14               ` Dmitry Eremin-Solenikov
2015-05-13 14:14               ` Dmitry Eremin-Solenikov
2015-05-13 14:53               ` Jacek Anaszewski
2015-05-13 14:53                 ` Jacek Anaszewski
2015-05-13 14:53                 ` Jacek Anaszewski
2015-05-13 14:53                 ` Jacek Anaszewski
     [not found]                 ` <5553654F.4010608-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2015-05-13 16:42                   ` Dmitry Torokhov
2015-05-13 16:42                     ` Dmitry Torokhov
2015-05-13 16:42                     ` Dmitry Torokhov
2015-05-13 16:42                     ` Dmitry Torokhov
2015-05-14  6:35                     ` Jacek Anaszewski
2015-05-14  6:35                       ` Jacek Anaszewski
2015-05-14  6:35                       ` Jacek Anaszewski
2015-05-14  6:35                       ` Jacek Anaszewski
2015-04-27 23:55 ` [PATCH v2 05/17] video: backlight: add new locomo backlight driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
     [not found] ` <1430178954-11138-1-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-04-27 23:55   ` [PATCH v2 03/17] input: convert LoCoMo keyboard driver to use new locomo core Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-05-12 20:21     ` Dmitry Torokhov
2015-05-12 20:21       ` Dmitry Torokhov
2015-05-12 20:21       ` Dmitry Torokhov
2015-05-12 21:01       ` Dmitry Eremin-Solenikov
2015-05-12 21:01         ` Dmitry Eremin-Solenikov
2015-05-12 21:01         ` Dmitry Eremin-Solenikov
2015-05-12 21:01         ` Dmitry Eremin-Solenikov
2015-05-12 21:13         ` Dmitry Torokhov
2015-05-12 21:13           ` Dmitry Torokhov
2015-05-12 21:13           ` Dmitry Torokhov
2015-05-12 21:13           ` Dmitry Torokhov
2015-04-27 23:55   ` [PATCH v2 04/17] input: locomokbd: provide an Alt-SysRQ combination Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-05-12 20:12     ` Dmitry Torokhov
2015-05-12 20:12       ` Dmitry Torokhov
2015-05-12 20:12       ` Dmitry Torokhov
2015-05-12 20:40       ` Dmitry Eremin-Solenikov
2015-05-12 20:40         ` Dmitry Eremin-Solenikov
2015-05-12 20:40         ` Dmitry Eremin-Solenikov
2015-05-12 20:40         ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` [PATCH v2 06/17] video: lcd: add LoCoMo LCD driver Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` [PATCH v2 10/17] i2c: add locomo i2c driver Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-04-27 23:55     ` Dmitry Eremin-Solenikov
2015-05-12 19:24     ` Wolfram Sang
2015-05-12 19:24       ` Wolfram Sang
2015-05-12 19:24       ` Wolfram Sang
2015-05-12 19:27       ` Dmitry Eremin-Solenikov
2015-05-12 19:27         ` Dmitry Eremin-Solenikov
2015-05-12 19:27         ` Dmitry Eremin-Solenikov
2015-05-12 19:27         ` Dmitry Eremin-Solenikov
2015-05-12 19:28         ` Wolfram Sang
2015-05-12 19:28           ` Wolfram Sang
2015-05-12 19:28           ` Wolfram Sang
2015-05-12 19:28           ` Wolfram Sang
2015-04-27 23:55 ` [PATCH v2 07/17] gpio: port LoCoMo gpio support from old driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-05-06 14:12   ` Linus Walleij
2015-05-06 14:12     ` Linus Walleij
2015-05-06 14:12     ` Linus Walleij
2015-04-27 23:55 ` [PATCH v2 08/17] gpio: locomo: implement per-pin irq handling Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-05-06 14:15   ` Linus Walleij
2015-05-06 14:15     ` Linus Walleij
2015-05-06 14:15     ` Linus Walleij
2015-05-06 16:42     ` Dmitry Eremin-Solenikov
2015-05-06 16:42       ` Dmitry Eremin-Solenikov
2015-05-06 16:42       ` Dmitry Eremin-Solenikov
2015-05-12 11:15       ` Linus Walleij
2015-05-12 11:15         ` Linus Walleij
2015-05-12 11:15         ` Linus Walleij
2015-04-27 23:55 ` [PATCH v2 09/17] spi: add locomo SPI driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-29 11:27   ` Mark Brown
2015-04-29 11:27     ` Mark Brown
2015-04-29 11:27     ` Mark Brown
2015-04-27 23:55 ` [PATCH v2 11/17] ARM: sa1100: make collie use new locomo drivers Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55 ` [PATCH v2 12/17] ARM: sa1100: don't preallocate IRQ space for locomo Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55 ` [PATCH v2 13/17] ASoC: pxa: poodle: make use of new locomo GPIO interface Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-05-06 14:19   ` Linus Walleij
2015-05-06 14:19     ` Linus Walleij
2015-05-06 14:19     ` Linus Walleij
2015-04-27 23:55 ` [PATCH v2 14/17] ARM: pxa: poodle: use new LoCoMo driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
     [not found]   ` <1430178954-11138-15-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-04-28 19:35     ` Robert Jarzmik
2015-04-28 19:35       ` Robert Jarzmik
2015-04-28 19:35       ` Robert Jarzmik
2015-05-06 14:20     ` Linus Walleij
2015-05-06 14:20       ` Linus Walleij
2015-05-06 14:20       ` Linus Walleij
2015-04-27 23:55 ` [PATCH v2 15/17] ARM: pxa: poodle: don't preallocate IRQ space for locomo Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-28 19:36   ` Robert Jarzmik
2015-04-28 19:36     ` Robert Jarzmik
2015-04-28 19:36     ` Robert Jarzmik
2015-04-27 23:55 ` [PATCH v2 16/17] video: backlight: drop old locomo bl/lcd driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
2015-04-27 23:55 ` [PATCH v2 17/17] ARM: drop old LoCoMo driver Dmitry Eremin-Solenikov
2015-04-27 23:55   ` Dmitry Eremin-Solenikov
     [not found]   ` <1430178954-11138-18-git-send-email-dbaryshkov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-05-06 14:22     ` Linus Walleij
2015-05-06 14:22       ` Linus Walleij
2015-05-06 14:22       ` Linus Walleij

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.