summaryrefslogtreecommitdiff
path: root/drivers/core
Commit message (Collapse)AuthorAgeLines
* fdt: allow fdtdec_get_addr_size_*() to translate addressesStephen Warren2016-08-12-1/+1
| | | | | | | | | | | | | | | Some code may want to read reg values from DT, but from nodes that aren't associated with DM devices, so using dev_get_addr_index() isn't appropriate. In this case, fdtdec_get_addr_size_*() are the functions to use. However, "translation" (via the chain of ranges properties in parent nodes) may still be desirable. Add a function parameter to request that, and implement it. Update all call sites to default to the original behaviour. Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Simon Glass <sjg@chromium.org> Squashed in build fix from Stephen: Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: Convert users from dm_scan_fdt_node() to dm_scan_fdt_dev()Simon Glass2016-07-27-2/+1
| | | | | | | This new function is more convenient for callers, and handles pre-relocation situations automatically. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Add a function to bind child devicesSimon Glass2016-07-27-0/+9
| | | | | | | | | | | | | | We currently use dm_scan_fdt_node() to bind devices. It is an internal function and it requires the caller to know whether we are pre- or post- relocation. This requirement has become quite common in drivers, so the current function is not ideal. Add a new function with fewer arguments, that does not require internal headers. This can be used directly as a post_bind() method if needed. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Add a way to find a device by its driverSimon Glass2016-07-25-0/+20
| | | | | | | | | Some SoCs have a single clock device. Provide a way to find it given its driver name. This is handled by the linker so will fail if the name is not found, avoiding strange errors when names change and do not match. It is also faster than a string comparison. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Add an implementation of regmap_init_mem_platdata()Simon Glass2016-07-14-2/+16
| | | | | | | | Add an implementation of this function which mirrors the functions of the automatic device-tree implementation. This can be used with of-platdata to create regmaps. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Move regmap allocation into a separate functionSimon Glass2016-07-14-12/+22
| | | | | | | We plan to add a new way of creating a regmap for of-platdata. Move the allocation code into a separate function so that it can be shared. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Expand platdata for of-platdata devicesSimon Glass2016-07-14-11/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Devices which use of-platdata have their own platdata. However, in many cases the driver will have its own auto-alloced platdata, for use with the device tree. The ofdata_to_platdata() method converts the device tree settings to platdata. With of-platdata we would not normally allocate the platdata since it is provided by the U_BOOT_DEVICE() declaration. However this is inconvenient since the of-platdata struct is closely tied to the device tree properties. It is unlikely to exactly match the platdata needed by the driver. In fact a useful approach is to declare platdata in the driver like this: struct r3288_mmc_platdata { struct dtd_rockchip_rk3288_dw_mshc of_platdata; /* the 'normal' fields go here */ }; In this case we have dt_platadata available, but the normal fields are not present, since ofdata_to_platdata() is never called. In fact driver model doesn't allocate any space for the 'normal' fields, since it sees that there is already platform data attached to the device. To make this easier, adjust driver model to allocate the full size of the struct (i.e. platdata_auto_alloc_size from the driver) and copy in the of-platdata. This means that when the driver's bind() method is called, the of-platdata will be present, followed by zero bytes for the empty 'normal field' portion. A new DM_FLAG_OF_PLATDATA flag is available that indicates that the platdata came from of-platdata. When the allocation/copy happens, the DM_FLAG_ALLOC_PDATA flag will be set as well. The dtoc tool is updated to output the platdata_size field, since U-Boot has no other way of knowing the size of the of-platdata struct. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Rename DM_NAME_ALLOCED to DM_FLAG_NAME_ALLOCEDSimon Glass2016-07-14-2/+2
| | | | | | This is a flag. Adjust the name to be consistent with the other flags. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: syscon: Add support for of-platdataSimon Glass2016-07-14-0/+13
| | | | | | | Provide a new function which can cope with obtaining information from of-platdata instead of the device tree. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: regmap: Add a dummy implementation for of-platdataSimon Glass2016-07-14-0/+9
| | | | | | | Add a placeholder for now so that this code will compile. It currently does nothing. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Don't use device tree with of-platdataSimon Glass2016-07-14-4/+4
| | | | | | | When CONFIG_SPL_OF_PLATDATA is enabled we should not access the device tree. Remove all references to this in the core driver-model code. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: implement dev_map_physmem()Vignesh R2016-07-09-0/+11
| | | | | | | | | | | | This API helps to map physical register addresss pace of device to virtual address space easily. Its just a wrapper around map_physmem() with MAP_NOCACHE flag. Signed-off-by: Vignesh R <vigneshr@ti.com> Suggested-by: Simon Glass <sjg@chromium.org> Reviewed-by: Jagan Teki <jteki@openedev.com> Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Jagan Teki <jteki@openedev.com>
* dm: add manual relocation for devicesAngelo Dureghello2016-06-19-0/+15
| | | | | | | | Some architectures as m68k still need to use CONFIG_NEEDS_MANUAL_RELOC, and are not still using the device tree. Signed-off-by: Angelo Dureghello <angelo@sysam.it> Acked-by: Simon Glass <sjg@chromium.org>
* dm: allow setting driver_data before/during bindStephen Warren2016-05-26-5/+24
| | | | | | | | | | | This will allow a driver's bind function to use the driver data. One example is the Tegra186 GPIO driver, which instantiates child devices for each of its GPIO ports, yet supports two different HW instances each with a different set of ports, and identified by the udevice_id .data field. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Simon Glass <sjg@chromium.org>
* fdt: Support for ISA bussesPaul Burton2016-05-25-0/+23
| | | | | | | | | | Support ISA busses in much the same way as Linux does. This allows for ISA bus addresses to be translated, and only if CONFIG_OF_ISA_BUS is selected in order to avoid including the code in builds which won't need it. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Reviewed-by: Simon Glass <sjg@chromium.org>
* drivers: core: device: add support to check dt compatible for a device/machineMugunthan V N2016-05-24-0/+14
| | | | | | | | | | | Provide an api to check whether the given device or machine is compatible with the given compat string which helps in making decisions in drivers based on device or machine compatible. Idea taken from Linux. Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
* dm: core: Allow device names to be freed automaticallySimon Glass2016-05-17-0/+8
| | | | | | | | | | Some devices have a name that is stored in allocated memory. At present there is no mechanism to free this memory when the device is unbound. Add a device flag to track whether a name is allocated and a function to add the flag. Free the memory when the device is unbound. Signed-off-by: Simon Glass <sjg@chromium.org>
* fdt: fix dev_get_addr_name node offsetStephen Warren2016-05-17-2/+2
| | | | | | | | Use the device's own DT offset, not the device's parent's. Fixes: 43c4d44e3330 ("fdt: implement dev_get_addr_name()") Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Simon Glass <sjg@chromium.org>
* dm: core: allow drivers to refuse to bindStephen Warren2016-05-17-0/+4
| | | | | | | | | | | | | In some cases, drivers may not want to bind to a device. Allow bind() to return -ENODEV in this case, and don't treat this as an error. This can be useful in situations where some information source other than the DT node's main status property indicates whether the device should be enabled, for example other DT properties might indicate this, or the driver might query non-DT sources such as system fuses or a version number register. Signed-off-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Simon Glass <sjg@chromium.org>
* dm: core: Add dev_get_addr_ptr() to return a pointer to the reg addressStefan Roese2016-04-25-0/+5
| | | | | | | | | | | | | | | | | | On some platforms (e.g. x86), the return value of dev_get_addr() can't be assigned to a pointer type variable directly. As there might be a difference between the size of fdt_addr_t and the pointer type. On x86 for example, "fdt_addr_t" is 64bit but "void *" only 32bit. So assigning the register base directly in dev_get_addr() results in this compilation warning: warning: cast to pointer from integer of different size This patch introduces the new function dev_get_addr_ptr() that returns a pointer to the 'reg' address that can be used by drivers in this case. Signed-off-by: Stefan Roese <sr@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* fdt: implement dev_get_addr_name()Stephen Warren2016-04-15-0/+16
| | | | | | | | | This function parses the reg property based on an index found in the reg-names property. This is required for bindings that are written using reg-names rather than hard-coding indices in reg. Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Simon Glass <sjg@chromium.org>
* dm: device.c: Minor coding-style fixStefan Roese2016-04-14-6/+6
| | | | | | | | Fix multi-line comment indentation in device_bind() Signed-off-by: Stefan Roese <sr@denx.de> Cc: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* dm: core: device: set pinctrl state for pinctrl devicePeng Fan2016-04-14-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We may have pinmux settings for pinctrl device, like the following example: " &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog_1>; imx6ul-evk { pinctrl_hog_1: hoggrp-1 { fsl,pins = < MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */ MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */ MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 0x17059 /* SD1 RESET */ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x80000000 >; }; [......] }; " We should not only select pinctrl state for non pinctrl devices, we need also to handle pin mux settings such as pinctrl_log for pinctrl devices. So at the end of probing process of pinctrl device, select the default state of pinctrl device. Signed-off-by: Peng Fan <van.freenix@gmail.com> Cc: Simon Glass <sjg@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Masahiro Yamada <yamada.masahiro@socionext.com>
* syscon: Avoid returning a device on failureSimon Glass2016-03-17-0/+1
| | | | | | | | | If the device cannot be probed, syscon_get_by_driver_data() will still return a useful value in its devp parameter. Ensure that it returns NULL instead. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* dm: core: make simple-bus compatible to simple-mfdMasahiro Yamada2016-03-14-0/+1
| | | | | | | | Simple MFD devices can bind children without special bus configuration. Like Linux, let's handle "simple-mfd" in the same way as "simple-bus". Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com> Acked-by: Simon Glass <sjg@chromium.org>
* dm: core: Add uclass_first_device_err() to return a valid deviceSimon Glass2016-03-14-0/+13
| | | | | | | | A common pattern is to call uclass_first_device() and then check if it actually returns a device. Add a new function which does this, returning an error if there are no devices in that uclass. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: Remove device_probe_child()Simon Glass2016-01-28-8/+1
| | | | | | | | | This function is not used as the use case for it did not eventuate. Remove it to avoid confusion. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Tom Rini <trini@konsulko.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* dm: syscon: Allow finding devices by driver dataSimon Glass2016-01-24-12/+19
| | | | | | | | We have a way to find a regmap by its syscon driver data value. Add the same for syscon itself. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* dm: core: Display the error number when driver binding failsSimon Glass2016-01-24-1/+2
| | | | | | | | This is often -96 (-EPFNOSUPPORT) which indicates that the uclass is not compiled in. Display the error number to make this easier to spot. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
* dm: core: Export uclass_find_device_by_of_offset()Simon Glass2016-01-21-2/+2
| | | | | | | | It is sometimes useful to be able to find a device before probing it, perhaps to set up some platform data for it. Allow finding by of_offset also. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Don't set pinctrl for pinctrl devicesSimon Glass2016-01-21-2/+4
| | | | | | | | | | | | | | There is sort-of race condition when a pinctrl device is probed. The pinctrl function is called which may end up using the same device as is being probed. This results in operations being used before the device is actually probed. For now, disallow pinctrl operations on pinctrl devices while probing. An alternative solution would be to move the operation to later in the device_probe() function (for pinctrl devices only) but this needs more thought. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Call uclass post_bind() after the driver's bind() methodSimon Glass2016-01-20-5/+7
| | | | | | | | | | | | | | | | | At present the uclass's post_bind() method is called before the driver's bind() method. This means that the uclass cannot use any of the information set up by the driver. Move it later in the sequence to permit this. This is an ordering change which is always fairly major in nature. The main impact is that devices which have children will not see them appear in their bind() method. From what I can see, existing drivers do not look at their children in the bind() method, so this should be safe. Conceptually this change seems to result in a 'more correct' ordering, since the uclass (which is broader than the device) gets the last word. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Tom Rini <trini@konsulko.com>
* dm: core: Provide uclass_find_device_by_phandle() only when neededSimon Glass2016-01-20-0/+4
| | | | | | | This function cannot be used unless support is enabled for device tree control. Adjust the code to reflect that. Signed-off-by: Simon Glass <sjg@chromium.org>
* Merge branch 'master' of git://www.denx.de/git/u-boot-microblazeTom Rini2016-01-13-1/+10
|\
| * spl: dm: Add SPL_DM_SEQ_ALIAS config optionNathan Rossi2016-01-13-1/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Device Model sequence alias feature is required by some Uclasses. Instead of disabling the feature for all SPL targets allow it to be configured. The config option is disabled by default to reduce code size for targets that are not interested or do not require this feature. Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> Acked-by: Simon Glass <sjg@chromium.org> Acked-by: Michal Simek <michal.simek@xilinx.com> Cc: Simon Glass <sjg@chromium.org> Cc: Masahiro Yamada <yamada.masahiro@socionext.com> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Marek Vasut <marex@denx.de> Cc: Michal Simek <michal.simek@xilinx.com> Cc: Stefan Roese <sr@denx.de> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
* | dm: core: Add a new api to get indexed device addressMugunthan V N2016-01-13-4/+27
| | | | | | | | | | | | | | | | | | Add new api to get device address based on index. Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com> Acked-by: Jagan Teki <jteki@openedev.com> [Rebased on master] Signed-off-by: Jagan Teki <jteki@openedev.com>
* | dm: core: Add option to configure an offset for the address translationStefan Roese2016-01-12-11/+41
|/ | | | | | | | | | | | Some platforms need to ability to configure an offset to the standard addresses extracted from the device-tree. This patch allows this by adding a function to DM to configure this offset (if needed). Signed-off-by: Stefan Roese <sr@denx.de> Acked-by: Simon Glass <sjg@chromium.org> Cc: Simon Glass <sjg@chromium.org> Fixed space before tab: Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Fix Kconfig text to mention SPL in SPL_OF_TRANSLATEStefan Roese2015-12-10-1/+1
| | | | | | | | | | Add a remark about SPL to this Kconfig option. Otherwise its identitcal to the non-SPL version, which is confusing. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Simon Glass <sjg@chromium.org> Acked-by: Simon Glass <sjg@chromium.org> Acked-by: Michal Simek <michal.simek@xilinx.com>
* dm: core: Enable SPL_SIMPLE_BUS by defaultMichal Simek2015-12-07-1/+1
| | | | | | | | | | | This option is needed for all SoCs which have nodes on bus. Without enabling this drivers are not found and probed. Issue was found on Zynq MMC probe. Enable this option by default. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Reviewed-by: Stefan Roese <sr@denx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
* dm: core: Add SPL Kconfig for REGMAP and SYSCONhuang lin2015-12-01-2/+21
| | | | | | | | Add SPL Kconfig for REGMAP and SYSCON, so REGMAP and SYSCON can remove from SPL stage. Signed-off-by: Lin Huang <hl@rock-chips.com> Acked-by: Simon Glass <sjg@chromium.org>
* Revert "dm: Export device_remove_children / device_unbind_children"Simon Glass2015-11-19-4/+18
| | | | | | This reverts commit bb52b367f6ca4a3a918e77737f4ff6a1089912d9. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: core: Add missing entries for manual relocationMichal Simek2015-11-19-0/+8
| | | | | | | | | | | | | | | | | | | Patches: "dm: core: Add a post_bind method for parents" (sha1: 0118ce79577f9b0881f99a6e4f8a79cd5014cb87) "dm: core: Add a uclass pre_probe() method for devices" (sha1: 02c07b3741f1b825934b1a6eb8f23530532dc426) "dm: core: Allow the uclass to set up a device's child after binding" (sha1: 081f2fcbd9a95ba10677065359791f8fea3f8c58) "dm: core: Allow uclass to set up a device's child before it is probed" (sha1: 83c7e434c9dd3ca81f8b763e23c1881b973bcf2f) Adds new entries to struct driver and struct uclass_driver without extending code for manual relocation. This patch fixes it for all architectures which requires MANUAL_RELOC. Signed-off-by: Michal Simek <michal.simek@xilinx.com> Acked-by: Simon Glass <sjg@chromium.org>
* Merge branch 'master' of git://git.denx.de/u-boot-netTom Rini2015-10-29-7/+0
|\
| * dm: core: Remove unnecessary codes in uclass_pre_remove_device()Bin Meng2015-10-29-7/+0
| | | | | | | | | | | | | | | | dev->uclass->uc_drv->per_device_auto_alloc_size is to be freed in device_free(), so is dev->seq. Remove these unnecessary codes. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Simon Glass <sjg@chromium.org>
* | dm: Rename dev_get_parentdata() to dev_get_parent_priv()Simon Glass2015-10-23-1/+1
|/ | | | | | | | The current name is inconsistent with other driver model data access functions. Rename it and fix up all users. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Joe Hershberger <joe.hershberger@ni.com>
* dm: core: Enable optional use of fdt_translate_address()Stefan Roese2015-10-21-0/+50
| | | | | | | | | | | | | | The current "simple" address translation simple_bus_translate() is not working on some platforms (e.g. MVEBU). As here more complex "ranges" properties are used in many nodes (multiple tuples etc). This patch enables the optional use of the common fdt_translate_address() function which handles this translation correctly. Signed-off-by: Stefan Roese <sr@denx.de> Cc: Simon Glass <sjg@chromium.org> Cc: Bin Meng <bmeng.cn@gmail.com> Cc: Marek Vasut <marex@denx.de> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
* dm: core: Don't use pinctrl for the root deviceSimon Glass2015-10-05-2/+6
| | | | | | | | | | | | | | | | | | | | | Currently when driver model starts up it finds the root uclass and the pinctrl uclass. This is because even the root node handles pinctrl processing. But this is not useful. The root node is not a real hardware device so cannot require any particular pinmux settings. Also it means that the memory leak tests fails, since they end up freeing more memory than they allocate: the marker it set after the root device and pinctrl uclass are allocated, and later once the pinctrl uclass is freed the memory used by driver model is less than when the marker was set. If a platform needs 'core' pin mulitplex settings it can do this with a driver that is probed on start-up. It would be an abuse of the root node to use this for pinctrl. To avoid this problem, only process pinctrl settings for non-root nodes. Signed-off-by: Simon Glass <sjg@chromium.org>
* fdt: add new fdt address parsing functionsStephen Warren2015-09-15-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | fdtdec_get_addr_size() hard-codes the number of cells used to represent an address or size in DT. This is incorrect in many cases depending on the DT binding for a particular node or property (e.g. it is incorrect for the "reg" property). In most cases, DT parsing code must use the properties #address-cells and #size-cells to parse addres properties. This change splits up the implementation of fdtdec_get_addr_size() so that the core logic can be used for both hard-coded and non-hard-coded cases. Various wrapper functions are implemented that support cases where hard-coded cell counts should or should not be used, and where the client does and doesn't know the parent node ID that contains the properties #address-cells and #size-cells. dev_get_addr() is updated to use the new functions. Core functionality in fdtdec_get_addr_size_fixed() is widely tested via fdtdec_get_addr_size(). I tested fdtdec_get_addr_size_auto_noparent() and dev_get_addr() by manually modifying the Tegra I2C driver to invoke them. Much of the core implementation of fdtdec_get_addr_size_fixed(), fdtdec_get_addr_size_auto_parent(), and fdtdec_get_addr_size_auto_noparent() comes from Thierry Reding's previous commit "fdt: Fix fdtdec_get_addr_size() for 64-bit". Based-on-work-by: Thierry Reding <treding@nvidia.com> Cc: Thierry Reding <treding@nvidia.com> Cc: Simon Glass <sjg@chromium.org> Cc: Michal Suchanek <hramrach@gmail.com> Signed-off-by: Stephen Warren <swarren@nvidia.com> Acked-by: Simon Glass <sjg@chromium.org> Dropped #define DEBUG at the top of fdtdec.c: Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: Provide better debugging when a device fails to bindSimon Glass2015-09-02-1/+4
| | | | | | | | | | All devices should bind without error. But when they don't, they can cause driver model init to fail. A real situation where this can happen is when there is a missing uclass. Add a debug() call to dm_scan_fdt_node to make this easier to track. Signed-off-by: Simon Glass <sjg@chromium.org>
* dm: Improve handling of a missing uclassSimon Glass2015-09-02-2/+9
| | | | | | | | | | | | | | | When a uclass definition is missing, no drivers in that uclass can operate. This can happen if a board has a strange collection of options (e.g. the driver is enabled but the uclass is not). Unfortunately this is very confusing at present. Starting up driver model results in a -ENOENT error, which is pretty generic. Quite a big of digging is needed to get to the root cause. To help with this, change the error to a very strange one with no other users in U-Boot. Also add a debug message. Signed-off-by: Simon Glass <sjg@chromium.org>