diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2017-01-11 19:00:03 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2017-01-11 19:00:03 +0100 |
commit | e05529dd8b582c4421938066a5ff5006452ced78 (patch) | |
tree | b4e925b08f2f672c6331db06c4b1986e58f89a75 /drivers | |
parent | 0c3f4d1da2277ac0cb88dc32ac0de48bc241e01f (diff) | |
parent | 9563a024d28c0f35db8fc459931f4909bbffe5eb (diff) | |
download | barebox-e05529dd8b582c4421938066a5ff5006452ced78.tar.gz barebox-e05529dd8b582c4421938066a5ff5006452ced78.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ahci.c | 7 | ||||
-rw-r--r-- | drivers/ata/pata-imx.c | 8 | ||||
-rw-r--r-- | drivers/base/regmap/regmap.c | 27 | ||||
-rw-r--r-- | drivers/gpio/Kconfig | 8 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-74164.c | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-sx150x.c | 274 | ||||
-rw-r--r-- | drivers/i2c/muxes/i2c-mux-pca954x.c | 7 | ||||
-rw-r--r-- | drivers/input/input.c | 4 | ||||
-rw-r--r-- | drivers/mci/omap_hsmmc.c | 2 | ||||
-rw-r--r-- | drivers/mfd/da9053.c | 13 | ||||
-rw-r--r-- | drivers/mtd/devices/m25p80.c | 2 | ||||
-rw-r--r-- | drivers/mtd/peb.c | 7 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 1 | ||||
-rw-r--r-- | drivers/mtd/ubi/io.c | 2 | ||||
-rw-r--r-- | drivers/of/platform.c | 2 |
16 files changed, 344 insertions, 22 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c31b337ba2..b416105970 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -207,7 +207,6 @@ static int ahci_read_id(struct ata_port *ata, void *buf) { struct ahci_port *ahci = container_of(ata, struct ahci_port, ata); u8 fis[20]; - int ret; memset(fis, 0, sizeof(fis)); @@ -216,11 +215,7 @@ static int ahci_read_id(struct ata_port *ata, void *buf) fis[1] = 1 << 7; /* Command FIS. */ fis[2] = ATA_CMD_ID_ATA; /* Command byte. */ - ret = ahci_io(ahci, fis, sizeof(fis), buf, NULL, SECTOR_SIZE); - if (ret) - return ret; - - return ret; + return ahci_io(ahci, fis, sizeof(fis), buf, NULL, SECTOR_SIZE); } static int ahci_rw(struct ata_port *ata, void *rbuf, const void *wbuf, diff --git a/drivers/ata/pata-imx.c b/drivers/ata/pata-imx.c index c8098a537f..4f75048c12 100644 --- a/drivers/ata/pata-imx.c +++ b/drivers/ata/pata-imx.c @@ -158,7 +158,6 @@ static int imx_pata_probe(struct device_d *dev) struct clk *clk; void __iomem *base; int ret; - const char *devname = NULL; ide = xzalloc(sizeof(*ide)); iores = dev_request_mem_resource(dev, 0); @@ -182,14 +181,9 @@ static int imx_pata_probe(struct device_d *dev) pata_imx_set_bus_timing(base, clk_get_rate(clk), 4); - if (IS_ENABLED(CONFIG_OFDEVICE)) { - devname = of_alias_get(dev->device_node); - if (devname) - devname = xstrdup(devname); - } ide->port.dev = dev; - ide->port.devname = devname; + ide->port.devname = xstrdup(of_alias_get(dev->device_node)); dev->priv = ide; dev->detect = pata_imx_detect; diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index a042a1a24e..52b7d88c74 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -137,6 +137,33 @@ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) } /** + * regmap_write_bits - write bits of a register in a map + * + * @map: The map + * @reg: The register offset of the register + * @mask: Mask indicating bits to be modified + * (1 - modified, 0 - untouched) + * @val: Bit value to be set + * + * Returns 0 for success or negative error code on failure + */ +int regmap_write_bits(struct regmap *map, unsigned int reg, + unsigned int mask, unsigned int val) +{ + int ret; + unsigned int tmp, orig; + + ret = regmap_read(map, reg, &orig); + if (ret != 0) + return ret; + + tmp = orig & ~mask; + tmp |= val & mask; + + return regmap_write(map, reg, tmp); +} + +/** * regmap_bulk_read(): Read data from the device * * @map: Register map to read from diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index ab919c95f5..078deee4e5 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -121,6 +121,14 @@ config GPIO_DESIGNWARE help Say Y or M here to build support for the Synopsys DesignWare APB GPIO block. + +config GPIO_SX150X + bool "Semtec SX150x I/O ports" + depends on I2C + help + Say Y here to build support for the Semtec Sx150x I2C GPIO + expander chip. + endmenu endif diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 8767eed1e8..2d5142d41c 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o obj-$(CONFIG_GPIO_DESIGNWARE) += gpio-dw.o +obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o diff --git a/drivers/gpio/gpio-74164.c b/drivers/gpio/gpio-74164.c index 926207aaf7..e4d413b689 100644 --- a/drivers/gpio/gpio-74164.c +++ b/drivers/gpio/gpio-74164.c @@ -92,6 +92,7 @@ static struct gpio_ops gpio_74164_ops = { static struct platform_device_id gpio_74164_ids[] = { { "74hc164" }, + { "74lvc594" }, { "74hc595" }, { } }; diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c new file mode 100644 index 0000000000..7b8cfb5042 --- /dev/null +++ b/drivers/gpio/gpio-sx150x.c @@ -0,0 +1,274 @@ +/* + * Driver for SX150x I2C GPIO expanders + * + * This code was ported from linux-4.9 kernel driver by + * Andrey Smirnov <andrew.smirnov@gmail.com>. + * + * Orginal code with it's copyright info can be found in + * drivers/pinctrl/pinctrl-sx150x.c + * + * Note: That although linux driver was converted from being a GPIO + * subsystem to Pinctrl subsytem driver, due to Barebox's lack of + * similar provisions this driver is still a GPIO driver. + * + * 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. + */ + +#include <common.h> +#include <init.h> +#include <malloc.h> +#include <driver.h> +#include <xfuncs.h> +#include <errno.h> +#include <i2c/i2c.h> +#include <regmap.h> + +#include <gpio.h> +#include <of_device.h> + +enum { + SX150X_123 = 0, + SX150X_456, + SX150X_789, +}; + +enum { + SX150X_MAX_REGISTER = 0xad, +}; + +struct sx150x_device_data { + u8 model; + u8 reg_dir; + u8 reg_data; + u8 ngpios; +}; + +struct sx150x_gpio { + struct device *dev; + struct i2c_client *client; + struct gpio_chip gpio; + struct regmap *regmap; + const struct sx150x_device_data *data; +}; + +static const struct sx150x_device_data sx1503q_device_data = { + .model = SX150X_123, + .reg_dir = 0x02, + .reg_data = 0x00, + .ngpios = 16, +}; + +static struct sx150x_gpio *to_sx150x_gpio(struct gpio_chip *gpio) +{ + return container_of(gpio, struct sx150x_gpio, gpio); +} + +static int sx150x_gpio_get_direction(struct gpio_chip *gpio, + unsigned int offset) +{ + struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio); + unsigned int value; + int ret; + + ret = regmap_read(sx150x->regmap, sx150x->data->reg_dir, &value); + if (ret < 0) + return ret; + + return !!(value & BIT(offset)); +} + +static int sx150x_gpio_get(struct gpio_chip *gpio, unsigned int offset) +{ + struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio); + unsigned int value; + int ret; + + ret = regmap_read(sx150x->regmap, sx150x->data->reg_data, &value); + if (ret < 0) + return ret; + + return !!(value & BIT(offset)); +} + +static int __sx150x_gpio_set(struct sx150x_gpio *sx150x, unsigned int offset, + int value) +{ + return regmap_write_bits(sx150x->regmap, sx150x->data->reg_data, + BIT(offset), value ? BIT(offset) : 0); +} + + +static void sx150x_gpio_set(struct gpio_chip *gpio, unsigned int offset, + int value) +{ + __sx150x_gpio_set(to_sx150x_gpio(gpio), offset, value); +} + +static int sx150x_gpio_direction_input(struct gpio_chip *gpio, + unsigned int offset) +{ + struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio); + + return regmap_write_bits(sx150x->regmap, + sx150x->data->reg_dir, + BIT(offset), BIT(offset)); +} + +static int sx150x_gpio_direction_output(struct gpio_chip *gpio, + unsigned int offset, int value) +{ + struct sx150x_gpio *sx150x = to_sx150x_gpio(gpio); + int ret; + + ret = __sx150x_gpio_set(sx150x, offset, value); + if (ret < 0) + return ret; + + return regmap_write_bits(sx150x->regmap, + sx150x->data->reg_dir, + BIT(offset), 0); +} + +static int sx150x_regmap_reg_width(struct sx150x_gpio *sx150x, + unsigned int reg) +{ + return sx150x->data->ngpios; +} + +/* + * In order to mask the differences between 16 and 8 bit expander + * devices we set up a sligthly ficticious regmap that pretends to be + * a set of 16-bit registers and transparently reconstructs those + * registers via multiple I2C/SMBus reads + * + * This way the rest of the driver code, interfacing with the chip via + * regmap API, can work assuming that each GPIO pin is represented by + * a group of bits at an offset proportioan to GPIO number within a + * given register. + * + */ +static int sx150x_regmap_reg_read(void *context, unsigned int reg, + unsigned int *result) +{ + int ret, n; + struct sx150x_gpio *sx150x = context; + struct i2c_client *i2c = sx150x->client; + const int width = sx150x_regmap_reg_width(sx150x, reg); + unsigned int idx, val; + + /* + * There are four potential cases coverd by this function: + * + * 1) 8-pin chip, single configuration bit register + * + * This is trivial the code below just needs to read: + * reg [ 7 6 5 4 3 2 1 0 ] + * + * 2) 16-pin chip, single configuration bit register + * + * The read will be done as follows: + * reg [ f e d c b a 9 8 ] + * reg + 1 [ 7 6 5 4 3 2 1 0 ] + * + */ + + for (n = width, val = 0, idx = reg; n > 0; n -= 8, idx++) { + val <<= 8; + + ret = i2c_smbus_read_byte_data(i2c, idx); + if (ret < 0) + return ret; + + val |= ret; + } + + *result = val; + + return 0; +} + +static int sx150x_regmap_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + int ret, n; + struct sx150x_gpio *sx150x = context; + struct i2c_client *i2c = sx150x->client; + const int width = sx150x_regmap_reg_width(sx150x, reg); + + n = width - 8; + do { + const u8 byte = (val >> n) & 0xff; + + ret = i2c_smbus_write_byte_data(i2c, reg, byte); + if (ret < 0) + return ret; + + reg++; + n -= 8; + } while (n >= 0); + + return 0; +} + +static const struct regmap_config sx150x_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = SX150X_MAX_REGISTER, +}; + +static const struct regmap_bus sx150x_regmap_bus = { + .reg_read = sx150x_regmap_reg_read, + .reg_write = sx150x_regmap_reg_write, +}; + +static struct gpio_ops sx150x_gpio_ops = { + .direction_input = sx150x_gpio_direction_input, + .direction_output = sx150x_gpio_direction_output, + .get_direction = sx150x_gpio_get_direction, + .get = sx150x_gpio_get, + .set = sx150x_gpio_set, +}; + +static int sx150x_probe(struct device_d *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct sx150x_gpio *sx150x; + const struct sx150x_device_data *data; + + data = of_device_get_match_data(dev); + if (!data) + return -EINVAL; + + sx150x = xzalloc(sizeof(*sx150x)); + + sx150x->regmap = regmap_init(dev, &sx150x_regmap_bus, + sx150x, &sx150x_regmap_config); + sx150x->client = client; + sx150x->data = data; + sx150x->gpio.ops = &sx150x_gpio_ops; + sx150x->gpio.base = -1; + sx150x->gpio.ngpio = sx150x->data->ngpios; + sx150x->gpio.dev = &client->dev; + + return gpiochip_add(&sx150x->gpio); +} + +static __maybe_unused struct of_device_id sx150x_dt_ids[] = { + { .compatible = "semtech,sx1503q", .data = &sx1503q_device_data, }, + { } +}; + +static struct driver_d sx150x_driver = { + .name = "sx150x", + .probe = sx150x_probe, + .of_compatible = sx150x_dt_ids, +}; + +static int __init sx150x_init(void) +{ + return i2c_driver_register(&sx150x_driver); +} +device_initcall(sx150x_init); diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c index baeae7bb94..0d5515b716 100644 --- a/drivers/i2c/muxes/i2c-mux-pca954x.c +++ b/drivers/i2c/muxes/i2c-mux-pca954x.c @@ -45,6 +45,8 @@ #include <i2c/i2c-algo-bit.h> #include <i2c/i2c-mux.h> #include <init.h> +#include <gpio.h> +#include <of_gpio.h> #define PCA954X_MAX_NCHANS 8 @@ -179,6 +181,7 @@ static int pca954x_probe(struct device_d *dev) int num, force; struct pca954x *data; int ret = -ENODEV; + int gpio; data = kzalloc(sizeof(struct pca954x), GFP_KERNEL); if (!data) { @@ -188,6 +191,10 @@ static int pca954x_probe(struct device_d *dev) i2c_set_clientdata(client, data); + gpio = of_get_named_gpio(dev->device_node, "reset-gpios", 0); + if (gpio_is_valid(gpio)) + gpio_direction_output(gpio, 1); + /* Read the mux register at addr to verify * that the mux is in fact present. */ diff --git a/drivers/input/input.c b/drivers/input/input.c index 31a9c22113..14e44d1378 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -43,9 +43,9 @@ void input_report_key_event(struct input_device *idev, unsigned int code, int va return; if (value) - set_bit(code, &idev->keys); + set_bit(code, idev->keys); else - clear_bit(code, &idev->keys); + clear_bit(code, idev->keys); event.code = code; event.value = value; diff --git a/drivers/mci/omap_hsmmc.c b/drivers/mci/omap_hsmmc.c index 180afb16c9..cbc69e4083 100644 --- a/drivers/mci/omap_hsmmc.c +++ b/drivers/mci/omap_hsmmc.c @@ -631,6 +631,8 @@ static int omap_mmc_probe(struct device_d *dev) hsmmc->mci.devname = xstrdup(alias); } + mci_of_parse(&hsmmc->mci); + dev->priv = hsmmc; dev->detect = omap_mmc_detect, diff --git a/drivers/mfd/da9053.c b/drivers/mfd/da9053.c index 250c0556ec..9adab8c75a 100644 --- a/drivers/mfd/da9053.c +++ b/drivers/mfd/da9053.c @@ -240,6 +240,10 @@ static void da9053_detect_reset_source(struct da9053_priv *da9053) priority = of_get_reset_source_priority(da9053->dev->device_node); reset_source_set_priority(type, priority); + + ret = da9053_reg_write(da9053, DA9053_FAULTLOG_REG, val); + if (ret < 0) + return; } static void __noreturn da9053_force_system_reset(struct restart_handler *rst) @@ -293,9 +297,18 @@ static int da9053_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id da9053_dt_ids[] = { + { + .compatible = "dlg,da9052", + }, { + /* sentinel */ + } +}; + static struct driver_d da9053_driver = { .name = DRIVERNAME, .probe = da9053_probe, + .of_compatible = DRV_OF_COMPAT(da9053_dt_ids), }; static int da9053_init(void) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 656a7f5ef0..8a67792125 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -179,7 +179,7 @@ static const struct platform_device_id m25p_ids[] = { {"en25f32"}, {"en25p32"}, {"en25q32b"}, {"en25p64"}, {"en25q64"}, {"en25qh128"}, {"en25qh256"}, {"f25l32pa"}, - {"mr25h256"}, {"mr25h10"}, + {"mr25h256"}, {"mr25h10"}, {"mr25h40"}, {"gd25q32"}, {"gd25q64"}, {"160s33b"}, {"320s33b"}, {"640s33b"}, {"mx25l2005a"}, {"mx25l4005a"}, {"mx25l8005"}, {"mx25l1606e"}, diff --git a/drivers/mtd/peb.c b/drivers/mtd/peb.c index 639dc0ee6f..66227d4ffb 100644 --- a/drivers/mtd/peb.c +++ b/drivers/mtd/peb.c @@ -252,7 +252,6 @@ retry: int mtd_peb_check_all_ff(struct mtd_info *mtd, int pnum, int offset, int len, int warn) { - size_t read; int err; void *buf; @@ -263,8 +262,8 @@ int mtd_peb_check_all_ff(struct mtd_info *mtd, int pnum, int offset, int len, err = mtd_peb_read(mtd, buf, pnum, offset, len); if (err && !mtd_is_bitflip(err)) { dev_err(&mtd->class_dev, - "error %d while reading %d bytes from PEB %d:%d, read %zd bytes\n", - err, len, pnum, offset, read); + "error %d while reading %d bytes from PEB %d:%d\n", + err, len, pnum, offset); goto out; } @@ -398,7 +397,7 @@ int mtd_peb_write(struct mtd_info *mtd, const void *buf, int pnum, int offset, addr = (loff_t)pnum * mtd->erasesize + offset; err = mtd_write(mtd, addr, len, &written, buf); if (err) { - dev_err(&mtd->class_dev, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes\n", + dev_err(&mtd->class_dev, "error %d while writing %d bytes to PEB %d:%d, written %zu bytes\n", err, len, pnum, offset, written); } else { if (written != len) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 45be586238..faeafe1bfb 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -504,6 +504,7 @@ static const struct spi_device_id spi_nor_ids[] = { /* Everspin */ { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, + { "mr25h40", CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) }, /* Fujitsu */ { "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) }, diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 43af4a52df..6d08f92ea6 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -711,7 +711,7 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, p = (char *)vid_hdr - ubi->vid_hdr_shift; read_err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset, - ubi->vid_hdr_alsize); + ubi->vid_hdr_shift + UBI_VID_HDR_SIZE); if (read_err && read_err != UBI_IO_BITFLIPS && !mtd_is_eccerr(read_err)) return read_err; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 3f848a4396..c9157cdd74 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -271,7 +271,7 @@ static struct device_d *of_amba_device_create(struct device_node *np) /* Allow the HW Peripheral ID to be overridden */ of_property_read_u32(np, "arm,primecell-periphid", &dev->periphid); - debug("register device 0x%08x\n", dev->dev.resource[0].start); + debug("register device %pa\n", &dev->dev.resource[0].start); ret = amba_device_add(dev); if (ret) |