diff options
Diffstat (limited to 'drivers/staging/nvec')
| -rw-r--r-- | drivers/staging/nvec/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/staging/nvec/nvec.c | 74 | ||||
| -rw-r--r-- | drivers/staging/nvec/nvec.h | 30 | ||||
| -rw-r--r-- | drivers/staging/nvec/nvec_kbd.c | 10 | ||||
| -rw-r--r-- | drivers/staging/nvec/nvec_ps2.c | 2 |
5 files changed, 49 insertions, 69 deletions
diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig index 7e61adacd15..9475e20c3d6 100644 --- a/drivers/staging/nvec/Kconfig +++ b/drivers/staging/nvec/Kconfig @@ -10,7 +10,7 @@ config KEYBOARD_NVEC tristate "Keyboard on nVidia compliant EC" depends on MFD_NVEC && INPUT help - Say Y here to enable support for a keyboard connected to + Say Y here to enable support for a keyboard connected to a nVidia compliant embedded controller. config SERIO_NVEC_PS2 diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 197c393c4ca..90f1c4d7fa8 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -33,11 +33,9 @@ #include <linux/mfd/core.h> #include <linux/mutex.h> #include <linux/notifier.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/workqueue.h> -#include <linux/clk/tegra.h> #include "nvec.h" @@ -84,7 +82,7 @@ enum nvec_sleep_subcmds { static struct nvec_chip *nvec_power_handle; -static struct mfd_cell nvec_devices[] = { +static const struct mfd_cell nvec_devices[] = { { .name = "nvec-kbd", .id = 1, @@ -680,9 +678,9 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) nvec->rx->data[nvec->rx->pos++] = received; else dev_err(nvec->dev, - "RX buffer overflow on %p: " - "Trying to write byte %u of %u\n", - nvec->rx, nvec->rx->pos, NVEC_MSG_SIZE); + "RX buffer overflow on %p: Trying to write byte %u of %u\n", + nvec->rx, nvec->rx ? nvec->rx->pos : 0, + NVEC_MSG_SIZE); break; default: nvec->state = 0; @@ -734,9 +732,9 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) clk_prepare_enable(nvec->i2c_clk); - tegra_periph_reset_assert(nvec->i2c_clk); + reset_control_assert(nvec->rst); udelay(2); - tegra_periph_reset_deassert(nvec->i2c_clk); + reset_control_deassert(nvec->rst); val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); @@ -751,8 +749,6 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) writel(0, nvec->base + I2C_SL_ADDR2); enable_irq(nvec->irq); - - clk_disable_unprepare(nvec->i2c_clk); } #ifdef CONFIG_PM_SLEEP @@ -772,11 +768,31 @@ static void nvec_power_off(void) nvec_write_async(nvec_power_handle, ap_pwr_down, 2); } +/* + * Parse common device tree data + */ +static int nvec_i2c_parse_dt_pdata(struct nvec_chip *nvec) +{ + nvec->gpio = of_get_named_gpio(nvec->dev->of_node, "request-gpios", 0); + + if (nvec->gpio < 0) { + dev_err(nvec->dev, "no gpio specified"); + return -ENODEV; + } + + if (of_property_read_u32(nvec->dev->of_node, "slave-addr", + &nvec->i2c_addr)) { + dev_err(nvec->dev, "no i2c address specified"); + return -ENODEV; + } + + return 0; +} + static int tegra_nvec_probe(struct platform_device *pdev) { int err, ret; struct clk *i2c_clk; - struct nvec_platform_data *pdata = pdev->dev.platform_data; struct nvec_chip *nvec; struct nvec_msg *msg; struct resource *res; @@ -785,6 +801,11 @@ static int tegra_nvec_probe(struct platform_device *pdev) unmute_speakers[] = { NVEC_OEM0, 0x10, 0x59, 0x95 }, enable_event[7] = { NVEC_SYS, CNF_EVENT_REPORTING, true }; + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "must be instantiated using device tree\n"); + return -ENODEV; + } + nvec = devm_kzalloc(&pdev->dev, sizeof(struct nvec_chip), GFP_KERNEL); if (nvec == NULL) { dev_err(&pdev->dev, "failed to reserve memory\n"); @@ -793,25 +814,9 @@ static int tegra_nvec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nvec); nvec->dev = &pdev->dev; - if (pdata) { - nvec->gpio = pdata->gpio; - nvec->i2c_addr = pdata->i2c_addr; - } else if (nvec->dev->of_node) { - nvec->gpio = of_get_named_gpio(nvec->dev->of_node, - "request-gpios", 0); - if (nvec->gpio < 0) { - dev_err(&pdev->dev, "no gpio specified"); - return -ENODEV; - } - if (of_property_read_u32(nvec->dev->of_node, - "slave-addr", &nvec->i2c_addr)) { - dev_err(&pdev->dev, "no i2c address specified"); - return -ENODEV; - } - } else { - dev_err(&pdev->dev, "no platform data\n"); - return -ENODEV; - } + err = nvec_i2c_parse_dt_pdata(nvec); + if (err < 0) + return err; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(&pdev->dev, res); @@ -830,6 +835,12 @@ static int tegra_nvec_probe(struct platform_device *pdev) return -ENODEV; } + nvec->rst = devm_reset_control_get(&pdev->dev, "i2c"); + if (IS_ERR(nvec->rst)) { + dev_err(nvec->dev, "failed to get controller reset\n"); + return PTR_ERR(nvec->rst); + } + nvec->base = base; nvec->irq = res->start; nvec->i2c_clk = i2c_clk; @@ -864,9 +875,6 @@ static int tegra_nvec_probe(struct platform_device *pdev) tegra_init_i2c_slave(nvec); - clk_prepare_enable(i2c_clk); - - /* enable event reporting */ nvec_toggle_global_events(nvec, true); diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index 2b1316d8747..e271375053f 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -23,6 +23,7 @@ #include <linux/list.h> #include <linux/mutex.h> #include <linux/notifier.h> +#include <linux/reset.h> #include <linux/spinlock.h> #include <linux/workqueue.h> @@ -103,38 +104,14 @@ struct nvec_msg { }; /** - * struct nvec_subdev - A subdevice of nvec, such as nvec_kbd - * @name: The name of the sub device - * @platform_data: Platform data - * @id: Identifier of the sub device - */ -struct nvec_subdev { - const char *name; - void *platform_data; - int id; -}; - -/** - * struct nvec_platform_data - platform data for a tegra slave controller - * @i2c_addr: number of i2c slave adapter the ec is connected to - * @gpio: gpio number for the ec request line - * - * Platform data, to be used in board definitions. For an example, take a - * look at the paz00 board in arch/arm/mach-tegra/board-paz00.c - */ -struct nvec_platform_data { - int i2c_addr; - int gpio; -}; - -/** * struct nvec_chip - A single connection to an NVIDIA Embedded controller * @dev: The device * @gpio: The same as for &struct nvec_platform_data * @irq: The IRQ of the I2C device * @i2c_addr: The address of the I2C slave * @base: The base of the memory mapped region of the I2C device - * @clk: The clock of the I2C device + * @i2c_clk: The clock of the I2C device + * @rst: The reset of the I2C device * @notifier_list: Notifiers to be called on received messages, see * nvec_register_notifier() * @rx_data: Received messages that have to be processed @@ -164,6 +141,7 @@ struct nvec_chip { int i2c_addr; void __iomem *base; struct clk *i2c_clk; + struct reset_control *rst; struct atomic_notifier_head notifier_list; struct list_head rx_data, tx_data; struct notifier_block nvec_status_notifier; diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index a0ec52a4114..c17a1c3eb3c 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -126,7 +126,7 @@ static int nvec_kbd_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i) keycodes[j++] = extcode_tab_us102[i]; - idev = input_allocate_device(); + idev = devm_input_allocate_device(&pdev->dev); idev->name = "nvec keyboard"; idev->phys = "nvec"; idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_LED); @@ -142,7 +142,7 @@ static int nvec_kbd_probe(struct platform_device *pdev) clear_bit(0, idev->keybit); err = input_register_device(idev); if (err) - goto fail; + return err; keys_dev.input = idev; keys_dev.notifier.notifier_call = nvec_keys_notifier; @@ -161,10 +161,6 @@ static int nvec_kbd_probe(struct platform_device *pdev) nvec_write_async(nvec, clear_leds, sizeof(clear_leds)); return 0; - -fail: - input_free_device(idev); - return err; } static int nvec_kbd_remove(struct platform_device *pdev) @@ -177,8 +173,6 @@ static int nvec_kbd_remove(struct platform_device *pdev) nvec_write_async(nvec, disable_kbd, 2); nvec_unregister_notifier(nvec, &keys_dev.notifier); - input_unregister_device(keys_dev.input); - return 0; } diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 06dbb02085a..45b2f1308e0 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -106,7 +106,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) struct serio *ser_dev; char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 }; - ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); + ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL); if (ser_dev == NULL) return -ENOMEM; |
