/* * Maxim MAX77620 Watchdog Driver * * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. * * Author: Laxman Dewangan * * 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 #include #include #include #include #include #include #include #include static bool nowayout = WATCHDOG_NOWAYOUT; struct max77620_wdt { struct device *dev; struct regmap *rmap; struct watchdog_device wdt_dev; }; static int max77620_wdt_start(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, MAX77620_WDTEN, MAX77620_WDTEN); } static int max77620_wdt_stop(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, MAX77620_WDTEN, 0); } static int max77620_wdt_ping(struct watchdog_device *wdt_dev) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, MAX77620_WDTC_MASK, 0x1); } static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, unsigned int timeout) { struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); unsigned int wdt_timeout; u8 regval; int ret; switch (timeout) { case 0 ... 2: regval = MAX77620_TWD_2s; wdt_timeout = 2; break; case 3 ... 16: regval = MAX77620_TWD_16s; wdt_timeout = 16; break; case 17 ... 64: regval = MAX77620_TWD_64s; wdt_timeout = 64; break; default: regval = MAX77620_TWD_128s; wdt_timeout = 128; break; } ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, MAX77620_WDTC_MASK, 0x1); if (ret < 0) return ret; ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, MAX77620_TWD_MASK, regval); if (ret < 0) return ret; wdt_dev->timeout = wdt_timeout; return 0; } static const struct watchdog_info max77620_wdt_info = { .identity = "max77620-watchdog", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, }; static const struct watchdog_ops max77620_wdt_ops = { .start = max77620_wdt_start, .stop = max77620_wdt_stop, .ping = max77620_wdt_ping, .set_timeout = max77620_wdt_set_timeout, }; static int max77620_wdt_probe(struct platform_device *pdev) { struct max77620_wdt *wdt; struct watchdog_device *wdt_dev; unsigned int regval; int ret; wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; wdt->dev = &pdev->dev; wdt->rmap = dev_get_regmap(pdev->dev.parent, NULL); if (!wdt->rmap) { dev_err(wdt->dev, "Failed to get parent regmap\n"); return -ENODEV; } wdt_dev = &wdt->wdt_dev; wdt_dev->info = &max77620_wdt_info; wdt_dev->ops = &max77620_wdt_ops; wdt_dev->min_timeout = 2; wdt_dev->max_timeout = 128; wdt_dev->max_hw_heartbeat_ms = 128 * 1000; platform_set_drvdata(pdev, wdt); /* Enable WD_RST_WK - WDT expire results in a restart */ ret = regmap_update_bits(wdt->rmap, MAX77620_REG_ONOFFCNFG2, MAX77620_ONOFFCNFG2_WD_RST_WK, MAX77620_ONOFFCNFG2_WD_RST_WK); if (ret < 0) { dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret); return ret; } /* Set WDT clear in OFF and sleep mode */ ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, MAX77620_WDTOFFC | MAX77620_WDTSLPC, MAX77620_WDTOFFC | MAX77620_WDTSLPC); if (ret < 0) { dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret); return ret; } /* Check if WDT running and if yes then set flags properly */ ret = regmap_read(wdt->rmap, MAX77620_REG_CNFGGLBL2, ®val); if (ret < 0) { dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret); return ret; } switch (regval & MAX77620_TWD_MASK) { case MAX77620_TWD_2s: wdt_dev->timeout = 2; break; case MAX77620_TWD_16s: wdt_dev->timeout = 16; break; case MAX77620_TWD_64s: wdt_dev->timeout = 64; break; default: wdt_dev->timeout = 128; break; } if (regval & MAX77620_WDTEN) set_bit(WDOG_HW_RUNNING, &wdt_dev->status); watchdog_set_nowayout(wdt_dev, nowayout); watchdog_set_drvdata(wdt_dev, wdt); ret = watchdog_register_device(wdt_dev); if (ret < 0) { dev_err(&pdev->dev, "watchdog registration failed: %d\n", ret); return ret; } return 0; } static int max77620_wdt_remove(struct platform_device *pdev) { struct max77620_wdt *wdt = platform_get_drvdata(pdev); max77620_wdt_stop(&wdt->wdt_dev); watchdog_unregister_device(&wdt->wdt_dev); return 0; } static struct platform_device_id max77620_wdt_devtype[] = { { .name = "max77620-watchdog", }, { }, }; MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); static struct platform_driver max77620_wdt_driver = { .driver = { .name = "max77620-watchdog", }, .probe = max77620_wdt_probe, .remove = max77620_wdt_remove, .id_table = max77620_wdt_devtype, }; module_platform_driver(max77620_wdt_driver); MODULE_DESCRIPTION("Max77620 watchdog timer driver"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_AUTHOR("Laxman Dewangan "); MODULE_LICENSE("GPL v2"); 554f8eb2d9f520642ba'>e88418808c867ed54bca5ff357b96737ce3720d6 /drivers/usb/chipidea/ci_hdrc_imx.c parent203f80f1c4187b2d5b3a282586fa6cc6d9503d4b (diff)parent0faa9cb5b3836a979864a6357e01d2046884ad52 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Handle multicast packets properly in fast-RX path of mac80211, from Johannes Berg. 2) Because of a logic bug, the user can't actually force SW checksumming on r8152 devices. This makes diagnosis of hw checksumming bugs really annoying. Fix from Hayes Wang. 3) VXLAN route lookup does not take the source and destination ports into account, which means IPSEC policies cannot be matched properly. Fix from Martynas Pumputis. 4) Do proper RCU locking in netvsc callbacks, from Stephen Hemminger. 5) Fix SKB leaks in mlxsw driver, from Arkadi Sharshevsky. 6) If lwtunnel_fill_encap() fails, we do not abort the netlink message construction properly in fib_dump_info(), from David Ahern. 7) Do not use kernel stack for DMA buffers in atusb driver, from Stefan Schmidt. 8) Openvswitch conntack actions need to maintain a correct checksum, fix from Lance Richardson. 9) ax25_disconnect() is missing a check for ax25->sk being NULL, in fact it already checks this, but not in all of the necessary spots. Fix from Basil Gunn. 10) Action GET operations in the packet scheduler can erroneously bump the reference count of the entry, making it unreleasable. Fix from Jamal Hadi Salim. Jamal gives a great set of example command lines that trigger this in the commit message. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (46 commits) net sched actions: fix refcnt when GETing of action after bind net/mlx4_core: Eliminate warning messages for SRQ_LIMIT under SRIOV net/mlx4_core: Fix when to save some qp context flags for dynamic VST to VGT transitions net/mlx4_core: Fix racy CQ (Completion Queue) free net: stmmac: don't use netdev_[dbg, info, ..] before net_device is registered net/mlx5e: Fix a -Wmaybe-uninitialized warning ax25: Fix segfault after sock connection timeout bpf: rework prog_digest into prog_tag tipc: allocate user memory with GFP_KERNEL flag net: phy: dp83867: allow RGMII_TXID/RGMII_RXID interface types ip6_tunnel: Account for tunnel header in tunnel MTU mld: do not remove mld souce list info when set link down be2net: fix MAC addr setting on privileged BE3 VFs be2net: don't delete MAC on close on unprivileged BE3 VFs be2net: fix status check in be_cmd_pmac_add() cpmac: remove hopeless #warning ravb: do not use zero-length alignment DMA descriptor mlx4: do not call napi_schedule() without care openvswitch: maintain correct checksum state in conntrack actions tcp: fix tcp_fastopen unaligned access complaints on sparc ...
Diffstat (limited to 'drivers/usb/chipidea/ci_hdrc_imx.c')