openwrtv4/target/linux/ar71xx/patches-4.9/451-gpio-74x164-improve-platform-device-support.patch
Hauke Mehrtens 7bbf4117c6 ar71xx: Add kernel 4.9 support
This add support for kernel 4.9 to the ar71xx target.
It was compile tested with the generic, NAND and mikrotik subtarget.
Multiple members of the community tested it on their boards and did not
report any major problem so far.

Especially the NAND part received some changes to adapt to the new
kernel APIs. The serial driver hack used for the Arduino Yun was not
ported because the kernel changed there a lot.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2017-10-11 22:32:39 +02:00

117 lines
3.2 KiB
Diff

--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/spi/spi.h>
+#include <linux/spi/74x164.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
@@ -103,9 +104,16 @@ static int gen_74x164_direction_output(s
static int gen_74x164_probe(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
+ struct gen_74x164_chip_platform_data *pdata = spi->dev.platform_data;
+ struct device_node *np = spi->dev.of_node;
u32 nregs;
int ret;
+ if (!np && !pdata) {
+ dev_err(&spi->dev, "No configuration data available.\n");
+ return -EINVAL;
+ }
+
/*
* bits_per_word cannot be configured in platform data
*/
@@ -115,17 +123,23 @@ static int gen_74x164_probe(struct spi_d
if (ret < 0)
return ret;
- if (of_property_read_u32(spi->dev.of_node, "registers-number",
- &nregs)) {
- dev_err(&spi->dev,
- "Missing registers-number property in the DT.\n");
- return -EINVAL;
- }
+ if (np) {
+ if (of_property_read_u32(np, "registers-number", &nregs)) {
+ dev_err(&spi->dev,
+ "Missing registers-number property in the DT.\n");
+ return -EINVAL;
+ }
+ } else if (pdata) {
+ nregs = pdata->num_registers;
+ }
chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL);
if (!chip)
return -ENOMEM;
+ if (pdata && pdata->init_data)
+ memcpy(chip->buffer, pdata->init_data, chip->registers);
+
spi_set_drvdata(spi, chip);
chip->gpio_chip.label = spi->modalias;
@@ -133,7 +147,11 @@ static int gen_74x164_probe(struct spi_d
chip->gpio_chip.get = gen_74x164_get_value;
chip->gpio_chip.set = gen_74x164_set_value;
chip->gpio_chip.set_multiple = gen_74x164_set_multiple;
- chip->gpio_chip.base = -1;
+ if (np)
+ chip->gpio_chip.base = -1;
+ else if (pdata)
+ chip->gpio_chip.base = pdata->base;
+
chip->registers = nregs;
chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
@@ -170,17 +188,19 @@ static int gen_74x164_remove(struct spi_
return 0;
}
+#ifdef CONFIG_OF
static const struct of_device_id gen_74x164_dt_ids[] = {
{ .compatible = "fairchild,74hc595" },
{ .compatible = "nxp,74lvc594" },
{},
};
MODULE_DEVICE_TABLE(of, gen_74x164_dt_ids);
+#endif
static struct spi_driver gen_74x164_driver = {
.driver = {
.name = "74x164",
- .of_match_table = gen_74x164_dt_ids,
+ .of_match_table = of_match_ptr(gen_74x164_dt_ids),
},
.probe = gen_74x164_probe,
.remove = gen_74x164_remove,
--- /dev/null
+++ b/include/linux/spi/74x164.h
@@ -0,0 +1,13 @@
+#ifndef LINUX_SPI_74X164_H
+#define LINUX_SPI_74X164_H
+
+struct gen_74x164_chip_platform_data {
+ /* number assigned to the first GPIO */
+ unsigned base;
+ /* number of chained registers */
+ unsigned num_registers;
+ /* address of a buffer containing initial data */
+ u8 *init_data;
+};
+
+#endif
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1154,7 +1154,6 @@ menu "SPI GPIO expanders"
config GPIO_74X164
tristate "74x164 serial-in/parallel-out 8-bits shift register"
- depends on OF_GPIO
help
Driver for 74x164 compatible serial-in/parallel-out 8-outputs
shift registers. This driver can be used to provide access