diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/base/bus.c | 27 | ||||
-rw-r--r-- | drivers/base/driver.c | 4 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware.c | 8 | ||||
-rw-r--r-- | drivers/net/phy/micrel.c | 34 | ||||
-rw-r--r-- | drivers/of/base.c | 12 | ||||
-rw-r--r-- | drivers/regulator/of_regulator.c | 148 | ||||
-rw-r--r-- | drivers/usb/gadget/udc-core.c | 55 | ||||
-rw-r--r-- | drivers/usb/imx/chipidea-imx.c | 5 | ||||
-rw-r--r-- | drivers/video/atmel_lcdfb_core.c | 1 | ||||
-rw-r--r-- | drivers/video/bcm2835.c | 1 | ||||
-rw-r--r-- | drivers/video/bochs/bochs_hw.c | 1 | ||||
-rw-r--r-- | drivers/video/imx-ipu-fb.c | 2 | ||||
-rw-r--r-- | drivers/video/imx-ipu-v3/ipufb.c | 1 | ||||
-rw-r--r-- | drivers/video/imx.c | 2 | ||||
-rw-r--r-- | drivers/video/omap.c | 1 | ||||
-rw-r--r-- | drivers/video/pxa.c | 1 | ||||
-rw-r--r-- | drivers/video/s3c24xx.c | 1 | ||||
-rw-r--r-- | drivers/video/simplefb-client.c | 1 | ||||
-rw-r--r-- | drivers/video/ssd1307fb.c | 1 | ||||
-rw-r--r-- | drivers/video/stm.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/wd_core.c | 26 |
21 files changed, 96 insertions, 237 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 1038d20a12..aac5b69f34 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -75,7 +75,7 @@ int device_match_of_modalias(struct device_d *dev, struct driver_d *drv) { const struct platform_device_id *id = drv->id_table; const char *of_modalias = NULL, *p; - int cplen; + const struct property *prop; const char *compat; if (!device_match(dev, drv)) @@ -84,25 +84,16 @@ int device_match_of_modalias(struct device_d *dev, struct driver_d *drv) if (!id || !IS_ENABLED(CONFIG_OFDEVICE) || !dev->device_node) return -1; - compat = of_get_property(dev->device_node, "compatible", &cplen); - if (!compat) - return -1; - - p = strchr(compat, ','); - of_modalias = p ? p + 1 : compat; - - while (id->name) { - if (!strcmp(id->name, dev->name)) { - dev->id_entry = id; - return 0; - } + of_property_for_each_string(dev->device_node, "compatible", prop, compat) { + p = strchr(compat, ','); + of_modalias = p ? p + 1 : compat; - if (of_modalias && !strcmp(id->name, of_modalias)) { - dev->id_entry = id; - return 0; + for (id = drv->id_table; id->name; id++) { + if (!strcmp(id->name, dev->name) || !strcmp(id->name, of_modalias)) { + dev->id_entry = id; + return 0; + } } - - id++; } return -1; diff --git a/drivers/base/driver.c b/drivers/base/driver.c index f60533c59e..1fa3f6c6fa 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -480,9 +480,7 @@ int dev_set_name(struct device_d *dev, const char *fmt, ...) */ free(oldname); - WARN_ON(err < 0); - - return err; + return WARN_ON(err < 0) ? err : 0; } EXPORT_SYMBOL_GPL(dev_set_name); diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware.c index bb9a0b7c4a..8508fac717 100644 --- a/drivers/i2c/busses/i2c-designware.c +++ b/drivers/i2c/busses/i2c-designware.c @@ -274,7 +274,7 @@ static void i2c_dw_setup_timings(struct dw_i2c_dev *dw) if (!(dw->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK)) dw->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT; - dev_dbg(&dw->adapter.dev, "adjust SDA hold time.\n"); + dev_dbg(dw->adapter.dev.parent, "adjust SDA hold time.\n"); writel(dw->sda_hold_time, dw->base + DW_IC_SDA_HOLD); } } @@ -547,9 +547,7 @@ static int i2c_dw_probe(struct device_d *pdev) ic_comp_type_value = readl(dw->base + DW_IC_COMP_TYPE); if (ic_comp_type_value != DW_IC_COMP_TYPE_VALUE) { - dev_err(pdev, - "unknown DesignWare IP block 0x%08x", - ic_comp_type_value); + dev_err(pdev, "unknown DesignWare IP block 0x%08x\n", ic_comp_type_value); ret = -ENODEV; goto fail; } @@ -574,7 +572,7 @@ static int i2c_dw_probe(struct device_d *pdev) ic_con = DW_IC_CON_SPEED_FAST; break; default: - dev_warn(pdev, "requested bitrate (%d) is not supported." + dev_warn(pdev, "requested bitrate (%d) is not supported.\n" " Falling back to 100kHz", bitrate); case 100000: /* FALLTHROUGH */ ic_con = DW_IC_CON_SPEED_STD; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 4e46370241..ea193c84a7 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -28,13 +28,16 @@ #define KSZPHY_OMSO_MII_OVERRIDE BIT(0) /* general PHY control reg in vendor specific block. */ -#define MII_KSZPHY_CTRL 0x1F +#define MII_KSZPHY_CTRL 0x1F /* bitmap of PHY register to set interrupt mode */ #define KSZPHY_CTRL_INT_ACTIVE_HIGH BIT(9) #define KSZ9021_CTRL_INT_ACTIVE_HIGH BIT(14) #define KS8737_CTRL_INT_ACTIVE_HIGH BIT(14) #define KSZ8051_RMII_50MHZ_CLK BIT(7) +/* PHY Control 1 */ +#define MII_KSZPHY_CTRL_1 0x1e + /* Write/read to/from extended registers */ #define MII_KSZPHY_EXTREG 0x0b #define KSZPHY_EXTREG_WRITE 0x8000 @@ -63,18 +66,35 @@ static int kszphy_extended_read(struct phy_device *phydev, return phy_read(phydev, MII_KSZPHY_EXTREG_READ); } +/* Handle LED mode, shift = position of first led mode bit, usually 4 or 14 */ +static int kszphy_led_mode(struct phy_device *phydev, int reg, int shift) +{ + const struct device_d *dev = &phydev->dev; + const struct device_node *of_node = dev->device_node ? : dev->parent->device_node; + u32 val; + + if (!of_property_read_u32(of_node, "micrel,led-mode", &val)) { + if (val > 0x03) { + dev_err(dev, "led-mode 0x%02x out of range\n", val); + return -1; + } + return phy_modify(phydev, reg, 0x03 << shift, val << shift); + } + return 0; +} + static int kszphy_config_init(struct phy_device *phydev) { + kszphy_led_mode(phydev, MII_KSZPHY_CTRL_1, 14); + return 0; } static int ksz8021_config_init(struct phy_device *phydev) { - u16 val; + phy_set_bits(phydev, MII_KSZPHY_OMSO, KSZPHY_OMSO_B_CAST_OFF); - val = phy_read(phydev, MII_KSZPHY_OMSO); - val |= KSZPHY_OMSO_B_CAST_OFF; - phy_write(phydev, MII_KSZPHY_OMSO, val); + kszphy_led_mode(phydev, MII_KSZPHY_CTRL, 4); return 0; } @@ -89,6 +109,8 @@ static int ks8051_config_init(struct phy_device *phydev) phy_write(phydev, MII_KSZPHY_CTRL, regval); } + kszphy_led_mode(phydev, MII_KSZPHY_CTRL, 4); + return 0; } @@ -143,6 +165,8 @@ static int ksz9021_config_init(struct phy_device *phydev) ksz9021_load_values_from_of(phydev, of_node, MII_KSZPHY_TX_DATA_PAD_SKEW, tx_pad_skew_names); + + kszphy_led_mode(phydev, 0x11, 6); } return 0; diff --git a/drivers/of/base.c b/drivers/of/base.c index 6fe02649ee..0e8750efec 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1048,7 +1048,7 @@ int of_property_match_string(struct device_node *np, const char *propname, } EXPORT_SYMBOL_GPL(of_property_match_string); -const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur, +const __be32 *of_prop_next_u32(const struct property *prop, const __be32 *cur, u32 *pu) { const void *curv = cur; @@ -1074,7 +1074,7 @@ out_val: } EXPORT_SYMBOL_GPL(of_prop_next_u32); -const char *of_prop_next_string(struct property *prop, const char *cur) +const char *of_prop_next_string(const struct property *prop, const char *cur) { const void *curv = cur; const void *value; @@ -2002,6 +2002,14 @@ static void __of_print_property(struct property *p, int indent) printf(";\n"); } +void of_print_properties(struct device_node *node) +{ + struct property *prop; + + list_for_each_entry(prop, &node->properties, list) + __of_print_property(prop, 0); +} + static int __of_print_parents(struct device_node *node) { int indent, i; diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 3e8caa8710..c536a82c43 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -9,145 +9,6 @@ #include <common.h> #include <of.h> #include <linux/regulator/of_regulator.h> -#include <linux/regulator/machine.h> - -static int of_get_regulation_constraints(struct device_d *dev, - struct device_node *np, - struct regulator_init_data **init_data, - const struct regulator_desc *desc) -{ - struct regulation_constraints *constraints = &(*init_data)->constraints; - int ret; - u32 pval; - - constraints->name = of_get_property(np, "regulator-name", NULL); - - if (!of_property_read_u32(np, "regulator-min-microvolt", &pval)) - constraints->min_uV = pval; - - if (!of_property_read_u32(np, "regulator-max-microvolt", &pval)) - constraints->max_uV = pval; - - /* Voltage change possible? */ - if (constraints->min_uV != constraints->max_uV) - constraints->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; - - /* Do we have a voltage range, if so try to apply it? */ - if (constraints->min_uV && constraints->max_uV) - constraints->apply_uV = true; - - if (!of_property_read_u32(np, "regulator-microvolt-offset", &pval)) - constraints->uV_offset = pval; - if (!of_property_read_u32(np, "regulator-min-microamp", &pval)) - constraints->min_uA = pval; - if (!of_property_read_u32(np, "regulator-max-microamp", &pval)) - constraints->max_uA = pval; - - if (!of_property_read_u32(np, "regulator-input-current-limit-microamp", - &pval)) - constraints->ilim_uA = pval; - - /* Current change possible? */ - if (constraints->min_uA != constraints->max_uA) - constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT; - - constraints->boot_on = of_property_read_bool(np, "regulator-boot-on"); - constraints->always_on = of_property_read_bool(np, "regulator-always-on"); - if (!constraints->always_on) /* status change should be possible. */ - constraints->valid_ops_mask |= REGULATOR_CHANGE_STATUS; - - constraints->pull_down = of_property_read_bool(np, "regulator-pull-down"); - - if (of_property_read_bool(np, "regulator-allow-bypass")) - constraints->valid_ops_mask |= REGULATOR_CHANGE_BYPASS; - - if (of_property_read_bool(np, "regulator-allow-set-load")) - constraints->valid_ops_mask |= REGULATOR_CHANGE_DRMS; - - ret = of_property_read_u32(np, "regulator-ramp-delay", &pval); - if (!ret) { - if (pval) - constraints->ramp_delay = pval; - else - constraints->ramp_disable = true; - } - - ret = of_property_read_u32(np, "regulator-settling-time-us", &pval); - if (!ret) - constraints->settling_time = pval; - - ret = of_property_read_u32(np, "regulator-settling-time-up-us", &pval); - if (!ret) - constraints->settling_time_up = pval; - if (constraints->settling_time_up && constraints->settling_time) { - pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-up-us'\n", - np); - constraints->settling_time_up = 0; - } - - ret = of_property_read_u32(np, "regulator-settling-time-down-us", - &pval); - if (!ret) - constraints->settling_time_down = pval; - if (constraints->settling_time_down && constraints->settling_time) { - pr_warn("%pOFn: ambiguous configuration for settling time, ignoring 'regulator-settling-time-down-us'\n", - np); - constraints->settling_time_down = 0; - } - - ret = of_property_read_u32(np, "regulator-enable-ramp-delay", &pval); - if (!ret) - constraints->enable_time = pval; - - constraints->soft_start = of_property_read_bool(np, - "regulator-soft-start"); - ret = of_property_read_u32(np, "regulator-active-discharge", &pval); - if (!ret) { - constraints->active_discharge = - (pval) ? REGULATOR_ACTIVE_DISCHARGE_ENABLE : - REGULATOR_ACTIVE_DISCHARGE_DISABLE; - } - - if (!of_property_read_u32(np, "regulator-system-load", &pval)) - constraints->system_load = pval; - - if (!of_property_read_u32(np, "regulator-max-step-microvolt", - &pval)) - constraints->max_uV_step = pval; - - constraints->over_current_protection = of_property_read_bool(np, - "regulator-over-current-protection"); - - return 0; -} - -/** - * of_get_regulator_init_data - extract regulator_init_data structure info - * @dev: device requesting for regulator_init_data - * @node: regulator device node - * @desc: regulator description - * - * Populates regulator_init_data structure by extracting data from device - * tree node, returns a pointer to the populated structure or NULL if memory - * alloc fails. - */ -struct regulator_init_data *of_get_regulator_init_data(struct device_d *dev, - struct device_node *node, - const struct regulator_desc *desc) -{ - struct regulator_init_data *init_data; - - if (!node) - return NULL; - - init_data = xzalloc(sizeof(*init_data)); - - if (of_get_regulation_constraints(dev, node, &init_data, desc)) - return NULL; - - return init_data; -} -EXPORT_SYMBOL_GPL(of_get_regulator_init_data); struct devm_of_regulator_matches { struct of_regulator_match *matches; @@ -192,7 +53,6 @@ int of_regulator_match(struct device_d *dev, struct device_node *node, for (i = 0; i < num_matches; i++) { struct of_regulator_match *match = &matches[i]; - match->init_data = NULL; match->of_node = NULL; } @@ -210,14 +70,6 @@ int of_regulator_match(struct device_d *dev, struct device_node *node, if (strcmp(match->name, name)) continue; - match->init_data = of_get_regulator_init_data(dev, child, - match->desc); - if (!match->init_data) { - dev_err(dev, - "failed to parse DT for regulator %pOFn\n", - child); - return -EINVAL; - } match->of_node = child; count++; break; diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 2516676f86..bd3404f9cf 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -46,61 +46,6 @@ static LIST_HEAD(udc_list); /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_KERNEL_HAS_DMA - -int usb_gadget_map_request(struct usb_gadget *gadget, - struct usb_request *req, int is_in) -{ - if (req->length == 0) - return 0; - - if (req->num_sgs) { - int mapped; - - mapped = dma_map_sg(&gadget->dev, req->sg, req->num_sgs, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - if (mapped == 0) { - dev_err(&gadget->dev, "failed to map SGs\n"); - return -EFAULT; - } - - req->num_mapped_sgs = mapped; - } else { - req->dma = dma_map_single(&gadget->dev, req->buf, req->length, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - - if (dma_mapping_error(&gadget->dev, req->dma)) { - dev_err(&gadget->dev, "failed to map buffer\n"); - return -EFAULT; - } - } - - return 0; -} -EXPORT_SYMBOL_GPL(usb_gadget_map_request); - -void usb_gadget_unmap_request(struct usb_gadget *gadget, - struct usb_request *req, int is_in) -{ - if (req->length == 0) - return; - - if (req->num_mapped_sgs) { - dma_unmap_sg(&gadget->dev, req->sg, req->num_mapped_sgs, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - - req->num_mapped_sgs = 0; - } else { - dma_unmap_single(&gadget->dev, req->dma, req->length, - is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - } -} -EXPORT_SYMBOL_GPL(usb_gadget_unmap_request); - -#endif /* CONFIG_HAS_DMA */ - -/* ------------------------------------------------------------------------- */ - void usb_gadget_set_state(struct usb_gadget *gadget, enum usb_device_state state) { diff --git a/drivers/usb/imx/chipidea-imx.c b/drivers/usb/imx/chipidea-imx.c index 7b87f302a9..aa27941c8c 100644 --- a/drivers/usb/imx/chipidea-imx.c +++ b/drivers/usb/imx/chipidea-imx.c @@ -256,8 +256,11 @@ static int imx_chipidea_probe(struct device_d *dev) } ci->vbus = regulator_get(dev, "vbus"); - if (IS_ERR(ci->vbus)) + if (IS_ERR(ci->vbus)) { + dev_warn(dev, "Cannot get vbus regulator: %pe (ignoring)\n", + ci->vbus); ci->vbus = NULL; + } /* * Some devices have more than one clock, in this case they are enabled diff --git a/drivers/video/atmel_lcdfb_core.c b/drivers/video/atmel_lcdfb_core.c index daabfe92d2..e7e420d38f 100644 --- a/drivers/video/atmel_lcdfb_core.c +++ b/drivers/video/atmel_lcdfb_core.c @@ -489,6 +489,7 @@ int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) sinfo->dma_desc = dma_alloc_coherent(data->dma_desc_size, DMA_ADDRESS_BROKEN); + info->dev.parent = dev; ret = register_framebuffer(info); if (ret != 0) { dev_err(dev, "Failed to register framebuffer\n"); diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c index 3d52f8b6b8..d808bc5c9f 100644 --- a/drivers/video/bcm2835.c +++ b/drivers/video/bcm2835.c @@ -118,6 +118,7 @@ static int bcm2835fb_probe(struct device_d *dev) info->fbi.mode->xres = info->fbi.xres; info->fbi.mode->yres = info->fbi.yres; + info->fbi.dev.parent = dev; ret = register_framebuffer(&info->fbi); if (ret) { free(info); diff --git a/drivers/video/bochs/bochs_hw.c b/drivers/video/bochs/bochs_hw.c index 252350aebb..debdd36941 100644 --- a/drivers/video/bochs/bochs_hw.c +++ b/drivers/video/bochs/bochs_hw.c @@ -201,5 +201,6 @@ int bochs_hw_probe(struct device_d *dev, void __iomem *fb_map, void __iomem *mmi fb->priv = bochs; fb->fbops = &bochs_fb_ops; + fb->dev.parent = dev; return register_framebuffer(fb); } diff --git a/drivers/video/imx-ipu-fb.c b/drivers/video/imx-ipu-fb.c index a3f195373b..f39b74676c 100644 --- a/drivers/video/imx-ipu-fb.c +++ b/drivers/video/imx-ipu-fb.c @@ -969,6 +969,7 @@ static int sdc_fb_register_overlay(struct ipu_fb_info *fbi, void *fb) sdc_enable_channel(fbi, overlay->screen_base, IDMAC_SDC_1); + fbi->overlay.dev.parent = &fbi->info.dev; ret = register_framebuffer(&fbi->overlay); if (ret < 0) { dev_err(fbi->dev, "failed to register framebuffer\n"); @@ -1039,6 +1040,7 @@ static int imxfb_probe(struct device_d *dev) sdc_enable_channel(fbi, info->screen_base, IDMAC_SDC_0); + fbi->info.dev.parent = dev; ret = register_framebuffer(&fbi->info); if (ret < 0) { dev_err(dev, "failed to register framebuffer\n"); diff --git a/drivers/video/imx-ipu-v3/ipufb.c b/drivers/video/imx-ipu-v3/ipufb.c index 0b53916434..68e87ff3fb 100644 --- a/drivers/video/imx-ipu-v3/ipufb.c +++ b/drivers/video/imx-ipu-v3/ipufb.c @@ -336,6 +336,7 @@ static int ipufb_probe(struct device_d *dev) if (ret) dev_dbg(fbi->dev, "failed to get modes: %s\n", strerror(-ret)); + info->dev.parent = dev; ret = register_framebuffer(info); if (ret < 0) { dev_err(fbi->dev, "failed to register framebuffer\n"); diff --git a/drivers/video/imx.c b/drivers/video/imx.c index e93859775a..f4f58b3ce3 100644 --- a/drivers/video/imx.c +++ b/drivers/video/imx.c @@ -514,6 +514,7 @@ static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb) overlay->blue = rgb->blue; overlay->transp = rgb->transp; + overlay->dev.parent = &fbi->info.dev; ret = register_framebuffer(overlay); if (ret < 0) { dev_err(fbi->dev, "failed to register framebuffer\n"); @@ -592,6 +593,7 @@ static int imxfb_probe(struct device_d *dev) imxfb_activate_var(&fbi->info); + fbi->info.dev.parent = dev; ret = register_framebuffer(&fbi->info); if (ret < 0) { dev_err(dev, "failed to register framebuffer\n"); diff --git a/drivers/video/omap.c b/drivers/video/omap.c index 009626fefc..52a68ef627 100644 --- a/drivers/video/omap.c +++ b/drivers/video/omap.c @@ -493,6 +493,7 @@ static int omapfb_probe(struct device_d *dev) goto out; } + info->dev.parent = dev; rc = register_framebuffer(info); if (rc < 0) { dev_err(dev, "failed to register framebuffer: %d\n", rc); diff --git a/drivers/video/pxa.c b/drivers/video/pxa.c index a2ff4bce2a..45efa6b71d 100644 --- a/drivers/video/pxa.c +++ b/drivers/video/pxa.c @@ -533,6 +533,7 @@ static int pxafb_probe(struct device_d *dev) pxafb_activate_var(fbi); + fbi->info.dev.parent = dev; ret = register_framebuffer(&fbi->info); if (ret < 0) { dev_err(dev, "failed to register framebuffer\n"); diff --git a/drivers/video/s3c24xx.c b/drivers/video/s3c24xx.c index 84ed0aee39..eb784162db 100644 --- a/drivers/video/s3c24xx.c +++ b/drivers/video/s3c24xx.c @@ -395,6 +395,7 @@ static int s3cfb_probe(struct device_d *hw_dev) if (IS_ENABLED(CONFIG_DRIVER_VIDEO_S3C_VERBOSE)) hw_dev->info = s3cfb_info; + fbi.info.dev.parent = hw_dev; ret = register_framebuffer(&fbi.info); if (ret != 0) { dev_err(hw_dev, "Failed to register framebuffer\n"); diff --git a/drivers/video/simplefb-client.c b/drivers/video/simplefb-client.c index 2d0495f616..1f26ac5067 100644 --- a/drivers/video/simplefb-client.c +++ b/drivers/video/simplefb-client.c @@ -121,6 +121,7 @@ static int simplefb_probe(struct device_d *dev) info->xres, info->yres, info->bits_per_pixel, info->line_length); + info->dev.parent = dev; ret = register_framebuffer(info); if (ret < 0) { dev_err(dev, "Unable to register simplefb: %d\n", ret); diff --git a/drivers/video/ssd1307fb.c b/drivers/video/ssd1307fb.c index 994f43dc5c..af5d6086e1 100644 --- a/drivers/video/ssd1307fb.c +++ b/drivers/video/ssd1307fb.c @@ -543,6 +543,7 @@ static int ssd1307fb_probe(struct device_d *dev) if (ret) goto reset_oled_error; + info->dev.parent = dev; ret = register_framebuffer(info); if (ret) { dev_err(&client->dev, "Couldn't register the framebuffer\n"); diff --git a/drivers/video/stm.c b/drivers/video/stm.c index d4a618fe50..28ddc649f8 100644 --- a/drivers/video/stm.c +++ b/drivers/video/stm.c @@ -571,6 +571,7 @@ static int stmfb_probe(struct device_d *hw_dev) fb_of_reserve_add_fixup(&fbi.info); + fbi.info.dev.parent = hw_dev; ret = register_framebuffer(&fbi.info); if (ret != 0) { dev_err(hw_dev, "Failed to register framebuffer\n"); diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c index 4b0ee31d5b..2e2814a8f2 100644 --- a/drivers/watchdog/wd_core.c +++ b/drivers/watchdog/wd_core.c @@ -18,6 +18,7 @@ #include <errno.h> #include <linux/ctype.h> #include <watchdog.h> +#include <restart.h> static LIST_HEAD(watchdog_list); @@ -177,6 +178,24 @@ static int seconds_to_expire_get(struct param_d *p, void *priv) return 0; } +static void __noreturn watchdog_restart_handle(struct restart_handler *this) +{ + struct watchdog *wd = watchdog_get_default(); + int ret = -ENODEV; + + if (wd) + ret = watchdog_set_timeout(wd, 1); + + BUG_ON(ret); + mdelay(2000); + __builtin_unreachable(); +} + +static struct restart_handler restart_handler = { + .restart = watchdog_restart_handle, + .name = "watchdog-restart", +}; + int watchdog_register(struct watchdog *wd) { struct param_d *p; @@ -247,6 +266,13 @@ int watchdog_register(struct watchdog *wd) goto error_unregister; } + if (!restart_handler.priority) { + restart_handler.priority = 10; /* don't override others */ + ret = restart_handler_register(&restart_handler); + if (ret) + dev_warn(&wd->dev, "failed to register restart handler\n"); + } + list_add_tail(&wd->list, &watchdog_list); pr_debug("registering watchdog %s with priority %d\n", watchdog_name(wd), |