Re: [PATCH] usb: dwc3-pci: Ensure system sleep PM ops are defined only when used
On 7 August 2013 17:34, Mark Brown broo...@kernel.org wrote: On Tue, Aug 06, 2013 at 10:35:52PM -0300, Fabio Estevam wrote: On Tue, Aug 6, 2013 at 12:49 PM, Mark Brown broo...@kernel.org wrote: From: Andy Green andy.gr...@linaro.org You might have CONFIG_PM, but you might not have CONFIG_SUSPEND, in which case these are unused. Signed-off-by: Andy Green andy.gr...@linaro.org Signed-off-by: Mark Brown broo...@linaro.org What about doing this instead? Makes sense to me - Andy? Sure, it seems a much more complete solution. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 06/12/12 00:42, the mail apparently from Alan Stern included: On Wed, 5 Dec 2012, Andy Green wrote: The details of this aren't clear yet. For instance, should the device core try to match the port with the asset info, or should this be done by the USB code when the port is created? Currently what I have (this is before changing it to pm domain, but this should be unchanged) lets the asset define a callback op which will receive notifications for all added child devices that have the device the asset is bound to as an ancestor. So you would bind an asset to the host controller device... static struct device_asset assets_ehci_omap0[] = { { .name = -0:1.0/port1, .asset = assets_ehci_omap0_smsc_port, .ops = device_descendant_attach_default_asset_ops, }, { } }; ...with this descendant filter callback pointing to a generic end of the device path matcher. when device_descendant_attach_default_asset_ops() sees the child that was foretold has appeared (and it only hears about children of ehci-omap.0 in this case), it binds the assets pointed to by .asset to the new child before its probe. assets_ehci_omap0_smsc_port is an array of the actual regulator and clock that need switching by the child. So the effect is to magic the right assets to the child device just before it gets added (and probe called etc). This is working well and the matcher helper is small and simple. Right. The question is should it be done in this somewhat roundabout way (you've got two separate assets for setting up this one thing), or should the USB port code be responsible for explicitly checking if there are any applicable assets when the port is created? The advantange of the second approach is that it doesn't involve checking all the ancestors every time a new device is added (and it involves only one asset). The disadvantage is that it works only for USB ports. It's done in two steps to strongly filter candidate child devices against being children of a known platform device. If you go around that, you will be back to full device path matching with wildcards at the USB child to determine if he is the one. So that's a feature not an issue I think. I can see doing it generically or not is equally a political issue as a technical one, but I think if we bother to add this kind of support we should prefer to do it generally. It's going to be about the same amount of code. As Tony Lindgren said, even board-omap4panda.c itself is deprecated, to project platform info into USB stack you either have to add DT code into usb stack then to go find things directly, or provide a generic methodology like assets which have the dt bindings done outside of any subsystem and apply their operations outside the subsystem too. To answer the question, we need to know how other subsystems might want to use the asset-matching approach. My guess is that only a small number of device types would care about assets (in the same way that assets matter to USB ports but not to other USB device types). And it might not be necessary to check against every ancestor; we might know beforehand where to check (just as the USB port would know to look for an asset attached to the host controller device). Yes I think it boils down to buses in general can benefit from this. They're the thing that dynamically - later - create child devices you might need to target with what was ultimately platform information. On Panda the other bus thing that can benefit is the WLAN module on SDIO. In fact that's a very illuminating case for your question above. Faced with exactly the same problem, that they needed to project platform info on to SDIO-probed device instance to tell it what clock rate it had been given, they invented an api which you can see today in board-omap4panda.c and other boards there, wl12xx_set_platform_data(). This is from board-4430sdp: static struct wl12xx_platform_data omap4_sdp4430_wlan_data __initdata = { .board_ref_clock = WL12XX_REFCLOCK_26, .board_tcxo_clock = WL12XX_TCXOCLOCK_26, }; ... ret = wl12xx_set_platform_data(omap4_sdp4430_wlan_data); You can find the other end of it here in drivers/net/wireless/ti/wlcore/wl12xx_platform_data.c static struct wl12xx_platform_data *platform_data; int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) { if (platform_data) return -EBUSY; if (!data) return -EINVAL; platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); if (!platform_data) return -ENOMEM; return 0; } when the driver for the device instance wants to get its platform data it reads the static pointer via another api. Obviously if you want two modules on your platform that's not so good. I doubt that's the only SDIO device that wants to know platform info. So I think
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 05/12/12 01:10, the mail apparently from Alan Stern included: [CC: list trimmed; the people who were on it should be subscribed to at least one of the lists anyway.] On Tue, 4 Dec 2012, Andy Green wrote: I think associating ULPI PHY reset and SMSC power and reset with the hub port power state is good. Then, you could have the driver in a device with multiple onboard USB devices, and individually control whether they're eating power or not. In the asset case, you'd associate mux assets with ehci-omap.0. Yesterday I studied the hub port code and have a couple of patches, one normalizes the hub port device to have a stub driver. The other then puts hub port power state signalling into runtime_pm handlers in the hub port device. Until now, actually there's no code in hub.c to switch off a port. In fact that's not quite true. You simply weren't aware of the new code; you can find a series of patches starting here: http://marc.info/?l=linux-usbm=135314427413307w=2 The parts of interest to us begin in patch 7/10. Yes I have been looking in usb-next. Assuming that's not insane, what should the user interface to disable a port power look like, something in sysfs? Until now it doesn't seem to exist. It will be implemented through PM QOS. OK. I saw [PATCH 09/10] usb: expose usb port's pm qos flags to user space now. (On the other hand, since the LAN95xx is the only thing connected to the root hub, it could be powered off and on by unbinding the ehci-omap.0 device from its driver and rebinding it.) We shouldn't get to tied up with Panda case, this will be there for all cases like PCs etc. It should work well if there are multiple ports with onboard assets. Okay, I'm fine with tying this to the port. OK. 2. If we do choose the port, do we want to identify it by matching against a device name string or by matching a sequence of port numbers (in this case, a length-1 sequence)? The port numbers are fixed by the board design, whereas the device name strings might get changed in the future. On the other hand, the port numbers apply only to USB whereas device names can be used by any subsystem. USB device names contain the port information. The matching scheme I have currently just uses the right-hand side of the path information and nothing that is not defined by the USB subsystem. It uses a platform_device ancestor to restrict matches to descendants of the right host controller. So unlike try#1 the names are as stable as the subsystem code alone, however stable that is, it's not exposed to changes from anywhere else. As you mention it's then workable on any dynamically probed bus. 3. Should the matching mechanism go into the device core or into the USB port code? (This is related to the previous question.) Currently I am experimenting with having the asset pointer in struct device, but migrating the events into runtime_resume and runtime_suspend. If it works out that has advantages that assets follow not just the logical device existence but the pm state of the device closely. It also allows leveraging assets directly to the hub port runtime_pm state, so they follow enable state of the port without any additional code. If we use a PM domain then there won't be any need to hook the runtime PM events. The domain will automatically be notified about power changes. OK. 4. Should this be implemented simply as a regulator (or a pair of regulators)? Or should it be generalized to some sort of PM domain thing? The generic_pm_domain structure defined in include/linux/pm_domain.h seems like overkill, but maybe it's the most appropriate thing to use. They should be regulators for that I think. But it's only part the problem since clocks and mux are also going to be commonly associated with device power state, and indeed are in Panda case. I realize restricting the scope is desirable to get something done, but I'm not sure supporting regulators only is enough of the job. Then why not use a PM domain? It will allow us to do whatever we want in the callbacks. I see, I never met them before now is the reason ^^. You're right it's already in struct device too, and it's much more plumbed into the future apis than what I have been doing. I'll study how to change what I have to fit this and do so. On Tue, 4 Dec 2012, Ming Lei wrote: Alos, the same ehci-omap driver and same LAN95xx chip is used in beagle board and panda board with different power control approach, does port driver can distinguish these two cases? Port device is a general device(not platform device), how does port driver get platform/board dependent info? This is the part that Andy has been working on. The board-dependent info will be registered by the board file, and it will take effect either when the port is registered or when it is bound
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 05/12/12 02:14, the mail apparently from Sarah Sharp included: On Tue, Dec 04, 2012 at 11:40:05AM +0800, Andy Green wrote: On 04/12/12 01:09, the mail apparently from Alan Stern included: On Mon, 3 Dec 2012, Andy Green wrote: Unless someone NAKs it for sure already (if you're already sure you're going to, please do so to avoid wasting time), I'll issue a try#2 of my code later which demonstrates what I mean. At least I guess it's useful for comparative purposes. Before you go writing a whole lot more code, we should discuss the basics a bit more clearly. There are several unsettled issues here: 1. Should the LAN95xx stuff be associated with the ehci-omap.0's driver or with the hub port? The port would be more flexible, offering the ability to turn the power off and on while the system is running without affecting anything else. But the port code is currently in flux, which could cause this new addition to be delayed. I think associating ULPI PHY reset and SMSC power and reset with the hub port power state is good. Then, you could have the driver in a device with multiple onboard USB devices, and individually control whether they're eating power or not. In the asset case, you'd associate mux assets with ehci-omap.0. Yesterday I studied the hub port code and have a couple of patches, one normalizes the hub port device to have a stub driver. The other then puts hub port power state signalling into runtime_pm handlers in the hub port device. Until now, actually there's no code in hub.c to switch off a port. Did you take a look at the most recent patches from Tianyu to add support to power off a port if a device is suspended? Start of the series: http://marc.info/?l=linux-usbm=135314427413307w=2 Patch that adds power off on device suspend: http://marc.info/?l=linux-usbm=135314431913321w=2 Tianyu also added some code to the xHCI host controller driver to call into the ACPI methods to power off a port when the USB hub driver clears the port power feature. No I didn't know about it, I will study these along with pm_domain stuff thanks. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 04/12/12 01:09, the mail apparently from Alan Stern included: On Mon, 3 Dec 2012, Andy Green wrote: Unless someone NAKs it for sure already (if you're already sure you're going to, please do so to avoid wasting time), I'll issue a try#2 of my code later which demonstrates what I mean. At least I guess it's useful for comparative purposes. Before you go writing a whole lot more code, we should discuss the basics a bit more clearly. There are several unsettled issues here: 1. Should the LAN95xx stuff be associated with the ehci-omap.0's driver or with the hub port? The port would be more flexible, offering the ability to turn the power off and on while the system is running without affecting anything else. But the port code is currently in flux, which could cause this new addition to be delayed. I think associating ULPI PHY reset and SMSC power and reset with the hub port power state is good. Then, you could have the driver in a device with multiple onboard USB devices, and individually control whether they're eating power or not. In the asset case, you'd associate mux assets with ehci-omap.0. Yesterday I studied the hub port code and have a couple of patches, one normalizes the hub port device to have a stub driver. The other then puts hub port power state signalling into runtime_pm handlers in the hub port device. Until now, actually there's no code in hub.c to switch off a port. Assuming that's not insane, what should the user interface to disable a port power look like, something in sysfs? Until now it doesn't seem to exist. (On the other hand, since the LAN95xx is the only thing connected to the root hub, it could be powered off and on by unbinding the ehci-omap.0 device from its driver and rebinding it.) We shouldn't get to tied up with Panda case, this will be there for all cases like PCs etc. It should work well if there are multiple ports with onboard assets. 2. If we do choose the port, do we want to identify it by matching against a device name string or by matching a sequence of port numbers (in this case, a length-1 sequence)? The port numbers are fixed by the board design, whereas the device name strings might get changed in the future. On the other hand, the port numbers apply only to USB whereas device names can be used by any subsystem. USB device names contain the port information. The matching scheme I have currently just uses the right-hand side of the path information and nothing that is not defined by the USB subsystem. It uses a platform_device ancestor to restrict matches to descendants of the right host controller. So unlike try#1 the names are as stable as the subsystem code alone, however stable that is, it's not exposed to changes from anywhere else. As you mention it's then workable on any dynamically probed bus. 3. Should the matching mechanism go into the device core or into the USB port code? (This is related to the previous question.) Currently I am experimenting with having the asset pointer in struct device, but migrating the events into runtime_resume and runtime_suspend. If it works out that has advantages that assets follow not just the logical device existence but the pm state of the device closely. It also allows leveraging assets directly to the hub port runtime_pm state, so they follow enable state of the port without any additional code. 4. Should this be implemented simply as a regulator (or a pair of regulators)? Or should it be generalized to some sort of PM domain thing? The generic_pm_domain structure defined in include/linux/pm_domain.h seems like overkill, but maybe it's the most appropriate thing to use. They should be regulators for that I think. But it's only part the problem since clocks and mux are also going to be commonly associated with device power state, and indeed are in Panda case. I realize restricting the scope is desirable to get something done, but I'm not sure supporting regulators only is enough of the job. Until we decide on the answers to these questions, there's no point writing detailed patches. I agree, however I can't get insight into and confidence about what to do without studying and meddling with the code. Some throwaway code is probably a reasonable price. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 04/12/12 10:39, the mail apparently from Ming Lei included: On Mon, Dec 3, 2012 at 12:52 PM, Andy Green andy.gr...@linaro.org wrote: +static void ehci_hub_power_off(struct power_controller *pc, struct device *dev) +{ + gpio_set_value(GPIO_HUB_NRESET, 0); + gpio_set_value(GPIO_HUB_POWER, 0); +} + +static struct usb_port_power_switch_data root_hub_port_data = { + .hub_tier = 0, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct usb_port_power_switch_data smsc_hub_port_data = { + .hub_tier = 1, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct power_controller pc = { + .name = omap_hub_eth_pc, + .count = ATOMIC_INIT(0), + .power_on = ehci_hub_power_on, + .power_off = ehci_hub_power_off, +}; + +static inline int omap_ehci_hub_port(struct device *dev) +{ + /* we expect dev-parent points to ehcd controller */ + if (dev-parent !strcmp(dev_name(dev-parent), ehci-omap.0)) + return 1; + return 0; +} + +static inline int dev_pc_match(struct device *dev) +{ + struct device *anc; + int ret = 0; + + if (likely(strcmp(dev_name(dev), port1))) + goto exit; + + if (dev-parent (anc = dev-parent-parent)) { + if (omap_ehci_hub_port(anc)) { + ret = 1; + goto exit; + } + + /* is it port of lan95xx hub? */ + if ((anc = anc-parent) omap_ehci_hub_port(anc)) { + ret = 2; + goto exit; + } + } +exit: + return ret; +} + +/* + * Notifications of device registration + */ +static int device_notify(struct notifier_block *nb, unsigned long action, void *data) +{ + struct device *dev = data; + int ret; + + switch (action) { + case DEV_NOTIFY_ADD_DEVICE: + ret = dev_pc_match(dev); + if (likely(!ret)) + goto exit; + if (ret == 1) + dev_pc_bind(pc, dev, root_hub_port_data, sizeof(root_hub_port_data)); + else + dev_pc_bind(pc, dev, smsc_hub_port_data, sizeof(smsc_hub_port_data)); + break; + + case DEV_NOTIFY_DEL_DEVICE: + break; + } +exit: + return 0; +} + +static struct notifier_block usb_port_nb = { + .notifier_call = device_notify, +}; + Some thoughts on trying to make this functionality specific to power only and ehci hub port only: - Quite a few boards have smsc95xx... they're all going to carry these additions in the board file? Surely you'll have to generalize the pieces All things are board dependent because we are discussing peripheral device(not builtin SoC devices), so it is proper to put it in the board file. If some boards want to share it, we can put it in a single .c file and let board file include it. Where would the .c file go... SMSC is not platform, or even arch specific chip (eg, iMX or MIPS or even x86 boards can have it), so not arch/arm/mach- or arch/arm/plat-xxx or arch/arm. I guess it would go in drivers/usb or drivers/net. How does drivers/usb or drivers/net know the SMSC is used on beagle or panda? Different power control approach is used in the two boards even same SMSC chip is shipped in the two boards. You mention you're going to put it in a single .c file and let the board file include it, I am just wondering where that .c file will live. It seems it would have to live down drivers/ somewhere so MIPS, x86 etc that might have an SMSC chip onboard can also use it if they want. Push in ARM-Land is towards single kernels which support many platforms, a good case in point is omap2plus_defconfg which wants to allow to support all OMAP2/3/4/5 platforms in one kernel. If you include that C file over and over in board files, it's not very nice for that. They anyway want to eliminate board files for the single kernel binary reason, and just have one load of config come in by dtb. I only mean it is reasonable to put the power control code into board file because each board may take different power control approach even same SMSC chip is used. I understand DT only describes the difference of the board via device node, and I am not sure if the current DT is enough to convert the board file into data as far as the problem is concerned. No the approach with DT is to provide a dummy SoC board file with all data provided by dtb. This is already established, see ./arch/arm/mach-omap2/board-generic.c for example. You can see there's nothing in it other than minimum dt match business. People with new boards are getting pointed at that and told to sort it out in dtb and disallowed from creating new board files. So whatever support or helper scheme you're adding needs a story about how dtb can
Re: [RFC PATCH 1/5] Device Power: introduce power controller
On 02/12/12 23:01, the mail apparently from Ming Lei included: Power controller is an abstract on simple power on/off switch. One power controller can bind to more than one device, which provides power logically, for example, we can think one usb port in hub provides power to the usb device attached to the port, even though the power is supplied actually by other ways, eg. the usb hub is a self-power device. From hardware view, more than one device can share one power domain, and power controller can power on if one of these devices need to provide power, and power off if all these devices don't need to provide power. What stops us using struct regulator here? If you have child regulators supplied by a parent supply, isn't that the right semantic already without introducing a whole new thing? Apologies if I missed the point. -Andy Cc: Rafael J. Wysocki r...@sisk.pl Cc: Andy Green andy.gr...@linaro.org Cc: Roger Quadros rog...@ti.com Cc: Alan Stern st...@rowland.harvard.edu Cc: Felipe Balbi ba...@ti.com Signed-off-by: Ming Lei tom.leim...@gmail.com --- drivers/base/power/Makefile |1 + drivers/base/power/power_controller.c | 110 + include/linux/power_controller.h | 48 ++ kernel/power/Kconfig |6 ++ 4 files changed, 165 insertions(+) create mode 100644 drivers/base/power/power_controller.c create mode 100644 include/linux/power_controller.h diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index 2e58ebb..c08bfc9 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_PM_TRACE_RTC) += trace.o obj-$(CONFIG_PM_OPP) += opp.o obj-$(CONFIG_PM_GENERIC_DOMAINS) += domain.o domain_governor.o obj-$(CONFIG_HAVE_CLK)+= clock_ops.o +obj-$(CONFIG_POWER_CONTROLLER) += power_controller.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/power/power_controller.c b/drivers/base/power/power_controller.c new file mode 100644 index 000..d7671fb --- /dev/null +++ b/drivers/base/power/power_controller.c @@ -0,0 +1,110 @@ +#include linux/init.h +#include linux/kernel.h +#include linux/power_controller.h +#include linux/slab.h +#include linux/err.h +#include linux/export.h + +static DEFINE_MUTEX(pc_lock); + +static void pc_devm_release(struct device *dev, void *res) +{ +} + +static int pc_devm_match(struct device *dev, void *res, void *match_data) +{ + struct pc_dev_data *data = res; + + return (data-magic == (unsigned long)pc_devm_release); +} + +static struct pc_dev_data *dev_pc_data(struct device *dev) +{ + struct pc_dev_data *data; + + data = devres_find(dev, pc_devm_release, pc_devm_match, NULL); + return data; +} + +static int pc_add_devm_data(struct device *dev, struct power_controller *pc, + void *dev_data, int dev_data_size) +{ + struct pc_dev_data *data; + int ret = 0; + + mutex_lock(pc_lock); + + /* each device should only have one power controller resource */ + data = dev_pc_data(dev); + if (data) { + ret = 1; + goto exit; + } + + data = devres_alloc(pc_devm_release, sizeof(struct pc_dev_data) + + dev_data_size, GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto exit; + } + + data-magic = (unsigned long)pc_devm_release; + data-pc = pc; + data-dev_data = data[1]; + memcpy(data-dev_data, dev_data, dev_data_size); + devres_add(dev, data); + +exit: + mutex_unlock(pc_lock); + return ret; +} + +static struct power_controller *dev_pc(struct device *dev) +{ + struct pc_dev_data *data = dev_pc_data(dev); + + if (data) + return data-pc; + return NULL; +} + +struct pc_dev_data *dev_pc_get_data(struct device *dev) +{ + struct pc_dev_data *data = dev_pc_data(dev); + return data; +} +EXPORT_SYMBOL(dev_pc_get_data); + +int dev_pc_bind(struct power_controller *pc, struct device *dev, + void *dev_data, int dev_data_size) +{ + return pc_add_devm_data(dev, pc, dev_data, dev_data_size); +} +EXPORT_SYMBOL(dev_pc_bind); + +void dev_pc_unbind(struct power_controller *pc, struct device *dev) +{ +} +EXPORT_SYMBOL(dev_pc_unbind); + +void dev_pc_power_on(struct device *dev) +{ + struct power_controller *pc = dev_pc(dev); + + if (!pc)return; + + if (atomic_inc_return(pc-count) == 1) + pc-power_on(pc, dev); +} +EXPORT_SYMBOL(dev_pc_power_on); + +void dev_pc_power_off(struct device *dev) +{ + struct power_controller *pc = dev_pc(dev); + + if (!pc)return; + + if (!atomic_dec_return(pc-count)) + pc-power_off(pc, dev); +} +EXPORT_SYMBOL(dev_pc_power_off); diff --git a/include/linux/power_controller.h b/include/linux/power_controller.h new file
Re: [RFC PATCH 2/5] driver core: introduce global device ADD/DEL notifier
On 02/12/12 23:01, the mail apparently from Ming Lei included: The global device ADD/DEL notifier is introduced so that some platform code can bind some device resource to the device. When this platform code runs, there is no any bus information about the device, so have to resort to the global notifier. Cc: Andy Green andy.gr...@linaro.org Cc: Roger Quadros rog...@ti.com Cc: Alan Stern st...@rowland.harvard.edu Cc: Felipe Balbi ba...@ti.com Signed-off-by: Ming Lei tom.leim...@gmail.com --- drivers/base/core.c| 21 + include/linux/device.h | 13 + 2 files changed, 34 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index a235085..37f11ff 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -43,6 +43,9 @@ static __init int sysfs_deprecated_setup(char *arg) early_param(sysfs.deprecated, sysfs_deprecated_setup); #endif +/* global device nofifier */ +struct blocking_notifier_head dev_notifier; + int (*platform_notify)(struct device *dev) = NULL; int (*platform_notify_remove)(struct device *dev) = NULL; static struct kobject *dev_kobj; @@ -1041,6 +1044,8 @@ int device_add(struct device *dev) if (platform_notify) platform_notify(dev); + blocking_notifier_call_chain(dev_notifier, DEV_NOTIFY_ADD_DEVICE, dev); + error = device_create_file(dev, uevent_attr); if (error) goto attrError; @@ -1228,6 +1233,7 @@ void device_del(struct device *dev) device_pm_remove(dev); driver_deferred_probe_del(dev); + blocking_notifier_call_chain(dev_notifier, DEV_NOTIFY_DEL_DEVICE, dev); /* Notify the platform of the removal, in case they * need to do anything... */ @@ -1376,6 +1382,8 @@ struct device *device_find_child(struct device *parent, void *data, int __init devices_init(void) { + BLOCKING_INIT_NOTIFIER_HEAD(dev_notifier); + devices_kset = kset_create_and_add(devices, device_uevent_ops, NULL); if (!devices_kset) return -ENOMEM; @@ -1995,6 +2003,19 @@ int dev_printk(const char *level, const struct device *dev, } EXPORT_SYMBOL(dev_printk); +/* The notifier should be avoided as far as possible */ +int dev_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(dev_notifier, nb); +} +EXPORT_SYMBOL_GPL(dev_register_notifier); + +int dev_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(dev_notifier, nb); +} +EXPORT_SYMBOL_GPL(dev_unregister_notifier); + #define define_dev_printk_level(func, kern_level) \ int func(const struct device *dev, const char *fmt, ...) \ { \ diff --git a/include/linux/device.h b/include/linux/device.h index 43dcda9..aeb54f6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -179,6 +179,19 @@ extern int bus_unregister_notifier(struct bus_type *bus, #define BUS_NOTIFY_UNBOUND_DRIVER 0x0006 /* driver is unbound from the device */ +/* All 2 notifers below get called with the target struct device * + * as an argument. Note that those functions are likely to be called + * with the device lock held in the core, so be careful. + */ +#define DEV_NOTIFY_ADD_DEVICE 0x0001 /* device added */ +#define DEV_NOTIFY_DEL_DEVICE 0x0002 /* device removed */ +extern int dev_register_notifier(struct notifier_block *nb); +extern int dev_unregister_notifier(struct notifier_block *nb); + +extern struct kset *bus_get_kset(struct bus_type *bus); +extern struct klist *bus_get_device_klist(struct bus_type *bus); + + extern struct kset *bus_get_kset(struct bus_type *bus); extern struct klist *bus_get_device_klist(struct bus_type *bus); Device de/registraton time is not necessarily a good choice for the notification point. At boot time, platform_devices may be being registered with no sign of driver and anything getting enabled in the notifier without further filtering (at each notifier...) will then always be enabled the whole session whether in use or not. probe() and remove() are more interesting because at that point the driver is present and we're definitely instantiating the thing or finished with its instantiation, and it's valid for non-usb devices too. In the one case you're servicing in the series, usb hub port, the device is very unusual in that it has no driver. However if you're going to add a global notifier in generic device code, you should have it do the right thing for normal device case so other people can use it... how I solved this for hub port was to simply normalize hub port by introducing a stub driver for it, so you get a probe / remove like anything else. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 02/12/12 23:01, the mail apparently from Ming Lei included: Hi - This patch defines power controller for powering on/off LAN95xx USB hub and USB ethernet devices, and implements one match function to associate the power controller with related USB port device. The big problem of this approach is that it depends on the global device ADD/DEL notifier. Another idea of associating power controller with port device is by introducing usb port driver, and move all this port power control stuff from platform code to the port driver, which is just what I think of and looks doable. The problem of the idea is that port driver is per board, so maybe cause lots of platform sort of code to be put under drivers/usb/port/, but this approach can avoid global device ADD/DEL notifier. I'd like to get some feedback about which one is better or other choice, then I may do it in next cycle. Cc: Andy Green andy.gr...@linaro.org Cc: Roger Quadros rog...@ti.com Cc: Alan Stern st...@rowland.harvard.edu Cc: Felipe Balbi ba...@ti.com Signed-off-by: Ming Lei tom.leim...@gmail.com --- arch/arm/mach-omap2/board-omap4panda.c | 99 +++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 5c8e9ce..3183832 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,6 +32,8 @@ #include linux/usb/musb.h #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include linux/power_controller.h +#include linux/usb/port.h #include asm/hardware/gic.h #include asm/mach-types.h @@ -154,6 +156,99 @@ static struct gpio panda_ehci_gpios[] __initdata = { { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, hub_nreset }, }; +static void ehci_hub_power_on(struct power_controller *pc, struct device *dev) +{ + gpio_set_value(GPIO_HUB_NRESET, 1); + gpio_set_value(GPIO_HUB_POWER, 1); +} You should wait a bit after applying power to the smsc chip before letting go of nReset too. In the regulator-based implementation I sent it's handled by delays encoded in the regulator structs. +static void ehci_hub_power_off(struct power_controller *pc, struct device *dev) +{ + gpio_set_value(GPIO_HUB_NRESET, 0); + gpio_set_value(GPIO_HUB_POWER, 0); +} + +static struct usb_port_power_switch_data root_hub_port_data = { + .hub_tier = 0, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct usb_port_power_switch_data smsc_hub_port_data = { + .hub_tier = 1, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct power_controller pc = { + .name = omap_hub_eth_pc, + .count = ATOMIC_INIT(0), + .power_on = ehci_hub_power_on, + .power_off = ehci_hub_power_off, +}; + +static inline int omap_ehci_hub_port(struct device *dev) +{ + /* we expect dev-parent points to ehcd controller */ + if (dev-parent !strcmp(dev_name(dev-parent), ehci-omap.0)) + return 1; + return 0; +} + +static inline int dev_pc_match(struct device *dev) +{ + struct device *anc; + int ret = 0; + + if (likely(strcmp(dev_name(dev), port1))) + goto exit; + + if (dev-parent (anc = dev-parent-parent)) { + if (omap_ehci_hub_port(anc)) { + ret = 1; + goto exit; + } + + /* is it port of lan95xx hub? */ + if ((anc = anc-parent) omap_ehci_hub_port(anc)) { + ret = 2; + goto exit; + } + } +exit: + return ret; +} + +/* + * Notifications of device registration + */ +static int device_notify(struct notifier_block *nb, unsigned long action, void *data) +{ + struct device *dev = data; + int ret; + + switch (action) { + case DEV_NOTIFY_ADD_DEVICE: + ret = dev_pc_match(dev); + if (likely(!ret)) + goto exit; + if (ret == 1) + dev_pc_bind(pc, dev, root_hub_port_data, sizeof(root_hub_port_data)); + else + dev_pc_bind(pc, dev, smsc_hub_port_data, sizeof(smsc_hub_port_data)); + break; + + case DEV_NOTIFY_DEL_DEVICE: + break; + } +exit: + return 0; +} + +static struct notifier_block usb_port_nb = { + .notifier_call = device_notify, +}; + Some thoughts on trying to make this functionality specific to power only and ehci hub port only: - Quite a few boards have smsc95xx... they're all going to carry these additions in the board file? Surely you'll have to generalize the pieces that perform device_path business out of the omap4panda board file at least. At that point the path matching code becomes generic end-of-the-device
Re: [RFC PATCH 4/5] arm: omap2: support port power on lan95xx devices
On 03/12/12 12:11, the mail apparently from Ming Lei included: On Mon, Dec 3, 2012 at 12:37 AM, Andy Green andy.gr...@linaro.org wrote: On 02/12/12 23:01, the mail apparently from Ming Lei included: Hi - This patch defines power controller for powering on/off LAN95xx USB hub and USB ethernet devices, and implements one match function to associate the power controller with related USB port device. The big problem of this approach is that it depends on the global device ADD/DEL notifier. Another idea of associating power controller with port device is by introducing usb port driver, and move all this port power control stuff from platform code to the port driver, which is just what I think of and looks doable. The problem of the idea is that port driver is per board, so maybe cause lots of platform sort of code to be put under drivers/usb/port/, but this approach can avoid global device ADD/DEL notifier. I'd like to get some feedback about which one is better or other choice, then I may do it in next cycle. Cc: Andy Green andy.gr...@linaro.org Cc: Roger Quadros rog...@ti.com Cc: Alan Stern st...@rowland.harvard.edu Cc: Felipe Balbi ba...@ti.com Signed-off-by: Ming Lei tom.leim...@gmail.com --- arch/arm/mach-omap2/board-omap4panda.c | 99 +++- 1 file changed, 96 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 5c8e9ce..3183832 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,6 +32,8 @@ #include linux/usb/musb.h #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include linux/power_controller.h +#include linux/usb/port.h #include asm/hardware/gic.h #include asm/mach-types.h @@ -154,6 +156,99 @@ static struct gpio panda_ehci_gpios[] __initdata = { { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, hub_nreset }, }; +static void ehci_hub_power_on(struct power_controller *pc, struct device *dev) +{ + gpio_set_value(GPIO_HUB_NRESET, 1); + gpio_set_value(GPIO_HUB_POWER, 1); +} You should wait a bit after applying power to the smsc chip before letting go of nReset too. In the regulator-based implementation I sent it's handled by delays encoded in the regulator structs. It isn't a big thing about the discussion. If these code is only platform code, we can use gpio or regulator or other thing. Well, you need a delay there FYI. It's just a nit. +static void ehci_hub_power_off(struct power_controller *pc, struct device *dev) +{ + gpio_set_value(GPIO_HUB_NRESET, 0); + gpio_set_value(GPIO_HUB_POWER, 0); +} + +static struct usb_port_power_switch_data root_hub_port_data = { + .hub_tier = 0, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct usb_port_power_switch_data smsc_hub_port_data = { + .hub_tier = 1, + .port_number = 1, + .type = USB_PORT_CONNECT_TYPE_HARD_WIRED, +}; + +static struct power_controller pc = { + .name = omap_hub_eth_pc, + .count = ATOMIC_INIT(0), + .power_on = ehci_hub_power_on, + .power_off = ehci_hub_power_off, +}; + +static inline int omap_ehci_hub_port(struct device *dev) +{ + /* we expect dev-parent points to ehcd controller */ + if (dev-parent !strcmp(dev_name(dev-parent), ehci-omap.0)) + return 1; + return 0; +} + +static inline int dev_pc_match(struct device *dev) +{ + struct device *anc; + int ret = 0; + + if (likely(strcmp(dev_name(dev), port1))) + goto exit; + + if (dev-parent (anc = dev-parent-parent)) { + if (omap_ehci_hub_port(anc)) { + ret = 1; + goto exit; + } + + /* is it port of lan95xx hub? */ + if ((anc = anc-parent) omap_ehci_hub_port(anc)) { + ret = 2; + goto exit; + } + } +exit: + return ret; +} + +/* + * Notifications of device registration + */ +static int device_notify(struct notifier_block *nb, unsigned long action, void *data) +{ + struct device *dev = data; + int ret; + + switch (action) { + case DEV_NOTIFY_ADD_DEVICE: + ret = dev_pc_match(dev); + if (likely(!ret)) + goto exit; + if (ret == 1) + dev_pc_bind(pc, dev, root_hub_port_data, sizeof(root_hub_port_data)); + else + dev_pc_bind(pc, dev, smsc_hub_port_data, sizeof(smsc_hub_port_data)); + break; + + case DEV_NOTIFY_DEL_DEVICE: + break; + } +exit: + return 0; +} + +static struct notifier_block usb_port_nb = { + .notifier_call = device_notify, +}; + Some thoughts on trying to make this functionality specific to power only
Re: [RFC PATCH 1/5] drivers : introduce device_path api
to UDEV events from ehci-omap?) to emulate LAN9514 power-on/off. I do realize it would be cool to have it automatically toggle in kernel when we (de)power the hub but isn't that outside of scope of Linux USB implementation? The above solution isn't most optimal for Panda but it seems a design more consistent with what we already have. Or so do I think. Not sure why you think that's out of scope for USB when USB allows hubs to control port power. Hub port power state seems like the right thing to control the enablement of the stuff wired to the hub port afaics, it's a great indication if we transition a hub port from depowered to powered, even if that only has a logical effect rather than actually switching 5V, we can understand from that we should power + clock (+ anything else needed) the thing connected to the port then so it can be probed... it's definitely what is wanted. The device_asset stuff is able to do that and control similarly the lifecycle of arbitrary mux, clocks and regulators to go along with it, without contaminiating the hub driver (except with 2 calls to work around the fact that hub port devices have no driver). The power domain stuff will also work, but only as far as hooking up the regulator and not the clock and mux stuff. If there's a plan to allow to bind clocks and mux to a regulator, well, OK you can do it all that way, gluing it together by magic names for the power domain assets. Anyway there's a lot of angles to it, the device_asset technique is powerful and will definitely solve out of band prerequisites setup nicely without involving the driver. But I can't say I can see deep enough into the other considerations (especially other subsystems understanding all this thinking) that just trying to solve the regulator angle with a power domain is wrong. However it won't properly solve even the Panda case by itself as well as device_asset - external clock will stay permanently up and the forest of mux code - it's code, not tables - in mach-omap2 will stay as a _init one-off. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [try#1 PATCH 5/7] omap4: panda: add smsc95xx regulator and reset dependent on root hub
On 11/30/2012 01:57 AM, the mail apparently from Alan Stern included: On Thu, 29 Nov 2012, Andy Green wrote: However I think what you're saying about binding to hub power is good. The hub ports are not devices, but it would be possible to bind an asset array to them and make the pre- and post- code functions. In the 3.6 kernel, hub ports are not devices. In 3.7 they are -- that is, each hub port has its own struct device. Right, I should have seen this in hub.c before. It's much better like that. I think it will be possible to address objections around the pathiness by being able to seed the path match with a platform_device pointer (there exists in the board file time a platform_device for ehci-omap.0 ...) and just matching the remainder on a single usb device's name, like *-1.1-1. Can you think of a way to do this without checking for a match every time a new device is registered? For instance, in this case it would be preferable to do this match only for descendants of ehci-omap.0. To match the port device, the string would have to be something like *-0:1.0/port2. Yes. How about adding a third callback to struct device_asset, along the lines of int (*pre_child_register)(struct device *child); then, in register_device() we add code that before we get down to it, we walk up the new device's parents calling -pre_child_register() on any assets the parents may have. In the typical case that's a rapid NOP once per device registration. However... if we had arranged back at boot time that the ehci-omap.0 struct device had an asset with only pre_device_register callback set, we can use that asset's .name for the right-justified child device name we are looking for like -0:1.0/port2, and its .asset member to point to another asset table the pre_child_register callback will attach to the child device if the name matches. So in the board file: struct device_asset ehci_omap0_smsc_hub_port_assets[] = { /* the smsc regulator and clock assets destined for the hub port */ { } }; /* below is attached to ehci-omap.0 like in try#1 */ struct device_asset ehci_omap0_assets[] = { { .name = -0:1.0/port2, .asset = ehci_omap0_smsc_hub_port_assets, .pre_child_register = device_asset_attach_to_child, }, { } }; In that way we can project as many stashed asset tables on to dynamically probed devices as we like from the platform_devices at boot time. Only children of the right platform devices do any checking or processing. In fact, if the match were anchored at the end of the string, we wouldn't need the wildcard at all -- at least, not in this case. The string could simply be -0:1.0/port2. But that's only if the match is restricted to devices below ehci-omap.0. It's a good idea, it won't get fooled by a hub getting plugged there which has its own port2 either, the -0:1.0 bit will have been elaborated for the subsequent hub path and won't match. It may be neater to split out the device_asset callbacks to an ..._ops struct. struct device_asset_ops { int (*pre_probe)(struct device *device, struct device_asset *asset); void (*post_remove)(struct device *device, struct device_asset *asset); int (*pre_child_register)(struct device *child); }; struct device_asset { ... struct device_asset_ops *ops; }; that also lets us export and set one thing to select say regulator handler, instead of n callbacks that must match. Something else I think mux would be a great target for device_asset support. That way it could become normal for mux function to get set as part of the specific device instantiation, so if you know you have an 8-bit ULPI PHY that will be logically created by the platform_device, you can attach ULPI-mode mux config appropriate for your exact SoC as an asset to the platform_device. When the device is destroyed, balls can go back to safe mode and save power, and if the balls are muxed with other things again the right mux asset can be associated with that so it switches automagically according to what you are doing. That's a lot better than forcing them once at boot which is the current method. Are there any gotchas with that? -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [try#1 PATCH 5/7] omap4: panda: add smsc95xx regulator and reset dependent on root hub
On 11/30/2012 04:58 AM, the mail apparently from Andy Green included: On 11/30/2012 01:57 AM, the mail apparently from Alan Stern included: On Thu, 29 Nov 2012, Andy Green wrote: However I think what you're saying about binding to hub power is good. The hub ports are not devices, but it would be possible to bind an asset array to them and make the pre- and post- code functions. In the 3.6 kernel, hub ports are not devices. In 3.7 they are -- that is, each hub port has its own struct device. Right, I should have seen this in hub.c before. It's much better like that. I think it will be possible to address objections around the pathiness by being able to seed the path match with a platform_device pointer (there exists in the board file time a platform_device for ehci-omap.0 ...) and just matching the remainder on a single usb device's name, like *-1.1-1. Can you think of a way to do this without checking for a match every time a new device is registered? For instance, in this case it would be preferable to do this match only for descendants of ehci-omap.0. To match the port device, the string would have to be something like *-0:1.0/port2. Yes. How about adding a third callback to struct device_asset, along the lines of int (*pre_child_register)(struct device *child); then, in register_device() we add code that before we get down to it, we walk up the new device's parents calling -pre_child_register() on any assets the parents may have. In the typical case that's a rapid NOP once per device registration. However... if we had arranged back at boot time that the ehci-omap.0 struct device had an asset with only pre_device_register callback set, we can use that asset's .name for the right-justified child device name we are looking for like -0:1.0/port2, and its .asset member to point to another asset table the pre_child_register callback will attach to the child device if the name matches. So in the board file: struct device_asset ehci_omap0_smsc_hub_port_assets[] = { /* the smsc regulator and clock assets destined for the hub port */ { } }; /* below is attached to ehci-omap.0 like in try#1 */ struct device_asset ehci_omap0_assets[] = { { .name = -0:1.0/port2, .asset = ehci_omap0_smsc_hub_port_assets, .pre_child_register = device_asset_attach_to_child, }, { } }; In that way we can project as many stashed asset tables on to dynamically probed devices as we like from the platform_devices at boot time. Only children of the right platform devices do any checking or processing. In fact, if the match were anchored at the end of the string, we wouldn't need the wildcard at all -- at least, not in this case. The string could simply be -0:1.0/port2. But that's only if the match is restricted to devices below ehci-omap.0. It's a good idea, it won't get fooled by a hub getting plugged there which has its own port2 either, the -0:1.0 bit will have been elaborated for the subsequent hub path and won't match. It may be neater to split out the device_asset callbacks to an ..._ops struct. struct device_asset_ops { int (*pre_probe)(struct device *device, struct device_asset *asset); void (*post_remove)(struct device *device, struct device_asset *asset); int (*pre_child_register)(struct device *child); }; struct device_asset { ... struct device_asset_ops *ops; }; that also lets us export and set one thing to select say regulator handler, instead of n callbacks that must match. I have everything discussed above ready for a try#2, including the descendant matching stuff in separate patches. The code got a lot smaller and better with the _ops struct. The new code can attach the assets to the targeted hub port as discussed (using only -0:1.0/port1 and only checking ehci-omap.0 descendants at device_add() time), but the hub port device never probes, unless I missed the point it's because it actually never binds to a driver, it's a very unusual standalone logical device. If that's the case I could work around that by doing the probe() asset stuff at device_add() time if there's no driver name on the device, but actually I am not sure that's where we wanted to end up. Now we got so far as to succeed to associate regulator + clock assets to the logical hub port device, isn't it that we want the assets to be enabled and disabled according to hub port power state? In that case it needs to go in the direction of calling device_asset helpers in the hub.c code that handles enable and disable hub port power. Is this sounding like the right way, or something else? -Andy Something else I think mux would be a great target for device_asset support. That way it could become normal for mux function to get set as part of the specific device instantiation, so if you know you have an 8-bit ULPI PHY
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/28/2012 07:13 PM, the mail apparently from Roger Quadros included: On 11/27/2012 09:22 PM, Andy Green wrote: On 11/28/2012 02:09 AM, the mail apparently from Alan Stern included: On Wed, 28 Nov 2012, Andy Green wrote: Greg's advice was simply not to rely on pathnames in sysfs because they aren't fixed in stone. That leaves plenty of other ways to approach this problem. It's sage advice, but there is zero code provided in my patches that relies on pathnames in sysfs. In your 1/5 patch, _device_path_generate() concatenates device name strings, starting from a device root and separating elements with '/' characters. Isn't that the same as a sysfs pathname? It's nothing to do with sysfs... yes some unrelated bits of sysfs also walk the device path. If we want to talk about how fragile the device path is as an id scheme over time we need to talk about likelihood of individual device names changing, not sysfs. Anyway -- Basically, what you want is for something related to device A (the regulator or the GPIO) to happen whenever device B (the ehci-omap.0 platform device) is bound to a driver. The most straightforward way to arrange this is for A's driver to have a callback that is invoked whenever B is bound or unbound. The most straightforward way to arrange _that_ is to allow each platform_device to have a list of callbacks. Sorry I didn't really understand this proposal yet. You want A, the regulator, driver to grow a callback function that gets called when the targeted platform_device (B, ehci-omap.0) probe happens. Could you expand what the callback prototype or new members in the struct might look like? It's your tuple thing or we pass it an opaque pointer that is the struct regulator * or suchlike? Well, it won't be exactly the same as the tuple thing because no strings will be involved, but it would be similar. The callback would receive an opaque pointer (presumably to the regulator) and a device pointer (the B device). OK. So I try to sketch it out iteractively to try to get in sync: device.h: enum asset_event { AE_PROBED, AE_REMOVED }; struct device_asset { char *name; /* name of regulator, clock, etc */ void *asset; /* regulator, clock, etc */ int (*handler)(struct device *dev_owner, enum asset_event asset_event, struct device_asset *asset); }; struct device { ... struct device_asset *assets; ... }; drivers/base/dd.c | really_probe(): ... struct device_asset *asset; ... asset = dev-assets; while (asset asset-name) { if (asset-handler(dev, AE_PROBED, asset)) { /* clean up and bail */ } asset++; } /* do probe */ ... drivers/base/dd.c | __device_release_driver: (is this really the best place to oppose probe()?) ... struct device_asset *asset; ... /* call device -remove() */ ... asset = dev-assets; while (asset asset-name) { asset-handler(dev, AE_REMOVED, asset); asset++; } ... board file: static struct regulator myreg = { .name = mydevice-regulator, }; static struct device_asset mydevice_assets[] = { { .name = mydevice-regulator, .handler = regulator_default_asset_handler, }, { } }; static struct platform_device mydevice = { ... .dev = { .assets = mydevice_assets, }, ... }; From Pandaboard's point of view, is mydevice supposed to be referring to ehci-omap, LAN95xx or something else? Strictly speaking, the regulator doesn't belongs neither to ehci-omap nor LAN95xx. It belongs to a power domain on the board. And user should have control to switch it OFF when required without hampering operation of ehci-omap, so that the other USB ports are still usable. I'd prefer to deal with that after a try#1 with regulator, I didn't see any code about power domain in there right now. There's a lot to get consensus on already with this series. Notice that these assets are generic, I will provide clk and regulator handlers with try#1, and working examples for Panda case with both, but presumably power domain can fold into it as well. Since I am on usb-next and there's nothing to be seen about power domains, what is the situation with that support? -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[try#1 PATCH 0/7] Introduce device_asset and use to control Panda HUB+ETH power and clock
The following series implements the device_asset addition to struct device that has been discussed on the usb and omap lists with Alan Stern and GKH. Several of the ideas here are from Alan Stern. First we add the new struct to linux/device.h and cause it to be used just before device probe with one device_asset-specific callback to enable the assets and just after device removal with another device_asset-specific callback to disable the associated assets. Typical assets are things like regulators and clocks which are not known to the generic driver but which are bound to the specific device instance by hardware design. Second we provide stock, default device_asset callbacks if your asset is a struct regulator. You can just use those and the regulator will have a get and enable until the device instance is removed, when it will be disabled and put. Third we provide the same for struct clk. These stock callbacks mean there won't be any code duplication caused in the common case. Fourth we remove all the struct regulator code from ehci-omap. Fifth we implement Panda HUB+ETH (smsc95xx chip) regulator control using the device_asset scheme. Since the right device, ehci-omap.0 is created under mfd, the device_asset array is passed in platform_data to the right place where it's added to the platform_device's device before registration. Sixth we add the Panda's external ULPI PHY clock to the device_asset array we established for the regulator case above. The end result is we are able to remove the code about regulator and don't need any for clock control in the generic drivers. Instead we are able to associate the board-specific prerequisites for the drivers to work on a board externally with the enable and disable hidden in the plumbing. The end result is power and clock to the HUB+PHY (smsc95xx chip) remains off until ehci-hcd module is inserted, and both are disabled again when the module is removed. --- Andy Green (7): drivers: base: introduce device assets regulator: core: add default device asset handlers clk: add default device asset handlers usb: omap ehci: remove all regulator control from ehci omap omap4: panda: add smsc95xx regulator and reset dependent on root hub omap4 panda add smsc95xx clock dependent on root hub config omap2plus add ehci bits arch/arm/configs/omap2plus_defconfig | 42 +--- arch/arm/mach-omap2/board-omap4panda.c | 113 +++- arch/arm/mach-omap2/usb-host.c |2 - arch/arm/plat-omap/include/plat/usb.h |9 +-- drivers/base/dd.c | 36 ++ drivers/clk/clkdev.c | 39 +++ drivers/mfd/omap-usb-host.c|9 ++- drivers/regulator/core.c | 34 ++ drivers/usb/host/ehci-omap.c | 37 -- include/linux/clk.h| 33 + include/linux/device.h | 25 +++ include/linux/regulator/machine.h | 30 12 files changed, 303 insertions(+), 106 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[try#1 PATCH 1/7] drivers: base: introduce device assets
This patch adds support for a new struct device member assets which may point to an array of struct assets. The array is terminated by one with a NULL pre_probe callback. These assets consist of named (in .name) or anonymous object pointers (.data) operated on by specified callbacks. A void * is provided to give configuration data or pointer if needed. Before device probe, any assets associated with the device have their pre_probe() callback called, which will typically enable them, and after device removal the post_remove() callback is called which will typically disable them. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/base/dd.c | 36 include/linux/device.h | 25 + 2 files changed, 61 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index e3bbed8..d37210a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -261,6 +261,7 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); static int really_probe(struct device *dev, struct device_driver *drv) { + struct device_asset *asset; int ret = 0; atomic_inc(probe_count); @@ -275,6 +276,23 @@ static int really_probe(struct device *dev, struct device_driver *drv) goto probe_failed; } + asset = dev-assets; + while (asset asset-pre_probe) { + dev_info(dev, Enabling pre-probe asset %s\n, asset-name); + ret = asset-pre_probe(dev, asset); + if (ret) { + dev_err(dev, Error Enabling pre-probe asset %s\n, + asset-name); + if (asset != dev-assets) + do { + asset--; + asset-post_remove(dev, asset); + } while (asset != dev-assets); + goto probe_failed; + } + asset++; + } + if (dev-bus-probe) { ret = dev-bus-probe(dev); if (ret) @@ -478,6 +496,7 @@ EXPORT_SYMBOL_GPL(driver_attach); static void __device_release_driver(struct device *dev) { struct device_driver *drv; + struct device_asset *asset; drv = dev-driver; if (drv) { @@ -496,6 +515,23 @@ static void __device_release_driver(struct device *dev) dev-bus-remove(dev); else if (drv-remove) drv-remove(dev); + + asset = dev-assets; + if (asset) { + /* remove in reverse order */ + while (asset-pre_probe) + asset++; + + if (asset != dev-assets) + do { + asset--; + dev_info(dev, + Disabling post-remove asset %s\n, + asset-name); + asset-post_remove(dev, asset); + } while (asset != dev-assets); + } + devres_release_all(dev); dev-driver = NULL; dev_set_drvdata(dev, NULL); diff --git a/include/linux/device.h b/include/linux/device.h index 86ef6ab..6eabe1d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -577,6 +577,26 @@ struct device_dma_parameters { }; /** + * struct device_asset - a prerequisite for this device's probing + * @name: Name of the regulator, clock, etc. Optional. + * @asset: Pointer to the regulator, clock, etc. If no name is given, + * this can be set before device probe, otherwise the pre_probe + * handler will dereference the name and store a pointer here + * @data: Optional configuration data the asset may need + * @pre_probe: Called before this device this is associated with gets + * probed. + * @post_remove: Called after this device instance gets removed. + */ + +struct device_asset { + const char *name; + void *asset; + void *data; + int (*pre_probe)(struct device *device, struct device_asset *asset); + void (*post_remove)(struct device *device, struct device_asset *asset); +}; + +/** * struct device - The basic device structure * @parent:The device's parent device, the device to which it is attached. * In most cases, a parent device is some sort of bus or host @@ -600,6 +620,9 @@ struct device_dma_parameters { * variants, which GPIO pins act in what additional roles, and so * on. This shrinks the Board Support Packages (BSPs) and * minimizes board-specific #ifdefs in drivers. + * @assets:Pointer to a NULL-pre_probe terminated array
[try#1 PATCH 2/7] regulator: core: add default device asset handlers
This adds default device_asset handlers for struct regulator. If you want an associated regulator asset of a device to be powered before probe, and depowered after removal, these callbacks will take care of everything including get and put. By defining them here in regulator core, code duplication at the usages is nipped in the bud. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/regulator/core.c | 34 ++ include/linux/regulator/machine.h | 30 ++ 2 files changed, 64 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e872c8b..1834e41 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3495,6 +3495,40 @@ void regulator_unregister(struct regulator_dev *rdev) } EXPORT_SYMBOL_GPL(regulator_unregister); +/* + * Default handlers for regulator asset preprobe and postremoval + */ +int regulator_asset_default_preprobe(struct device *device, + struct device_asset *asset) +{ + struct regulator **reg = (struct regulator **)asset-asset; + int n; + + *reg = regulator_get(device, asset-name); + if (IS_ERR(*reg)) + return PTR_ERR(*reg); + n = regulator_enable(*reg); + if (n 0) + regulator_put(*reg); + + dev_info(device, Enabled regulator asset %s\n, asset-name); + + return n; +} +EXPORT_SYMBOL_GPL(regulator_asset_default_preprobe); + +void regulator_asset_default_postremove(struct device *device, + struct device_asset *asset) +{ + struct regulator *reg = asset-asset; + + dev_info(device, Disabling post-remove asset %s\n, asset-name); + + regulator_disable(reg); + regulator_put(reg); +} +EXPORT_SYMBOL_GPL(regulator_asset_default_postremove); + /** * regulator_suspend_prepare - prepare regulators for system wide suspend * @state: system suspend state diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 36adbc8..151a330 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -191,9 +191,39 @@ int regulator_suspend_prepare(suspend_state_t state); int regulator_suspend_finish(void); #ifdef CONFIG_REGULATOR +/** + * regulator_asset_default_preprobe: default probe handler for regulator assets + * @device:the device whose assets we are enabling just before probing it + * @asset: the named regulator asset we are going to get and enable + * + * You can give this as the handler for .pre_probe callback in device_asset to + * deal with pre-enabling/get of a device's named regulator assets + */ +int regulator_asset_default_preprobe(struct device *device, + struct device_asset *asset); +/** + * regulator_asset_default_postremove: default remove handler for reg assets + * @device:the device whose assets we are disabling just after removing it + * @asset: the regulator asset we are going to disable and put + * + * You can give this as the handler for .post_remove callback in device_asset + * to deal with post-disabling/put of a device's regulator assets + */ +void regulator_asset_default_postremove(struct device *device, + struct device_asset *asset); + void regulator_has_full_constraints(void); void regulator_use_dummy_regulator(void); #else +static inline int regulator_asset_default_preprobe(struct device *device, + struct device_asset *asset) +{ + return 0; +} +static inline void regulator_asset_default_postremove(struct device *device, + struct device_asset *asset) +{ +} static inline void regulator_has_full_constraints(void) { } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[try#1 PATCH 3/7] clk: add default device asset handlers
This adds default device_asset handlers for struct clk. If you want an associated clk asset of a device to be optionally set, and enabled before probe, and disabled after removal, these callbacks will take care of everything including get and put. By defining them here in regulator core, code duplication at the usages is nipped in the bud. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/clk/clkdev.c | 39 +++ include/linux/clk.h | 33 - 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 442a313..01d3fcd 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -327,3 +327,42 @@ int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) return 0; } EXPORT_SYMBOL(clk_register_clkdevs); + +/* + * Default handlers for clock asset preprobe and postremoval + */ +int clk_asset_default_preprobe(struct device *device, + struct device_asset *asset) +{ + struct clk **clk = (struct clk **)asset-asset; + int n; + + *clk = clk_get(device, asset-name); + if (IS_ERR(*clk)) + return PTR_ERR(*clk); + if (asset-data) { + n = clk_set_rate(*clk, (unsigned long)asset-data); + if (n 0) + goto bail; + } + n = clk_prepare_enable(*clk); + if (n 0) + goto bail; + + return 0; +bail: + clk_put(*clk); + + return n; +} +EXPORT_SYMBOL_GPL(clk_asset_default_preprobe); + +void clk_asset_default_postremove(struct device *device, + struct device_asset *asset) +{ + struct clk **clk = (struct clk **)asset-asset; + + clk_disable_unprepare(*clk); + clk_put(*clk); +} +EXPORT_SYMBOL_GPL(clk_asset_default_postremove); diff --git a/include/linux/clk.h b/include/linux/clk.h index b3ac22d..3956675 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -17,6 +17,7 @@ #include linux/notifier.h struct device; +struct device_asset; struct clk; @@ -276,6 +277,27 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); +/** + * clk_asset_default_preprobe: default probe handler for clock device assets + * @device:the device whose assets we are enabling just before probing it + * @asset: the clock asset we are going to get and enable + * + * You can give this as the handler for .pre_probe callback in device_asset to + * deal with pre-enabling/get of a device's clock assets + */ +int clk_asset_default_preprobe(struct device *device, + struct device_asset *asset); +/** + * clk_asset_default_postremove: default remove handler for clock device assets + * @device:the device whose assets we are disabling just after removing it + * @asset: the clock asset we are going to disable and put + * + * You can give this as the handler for .post_remove callback in device_asset + * to deal with post-disabling/put of a device's clock assets + */ +void clk_asset_default_postremove(struct device *device, + struct device_asset *asset); + #else /* !CONFIG_HAVE_CLK */ static inline struct clk *clk_get(struct device *dev, const char *id) @@ -323,7 +345,16 @@ static inline struct clk *clk_get_parent(struct clk *clk) { return NULL; } - +static inline int clk_asset_default_preprobe(struct device *device, + struct device_asset *asset) +{ + return 0; +} +static inline void clk_asset_default_postremove(struct device *device, + struct device_asset *asset) +{ +} +s #endif /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[try#1 PATCH 4/7] usb: omap ehci: remove all regulator control from ehci omap
This series migrates it to be assets of the logical ehci-omap.0 device object. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/usb-host.c|1 - arch/arm/plat-omap/include/plat/usb.h |7 -- drivers/usb/host/ehci-omap.c | 37 - 3 files changed, 45 deletions(-) diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 3c43449..98f3287 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -498,7 +498,6 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) ohci_data.port_mode[i] = pdata-port_mode[i]; ehci_data.port_mode[i] = pdata-port_mode[i]; ehci_data.reset_gpio_port[i] = pdata-reset_gpio_port[i]; - ehci_data.regulator[i] = pdata-regulator[i]; } ehci_data.phy_reset = pdata-phy_reset; ohci_data.es2_compatibility = pdata-es2_compatibility; diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h index 87ee140..70acdee 100644 --- a/arch/arm/plat-omap/include/plat/usb.h +++ b/arch/arm/plat-omap/include/plat/usb.h @@ -36,12 +36,6 @@ struct usbhs_omap_board_data { unsignedes2_compatibility:1; unsignedphy_reset:1; - - /* -* Regulators for USB PHYs. -* Each PHY can have a separate regulator. -*/ - struct regulator*regulator[OMAP3_HS_USB_PORTS]; }; #ifdef CONFIG_ARCH_OMAP2PLUS @@ -49,7 +43,6 @@ struct usbhs_omap_board_data { struct ehci_hcd_omap_platform_data { enum usbhs_omap_port_mode port_mode[OMAP3_HS_USB_PORTS]; int reset_gpio_port[OMAP3_HS_USB_PORTS]; - struct regulator*regulator[OMAP3_HS_USB_PORTS]; unsignedphy_reset:1; }; diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 44e7d0f..7ab7c54 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -40,7 +40,6 @@ #include linux/slab.h #include linux/usb/ulpi.h #include plat/usb.h -#include linux/regulator/consumer.h #include linux/pm_runtime.h #include linux/gpio.h #include linux/clk.h @@ -149,19 +148,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) return rc; } -static void disable_put_regulator( - struct ehci_hcd_omap_platform_data *pdata) -{ - int i; - - for (i = 0 ; i OMAP3_HS_USB_PORTS ; i++) { - if (pdata-regulator[i]) { - regulator_disable(pdata-regulator[i]); - regulator_put(pdata-regulator[i]); - } - } -} - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -175,14 +161,11 @@ static void disable_put_regulator( static int ehci_hcd_omap_probe(struct platform_device *pdev) { struct device *dev = pdev-dev; - struct ehci_hcd_omap_platform_data *pdata = dev-platform_data; struct resource *res; struct usb_hcd *hcd; void __iomem*regs; int ret = -ENODEV; int irq; - int i; - charsupply[7]; if (usb_disabled()) return -ENODEV; @@ -223,23 +206,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) hcd-rsrc_len = resource_size(res); hcd-regs = regs; - /* get ehci regulator and enable */ - for (i = 0 ; i OMAP3_HS_USB_PORTS ; i++) { - if (pdata-port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { - pdata-regulator[i] = NULL; - continue; - } - snprintf(supply, sizeof(supply), hsusb%d, i); - pdata-regulator[i] = regulator_get(dev, supply); - if (IS_ERR(pdata-regulator[i])) { - pdata-regulator[i] = NULL; - dev_dbg(dev, - failed to get ehci port%d regulator\n, i); - } else { - regulator_enable(pdata-regulator[i]); - } - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -261,11 +227,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) goto err_pm_runtime; } - return 0; err_pm_runtime: - disable_put_regulator(pdata); pm_runtime_put_sync(dev); usb_put_hcd(hcd); @@ -290,7 +254,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) struct ehci_hcd_omap_platform_data *pdata = dev-platform_data
[try#1 PATCH 5/7] omap4: panda: add smsc95xx regulator and reset dependent on root hub
This adds regulators which are controlled by the OMAP4 PandaBoard (ES)'s EHCI logical root hub existing. The regulators are made a device_asset of the EHCI logical root hub by passing them through the hsusb - mfd path. Although the ehci-related platform_device is created at boot time, it is not instantiated until the ehci-hcd module is inserted if it is modular. Since the regulator is an asset of the ehci-omap.0 device, it's turned on during successful probe and off when the device is removed. Without power control, the ULPI PHY + SMSC9614 on the Panda eats 700-900mW all the time, which is around the same as the idle power of the SoC and rest of the board. This allows us to start off with it depowered, and only power it if the ehci-hcd module is inserted. When the module is removed, it's depowered again. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/board-omap4panda.c | 100 ++-- arch/arm/mach-omap2/usb-host.c |1 arch/arm/plat-omap/include/plat/usb.h |2 + drivers/mfd/omap-usb-host.c|9 ++- 4 files changed, 89 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index bfcd397..52add03 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -144,6 +144,15 @@ static struct platform_device *panda_devices[] __initdata = { btwilink_device, }; +static struct device_asset assets_ehci_omap0[] = { + { + .name = reg-panda-smsc95xx, + .pre_probe = regulator_asset_default_preprobe, + .post_remove = regulator_asset_default_postremove, + }, + { } +}; + static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED, @@ -151,12 +160,8 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .phy_reset = false, .reset_gpio_port[0] = -EINVAL, .reset_gpio_port[1] = -EINVAL, - .reset_gpio_port[2] = -EINVAL -}; - -static struct gpio panda_ehci_gpios[] __initdata = { - { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, hub_power }, - { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, hub_nreset }, + .reset_gpio_port[2] = -EINVAL, + .assets = assets_ehci_omap0, }; static void __init omap4_ehci_init(void) @@ -173,23 +178,76 @@ static void __init omap4_ehci_init(void) clk_set_rate(phy_ref_clk, 1920); clk_prepare_enable(phy_ref_clk); - /* disable the power to the usb hub prior to init and reset phy+hub */ - ret = gpio_request_array(panda_ehci_gpios, -ARRAY_SIZE(panda_ehci_gpios)); - if (ret) { - pr_err(Unable to initialize EHCI power/reset\n); - return; - } + usbhs_init(usbhs_bdata); +} - gpio_export(GPIO_HUB_POWER, 0); - gpio_export(GPIO_HUB_NRESET, 0); - gpio_set_value(GPIO_HUB_NRESET, 1); +/* + * hub_nreset also resets the ULPI PHY and is required after powering SMSC chip + * ULPI PHY is always powered... need to do reset once for both once + * hub_power enables a 3.3V regulator for (hub + eth) chip + * however there's no point having ULPI PHY in use alone + * since it's only connected to the (hub + eth) chip + */ - usbhs_init(usbhs_bdata); +static struct regulator_init_data panda_hub = { + .constraints = { + .name = vhub, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; - /* enable power to hub */ - gpio_set_value(GPIO_HUB_POWER, 1); -} +static struct fixed_voltage_config panda_vhub = { + .supply_name = vhub, + .microvolts = 330, + .gpio = GPIO_HUB_POWER, + .startup_delay = 7, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = panda_hub, +}; + +static struct platform_device omap_vhub_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = panda_vhub, + }, +}; + +static struct regulator_init_data panda_ulpireset = { + /* +* idea is that when operating ulpireset, regulator api will make +* sure that the hub+eth chip is powered, since it's the parent +*/ + .supply_regulator = vhub, /* we are a child of vhub */ + .constraints = { + /* +* this magic string associates us with ehci-omap.0 root hub +* when the root hub logical device is up, we will power +* and reset [ ULPI PHY + [ HUB + ETH ] ] +*/ + .name = reg-panda-smsc95xx, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct fixed_voltage_config panda_vulpireset = { + .supply_name = reg
[try#1 PATCH 6/7] omap4 panda add smsc95xx clock dependent on root hub
This patch makes the ULPI PHY clock control also be a device_asset of the ehci-omap.0 device, along with the [HUB + ETH] smsc95xx chip power regulator. Without clock control, the PHY clock is running all the time from boot whether USB is in use or not, and during suspend distorting power measurements there. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/board-omap4panda.c | 25 +++-- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 52add03..97489c7 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -150,6 +150,12 @@ static struct device_asset assets_ehci_omap0[] = { .pre_probe = regulator_asset_default_preprobe, .post_remove = regulator_asset_default_postremove, }, + { + .name = auxclk3_ck, + .data = (void *)1920, + .pre_probe = clk_asset_default_preprobe, + .post_remove = clk_asset_default_postremove, + }, { } }; @@ -164,23 +170,6 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .assets = assets_ehci_omap0, }; -static void __init omap4_ehci_init(void) -{ - int ret; - struct clk *phy_ref_clk; - - /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */ - phy_ref_clk = clk_get(NULL, auxclk3_ck); - if (IS_ERR(phy_ref_clk)) { - pr_err(Cannot request auxclk3\n); - return; - } - clk_set_rate(phy_ref_clk, 1920); - clk_prepare_enable(phy_ref_clk); - - usbhs_init(usbhs_bdata); -} - /* * hub_nreset also resets the ULPI PHY and is required after powering SMSC chip * ULPI PHY is always powered... need to do reset once for both once @@ -567,7 +556,7 @@ static void __init omap4_panda_init(void) omap_serial_init(); omap_sdrc_init(NULL, NULL); omap4_twl6030_hsmmc_init(mmc); - omap4_ehci_init(); + usbhs_init(usbhs_bdata); usb_musb_init(musb_board_data); omap4_panda_display_init(); } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[try#1 PATCH 7/7] config omap2plus add ehci bits
omap2plus seems to have rotted a bit, this is the delta that appears if we enable modular build for ehci-hcd and smsc95xx. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/configs/omap2plus_defconfig | 42 ++ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 6230304..2f858a3 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -1,14 +1,14 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,16 +20,15 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_OMAP=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y +CONFIG_SOC_OMAP5=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 -CONFIG_LEDS=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE=root=/dev/mmcblk0p2 rootwait console=ttyO2,115200 @@ -87,22 +86,21 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y -CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_DEBUG=y CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -132,14 +130,13 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y -CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y @@ -154,7 +151,6 @@ CONFIG_PANEL_ACX565AKM=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -174,13 +170,15 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=m CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_USB_TEST=y +CONFIG_OMAP_USB2=m CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y CONFIG_USB_GADGET_DEBUG_FILES=y @@ -214,23 +212,18 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set @@ -239,4 +232,3 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_LIBCRC32C=y -CONFIG_SOC_OMAP5=y -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [try#1 PATCH 5/7] omap4: panda: add smsc95xx regulator and reset dependent on root hub
On 11/28/2012 11:06 PM, the mail apparently from Roger Quadros included: Hi Roger - On 11/28/2012 02:59 PM, Andy Green wrote: This adds regulators which are controlled by the OMAP4 PandaBoard (ES)'s EHCI logical root hub existing. The regulators are made a device_asset of the EHCI logical root hub by passing them through the hsusb - mfd path. Although the ehci-related platform_device is created at boot time, it is not instantiated until the ehci-hcd module is inserted if it is modular. Since the regulator is an asset of the ehci-omap.0 device, it's turned on during successful probe and off when the device is removed. Without power control, the ULPI PHY + SMSC9614 on the Panda eats 700-900mW all the time, which is around the same as the idle power of the SoC and rest of the board. This allows us to start off with it depowered, and only power it if the ehci-hcd module is inserted. When the module is removed, it's depowered again. ... diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 98f3287..2a0fdf9 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -501,6 +501,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata) } ehci_data.phy_reset = pdata-phy_reset; ohci_data.es2_compatibility = pdata-es2_compatibility; + ehci_data.assets = pdata-assets; Just wondering if it makes more sense to tie the regulator and clock assets on the Panda to LAN95xx platform device instead of ehci_omap's platform device. The only thing we need to do is add a dummy platform device for the LAN9xx chip and probe it in the smsc9xx driver. The benefit of this is we can choose to power up/down the LAN9xx device by insmod/rmmod smsc0xx driver and still have other OMAP USB ports functional. what do you think? I think it's cool but I am not sure it hangs together. Just to make sure we're on the same page, the LAN95XX platform device doesn't exist at the moment, right? With hsusb mfd - ehci the platform device can be made from boot because the memory-mapped hardware is always there. As soon as the driver appears, it can be probed and made into a real live device and everything is straight. But when the platform_device would represent a usb device, that's not quite the same. AIUI the usb stack only creates the device when it has probed a vid:pid and identified a driver that claims to serve it. If the power for the HUB+ETH was controlled by an asset on the probe for the HUB+ETH device, isn't that never going to happen? The usb stack can't see the vid+pid for smsc95xx device until we give it power (it's connected but off), in this scheme we don't give it power until something ran probe for an smsc95xx device? There's another quirk on Panda that makes trouble too, after enabling power on the HUB+ETH chip, we must reset it. But the same reset signal resets the ULPI PHY too. So if the powering deadlock was solved we would still run into a problem where we caused ULPI errors bringing up the smsc95xx, if ehci+ULPI was already going. It's a violation of the independence of the ULPI and [usb device on other side of ulpi] caused by the Panda design using the same reset signal. That is why the current approach gets power + reset over with once at the time we would anyway want to reset the ULPI PHY. However I think what you're saying about binding to hub power is good. The hub ports are not devices, but it would be possible to bind an asset array to them and make the pre- and post- code functions. But AFAIK neither that, nor the platform_device idea for smsc95xx even get off the ground without a device_path type addressing scheme, because you are targeting from the board file specific logical devices that only exist later after other probes. I think it will be possible to address objections around the pathiness by being able to seed the path match with a platform_device pointer (there exists in the board file time a platform_device for ehci-omap.0 ...) and just matching the remainder on a single usb device's name, like *-1.1-1. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/28/2012 12:37 AM, the mail apparently from Alan Stern included: On Tue, 27 Nov 2012, Andy Green wrote: I don't know if such an approach would be sufficiently general for future requirements, but it would solve the problem at hand. We can get a notification about device creation and do things there. But the cost of that is like the tuple suggestion, they'll only be able to do a fixed thing like operate on regulators. I'm not quite sure what you mean by that. _Any_ function is capable of doing only a fixed thing. Actually the targeted device may have arbitrary associated assets like generic GPIO to turn on a flash for built-in webcam controlled out-of-band. These also can be reached by known names. And the driver may wish to do things with them that are more complex than enable / disable or follow logical lifecycle of the hub or whatever. Let's worry about that when it arises. However when the guidance from Greg is that we can do nothing except complain at hardware designers for some reason I failed to quite identify, I fear we are moving deckchairs on the titanic. Greg's advice was simply not to rely on pathnames in sysfs because they aren't fixed in stone. That leaves plenty of other ways to approach this problem. It's sage advice, but there is zero code provided in my patches that relies on pathnames in sysfs. Basically, what you want is for something related to device A (the regulator or the GPIO) to happen whenever device B (the ehci-omap.0 platform device) is bound to a driver. The most straightforward way to arrange this is for A's driver to have a callback that is invoked whenever B is bound or unbound. The most straightforward way to arrange _that_ is to allow each platform_device to have a list of callbacks. Sorry I didn't really understand this proposal yet. You want A, the regulator, driver to grow a callback function that gets called when the targeted platform_device (B, ehci-omap.0) probe happens. Could you expand what the callback prototype or new members in the struct might look like? It's your tuple thing or we pass it an opaque pointer that is the struct regulator * or suchlike? Throwing out the path stuff and limiting this to platform_device means you cannot bind to dynamically created objects like hub or anything downstream of a hub. So Felipe's identification of the hub as the happening place to do this is out of luck. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/28/2012 01:22 AM, the mail apparently from Ming Lei included: On Wed, Nov 28, 2012 at 12:30 AM, Alan Stern st...@rowland.harvard.edu wrote: On Tue, 27 Nov 2012, Ming Lei wrote: IMO, all matches mean the devices are inside the ehci-omap bus, so the direct/simple way is to enable/disable the regulators in the probe() and remove() of ehci-omap controller driver. When this discussion started, Felipe argued against such an approach. He pointed out that the same chip could be used in other platforms, and then the code added to ehci-omap.c would have to be duplicated in several other places. From Andy's implementation, the 'general' code is to enable/disable the regulators(patch 3/5), I am wondering if it is general enough, so the 'duplicated' code are just several lines of regulator_enable/regulator_disable, which should be implemented in many platform drivers. Fair enough; my main interest was in the device path side when writing the patches. I stuck enough in one place to confirm the series works on Panda case for power control. So long as it doesn't get obsessed with just regulators some common implementation that seems to be discussed will be better. (BTW let me take this opportunity to thank you for your great urbs-in-flight limiting patch on smsc95xx a while back) Also from my intuition, power domain should be involved in the problem, because these hard-wired and self-powered USB devices should have its own power domains, and the ehci-omap driver may enable/disable these power domains before adding the bus. I don't know enough to have an opinion, but the arrangement on Panda is literally a linear regulator is being controlled by a gpio, which fits into struct regulator model. What else would a power domain for that buy us? We should have a more generic solution in a more central location, like the device core. For example, each struct platform_device could have a list of resources to be enabled when the device is bound to a driver and disabled when the device is unbound. Such a list could include regulators, clocks, and whatever else people can invent. In this case, when it is created the ehci-omap.0 platform device could get an entry pointing to the LAN95xx's regulator. Then the regulator would automatically be turned on when the platform device is bound to the ehci-omap driver. The LAN95xx's regulator is still platform dependent(even for same LAN95xx USB devices on different platforms(omap, tegra, ..)) , so I am wondering why we don't enable it directly in probe() of ehci-omap.0 platform device? I didn't get this point, ehci-omap doesn't help if it's non-omap platform. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/28/2012 02:09 AM, the mail apparently from Alan Stern included: On Wed, 28 Nov 2012, Andy Green wrote: Greg's advice was simply not to rely on pathnames in sysfs because they aren't fixed in stone. That leaves plenty of other ways to approach this problem. It's sage advice, but there is zero code provided in my patches that relies on pathnames in sysfs. In your 1/5 patch, _device_path_generate() concatenates device name strings, starting from a device root and separating elements with '/' characters. Isn't that the same as a sysfs pathname? It's nothing to do with sysfs... yes some unrelated bits of sysfs also walk the device path. If we want to talk about how fragile the device path is as an id scheme over time we need to talk about likelihood of individual device names changing, not sysfs. Anyway -- Basically, what you want is for something related to device A (the regulator or the GPIO) to happen whenever device B (the ehci-omap.0 platform device) is bound to a driver. The most straightforward way to arrange this is for A's driver to have a callback that is invoked whenever B is bound or unbound. The most straightforward way to arrange _that_ is to allow each platform_device to have a list of callbacks. Sorry I didn't really understand this proposal yet. You want A, the regulator, driver to grow a callback function that gets called when the targeted platform_device (B, ehci-omap.0) probe happens. Could you expand what the callback prototype or new members in the struct might look like? It's your tuple thing or we pass it an opaque pointer that is the struct regulator * or suchlike? Well, it won't be exactly the same as the tuple thing because no strings will be involved, but it would be similar. The callback would receive an opaque pointer (presumably to the regulator) and a device pointer (the B device). OK. So I try to sketch it out iteractively to try to get in sync: device.h: enum asset_event { AE_PROBED, AE_REMOVED }; struct device_asset { char *name; /* name of regulator, clock, etc */ void *asset; /* regulator, clock, etc */ int (*handler)(struct device *dev_owner, enum asset_event asset_event, struct device_asset *asset); }; struct device { ... struct device_asset *assets; ... }; drivers/base/dd.c | really_probe(): ... struct device_asset *asset; ... asset = dev-assets; while (asset asset-name) { if (asset-handler(dev, AE_PROBED, asset)) { /* clean up and bail */ } asset++; } /* do probe */ ... drivers/base/dd.c | __device_release_driver: (is this really the best place to oppose probe()?) ... struct device_asset *asset; ... /* call device -remove() */ ... asset = dev-assets; while (asset asset-name) { asset-handler(dev, AE_REMOVED, asset); asset++; } ... board file: static struct regulator myreg = { .name = mydevice-regulator, }; static struct device_asset mydevice_assets[] = { { .name = mydevice-regulator, .handler = regulator_default_asset_handler, }, { } }; static struct platform_device mydevice = { ... .dev = { .assets = mydevice_assets, }, ... }; regulator code: int regulator_default_asset_handler(struct device *dev_owner, enum asset_event asset_event, struct device_asset *asset) { struct regulator **reg = asset-asset; int n; switch (asset_event) { case AE_PROBED: *reg = regulator_get(dev_owner, asset-name); if (IS_ERR(*reg)) return *reg; n = regulator_enable(*reg); if (n 0) regulator_put(*reg); return n; case AE_REMOVED: regulator_put(*reg); break; } return 0; } EXPORT_SYMBOL_GPL(regulator_default_asset_handler); The subsystems that can expect to get used (clock...) might each want to define a default handler like the one for regulator. That'll be an end to the code duplication issue. The user can still do his own handler if he wants. I put a name field in so we can use regulator_get() nicely, we don't need access to the object pointer or that it exists at boardfile-time that way either. But I can see it's arguable. Throwing out the path stuff and limiting this to platform_device means you cannot bind to dynamically created objects like hub or anything downstream of a hub. So Felipe's identification of the hub as the happening place to do
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/28/2012 04:10 AM, the mail apparently from Alan Stern included: On Wed, 28 Nov 2012, Andy Green wrote: OK. So I try to sketch it out iteractively to try to get in sync: device.h: enum asset_event { AE_PROBED, AE_REMOVED }; struct device_asset { char *name; /* name of regulator, clock, etc */ void *asset; /* regulator, clock, etc */ int (*handler)(struct device *dev_owner, enum asset_event asset_event, struct device_asset *asset); }; Another possibility is to have two handlers: one for pre-probe and the other for post-remove. Then of course asset_event wouldn't be needed. Linus tends to prefer this strategy -- separate functions for separate events. That's why struct dev_pm_ops has so many method pointers. OK. I wonder if this needs extending to PM ops passing in to the assets. Regulator is usually self-sufficient but sometimes clocks at least need meddling in suspend paths. Maybe it's enough instead to offer a standalone api for drivers that want to meddle with assets, like enable / disable an asset clock... void *device_find_asset(struct device *device, const char *name); ...if it wants to touch anything like that it needs to mandate a nonambiguous name for the asset like reg-mydriver-ehci-omap.0. This is also handy since the driver can then adapt around absence or presence of optional assets if it wants. struct device { ... struct device_asset *assets; Or a list instead of a NULL-terminated array. It depends on whether people will want to add or remove assets dynamically. For now an array would be fine. OK. ... }; drivers/base/dd.c | really_probe(): ... struct device_asset *asset; ... asset = dev-assets; while (asset asset-name) { Maybe it would be better to test asset-handler. Some assets might not need names. Good point. if (asset-handler(dev, AE_PROBED, asset)) { /* clean up and bail */ } asset++; } /* do probe */ ... drivers/base/dd.c | __device_release_driver: (is this really the best place to oppose probe()?) The right place is just after the remove method is called, so yes. ... struct device_asset *asset; ... /* call device -remove() */ ... asset = dev-assets; while (asset asset-name) { asset-handler(dev, AE_REMOVED, asset); asset++; } It would be slightly safer to iterate in reverse order. Good point. ... board file: static struct regulator myreg = { .name = mydevice-regulator, }; static struct device_asset mydevice_assets[] = { { .name = mydevice-regulator, .handler = regulator_default_asset_handler, }, { } }; static struct platform_device mydevice = { ... .dev = { .assets = mydevice_assets, }, ... }; regulator code: int regulator_default_asset_handler(struct device *dev_owner, enum asset_event asset_event, struct device_asset *asset) { struct regulator **reg = asset-asset; int n; switch (asset_event) { case AE_PROBED: *reg = regulator_get(dev_owner, asset-name); if (IS_ERR(*reg)) return *reg; PTR_ERR. Right. I'll offer a series with these adaptations shortly. -Andy n = regulator_enable(*reg); if (n 0) regulator_put(*reg); return n; case AE_REMOVED: regulator_put(*reg); break; } return 0; } EXPORT_SYMBOL_GPL(regulator_default_asset_handler); The subsystems that can expect to get used (clock...) might each want to define a default handler like the one for regulator. That'll be an end to the code duplication issue. The user can still do his own handler if he wants. I put a name field in so we can use regulator_get() nicely, we don't need access to the object pointer or that it exists at boardfile-time that way either. But I can see it's arguable. It hadn't occurred to me, but it seems like a good idea. Yes, overall this is almost exactly what I had in mind. Throwing out the path stuff and limiting this to platform_device means you cannot bind to dynamically created objects like hub or anything downstream of a hub. So Felipe's identification of the hub as the happening place to do this is out of luck. Greg pointed out that this could be useful for arbitrary devices, not just platform devices, so it could be applied to dynamically created objects. Well that is cool, but to exploit that in the dynamic object case
[RFC PATCH 0/5] Device Paths introduced and applied to generic hub and panda
NB this is against usb-next at 3.7-rc6 The following series introduces wildcard device paths as discussed recently; in particular the wildcard idea is from Alan Stern. First the API is introduced for generating, comparing and registering the wildcard device paths. I put them in drivers/base for now but if that seems wrong it's easy to move. They are a default n CONFIG_ option. Then I remove the ehci-omap existing regulator support completely. Third I add optional regulator support to the usb generic hub. This uses wildcard device path APIs to look for a regulator that matches the hub. Again the support is optional on a default n CONFIG_ option. If the regulator is found, then it is enabled for the lifetime of the matching logical hub object. Board support for OMAP4 Panda is added which provides regulators with the correct wildcard name to match the ehci-omap.0 root hub object. The wildcard name is registered so it will be used as a literal on any matching generated device path. Lastly there's a config delta on omap2plus_defconfig which enables EHCI, which is otherwise disabled by default. The end result is that the SMSC HUB+ETH chip is off by default at boot, and is powered cleanly for the lifecycle of the ehci-hcd root hub object. Comments welcome, this is my first attempt at turning the discussion of the last few days into an implementation, it is working here well on Panda ES. -Andy --- Andy Green (5): drivers : introduce device_path api usb: omap ehci: remove all regulator control from ehci omap usb: hub: add device_path regulator control to generic hub omap4: panda: add smsc95xx regulator and reset dependent on root hub config omap2plus add ehci bits arch/arm/configs/omap2plus_defconfig | 42 +++ arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 90 +--- drivers/base/Kconfig |6 + drivers/base/Makefile |2 drivers/base/core.c|2 drivers/base/path.c| 181 drivers/usb/core/Kconfig | 10 ++ drivers/usb/core/hub.c | 26 - drivers/usb/host/ehci-omap.c | 33 -- include/linux/device.h | 12 ++ 11 files changed, 327 insertions(+), 78 deletions(-) create mode 100644 drivers/base/path.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 1/5] drivers : introduce device_path api
This adds a small optional API into drivers/base which deals with generating, matching and registration of wildcard device paths. From a struct device * you can generate a string like /platform/usbhs_omap/ehci-omap.0/usb1/1-1 which enapsulates the path of the device's connection to the board. These can be used to match up other assets, for example struct regulators, that have been registed elsewhere with a device instance that is probed asynchronously from the other board assets. If your device is on a bus, as it probably is, the device path will feature redundant bus indexes that do not contain information about the connectivity. For example if more than one driver can generate devices on the same bus, then the ordering of device probing will change the path, despite the connectivity remains the same. For that reason, to get a deterministic path for matching, wildcards are allowed. If your target device has the path /platform/usbhs_omap/ehci-omap.0/usb1/1-1 generated, in the asset you wish to match with it you can instead use /platform/usbhs_omap/ehci-omap.0/usb*/*-1 in order to only leave the useful, invariant parts of the path to match against. To avoid having to adapt every kind of search by string api to also use the wildcards, the api takes the approach you can register your wildcard, and if a matching path is generated for a device, the wildcard itself is handed back as the device path instead. So if your board code or a (not yet done) DT binding registers this wildcard /platform/usbhs_omap/ehci-omap.0/usb* and the usb hub driver asks to generate its device path device_path_generate(dev, name, sizeof name); that is actually /platform/usbhs_omap/ehci-omap.0/usb1 then what will be returned is /platform/usbhs_omap/ehci-omap.0/usb* providing the same literal string for ehci-omap.0 hub no matter how many\ usb buses have been registered before. This wildcard string can then be matched to regulators or other string- searchable assets intended for the device on that hardware path. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/base/Kconfig |6 ++ drivers/base/Makefile |2 + drivers/base/core.c|2 + drivers/base/path.c| 181 include/linux/device.h | 12 +++ 5 files changed, 203 insertions(+) create mode 100644 drivers/base/path.c diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index b34b5cd..3324a55 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -282,4 +282,10 @@ config CMA_AREAS endif +config DEVICEPATH + bool Device path api + default n + help + Include dynamicly probed path matching API + endmenu diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 5aa2d70..b8d5723 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -22,5 +22,7 @@ obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_REGMAP) += regmap/ obj-$(CONFIG_SOC_BUS) += soc.o +obj-$(CONFIG_DEVICEPATH) += path.o + ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/core.c b/drivers/base/core.c index abea76c..cc0ba02 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1368,6 +1368,8 @@ int __init devices_init(void) if (!sysfs_dev_char_kobj) goto char_kobj_err; + device_path_init(); + return 0; char_kobj_err: diff --git a/drivers/base/path.c b/drivers/base/path.c new file mode 100644 index 000..384e792 --- /dev/null +++ b/drivers/base/path.c @@ -0,0 +1,181 @@ +/* + * drivers/base/path.c - device_path apis for matching dynamic / variable + * device paths on buses like usb / mmc to wildcard constants from + * platform or DT + * + * Copyright (c) 2012 Linaro, LTD + * Author: Andy Green andy.gr...@linaro.org + * + * This file is released under the GPLv2 + * + */ + +#include linux/device.h +#include linux/err.h +#include linux/list.h +#include linux/mutex.h +#include linux/string.h +#include linux/export.h +#include linux/slab.h + +struct device_path { + char *path; + struct list_head list; +}; + +struct device_path list; +DEFINE_MUTEX(lock); + +static int device_path_compare_wildcard(const char *awc, const char *b) +{ + while (*awc *b) { + if (*awc == '*') { + awc++; + /* wildcard disallowed from extening past / */ + while (*b *b != *awc *b != '/') + b++; + } + if (*awc != *b) + return -ENOENT; + if (!*awc) + return 0; + awc++; + b++; + } + + if (!*awc !*b) + return 0; + + return -ENOENT; +} + +static const char *device_path_find_wildcard(const char *device_path) +{ + struct device_path *dp; + + mutex_lock(lock); + list_for_each_entry(dp, list.list, list
[RFC PATCH 2/5] usb: omap ehci: remove all regulator control from ehci omap
This series migrates it to the hub driver as suggested by Felipe Balbi. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/usb/host/ehci-omap.c | 33 - 1 file changed, 33 deletions(-) diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 44e7d0f..2292544 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -40,7 +40,6 @@ #include linux/slab.h #include linux/usb/ulpi.h #include plat/usb.h -#include linux/regulator/consumer.h #include linux/pm_runtime.h #include linux/gpio.h #include linux/clk.h @@ -149,19 +148,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) return rc; } -static void disable_put_regulator( - struct ehci_hcd_omap_platform_data *pdata) -{ - int i; - - for (i = 0 ; i OMAP3_HS_USB_PORTS ; i++) { - if (pdata-regulator[i]) { - regulator_disable(pdata-regulator[i]); - regulator_put(pdata-regulator[i]); - } - } -} - /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -223,23 +209,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) hcd-rsrc_len = resource_size(res); hcd-regs = regs; - /* get ehci regulator and enable */ - for (i = 0 ; i OMAP3_HS_USB_PORTS ; i++) { - if (pdata-port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { - pdata-regulator[i] = NULL; - continue; - } - snprintf(supply, sizeof(supply), hsusb%d, i); - pdata-regulator[i] = regulator_get(dev, supply); - if (IS_ERR(pdata-regulator[i])) { - pdata-regulator[i] = NULL; - dev_dbg(dev, - failed to get ehci port%d regulator\n, i); - } else { - regulator_enable(pdata-regulator[i]); - } - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -265,7 +234,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) return 0; err_pm_runtime: - disable_put_regulator(pdata); pm_runtime_put_sync(dev); usb_put_hcd(hcd); @@ -290,7 +258,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) struct ehci_hcd_omap_platform_data *pdata = dev-platform_data; usb_remove_hcd(hcd); - disable_put_regulator(dev-platform_data); iounmap(hcd-regs); usb_put_hcd(hcd); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 3/5] usb: hub: add device_path regulator control to generic hub
This adds the config option to associate a regulator with each hub, when the hub on a specific, interesting device path appears, then the regular is powered while the logical hub exists. Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/usb/core/Kconfig | 10 ++ drivers/usb/core/hub.c | 26 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index f70c1a1..4a91eb1 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -95,3 +95,13 @@ config USB_OTG_BLACKLIST_HUB and software costs by not supporting external hubs. So are Embedded Hosts that don't offer OTG support. +config USB_HUB_DEVICE_PATH_REGULATOR + bool Support generic regulators at hubs + select DEVICEPATH + depends on USB + default n + help + Allows you to use the device_path APIs to associate kernel regulators + with dynamically probed USB hubs, so the regulators are enabled + as the appropriate hub instance gets created and disabled as it + is destroyed. diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index a815fd2..49ebb5e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -26,6 +26,7 @@ #include linux/mutex.h #include linux/freezer.h #include linux/random.h +#include linux/regulator/consumer.h #include asm/uaccess.h #include asm/byteorder.h @@ -54,7 +55,9 @@ struct usb_hub { struct usb_device *hdev; struct kref kref; struct urb *urb; /* for interrupt polling pipe */ - +#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR + struct regulator*regulator; /* optional power control */ +#endif /* buffer for urb ... with extra space in case of babble */ char(*buffer)[8]; union { @@ -1594,6 +1597,12 @@ static void hub_disconnect(struct usb_interface *intf) if (hub-hdev-speed == USB_SPEED_HIGH) highspeed_hubs--; +#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR + if (hub-regulator !IS_ERR(hub-regulator)) { + regulator_disable(hub-regulator); + regulator_put(hub-regulator); + } +#endif usb_free_urb(hub-urb); kfree(hub-ports); kfree(hub-descriptor); @@ -1609,6 +1618,9 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_endpoint_descriptor *endpoint; struct usb_device *hdev; struct usb_hub *hub; +#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR + char *dev_path; +#endif desc = intf-cur_altsetting; hdev = interface_to_usbdev(intf); @@ -1692,6 +1704,18 @@ descriptor_error: return -ENOMEM; } +#ifdef CONFIG_USB_HUB_DEVICE_PATH_REGULATOR + /* if a regulator is associated on our device_path, use it */ + dev_path = kmalloc(MAX_DEV_PATH_SIZE, GFP_KERNEL); + if (!device_path_generate(hdev-dev, dev_path, MAX_DEV_PATH_SIZE)) { + dev_info(hdev-dev, device_path: %s\n, dev_path); + hub-regulator = regulator_get(hdev-dev, dev_path); + if (!IS_ERR(hub-regulator)) + regulator_enable(hub-regulator); + } + kfree(dev_path); +#endif + kref_init(hub-kref); INIT_LIST_HEAD(hub-event_list); hub-intfdev = intf-dev; -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 4/5] omap4: panda: add smsc95xx regulator and reset dependent on root hub
This adds regulators which are controlled by the OMAP4 PandaBoard (ES)'s EHCI logical root hub existing. Without power control, the ULPI PHY + SMSC9614 on the Panda eats 700-900mW all the time, which is around the same as the idle power of the SoC and rest of the board. This allows us to start off with it depowered, and only power it if the ehci-hcd module is inserted. When the module is removed, it's depowered again. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 90 +--- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index d669e22..5105109 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -368,6 +368,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USB_HUB_DEVICE_PATH_REGULATOR config OMAP3_EMU bool OMAP3 debugging peripherals diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index bfcd397..b032b6b 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -154,11 +154,6 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .reset_gpio_port[2] = -EINVAL }; -static struct gpio panda_ehci_gpios[] __initdata = { - { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, hub_power }, - { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, hub_nreset }, -}; - static void __init omap4_ehci_init(void) { int ret; @@ -173,23 +168,76 @@ static void __init omap4_ehci_init(void) clk_set_rate(phy_ref_clk, 1920); clk_prepare_enable(phy_ref_clk); - /* disable the power to the usb hub prior to init and reset phy+hub */ - ret = gpio_request_array(panda_ehci_gpios, -ARRAY_SIZE(panda_ehci_gpios)); - if (ret) { - pr_err(Unable to initialize EHCI power/reset\n); - return; - } + usbhs_init(usbhs_bdata); +} - gpio_export(GPIO_HUB_POWER, 0); - gpio_export(GPIO_HUB_NRESET, 0); - gpio_set_value(GPIO_HUB_NRESET, 1); +/* + * hub_nreset also resets the ULPI PHY and is required after powering SMSC chip + * ULPI PHY is always powered... need to do reset once for both once + * hub_power enables a 3.3V regulator for (hub + eth) chip + * however there's no point having ULPI PHY in use alone + * since it's only connected to the (hub + eth) chip + */ - usbhs_init(usbhs_bdata); +static struct regulator_init_data panda_hub = { + .constraints = { + .name = vhub, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; - /* enable power to hub */ - gpio_set_value(GPIO_HUB_POWER, 1); -} +static struct fixed_voltage_config panda_vhub = { + .supply_name = vhub, + .microvolts = 330, + .gpio = GPIO_HUB_POWER, + .startup_delay = 7, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = panda_hub, +}; + +static struct platform_device omap_vhub_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = panda_vhub, + }, +}; + +static struct regulator_init_data panda_ulpireset = { + /* +* idea is that when operating ulpireset, regulator api will make +* sure that the hub+eth chip is powered, since it's the parent +*/ + .supply_regulator = vhub, /* we are a child of vhub */ + .constraints = { + /* +* this magic string associates us with ehci-omap.0 root hub +* when the root hub logical device is up, we will power +* and reset [ ULPI PHY + [ HUB + ETH ] ] +*/ + .name = /platform/usbhs_omap/ehci-omap.0/usb*, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct fixed_voltage_config panda_vulpireset = { + .supply_name = /platform/usbhs_omap/ehci-omap.0/usb*, + .microvolts = 330, + .gpio = GPIO_HUB_NRESET, + .startup_delay = 7, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = panda_ulpireset, +}; + +static struct platform_device omap_vulpireset_device = { + .name = reg-fixed-voltage, + .id = 3, + .dev = { + .platform_data = panda_vulpireset, + }, +}; static struct omap_musb_board_data musb_board_data = { .interface_type = MUSB_INTERFACE_UTMI, @@ -503,7 +551,11 @@ static void __init omap4_panda_init(void) omap4_panda_init_rev(); omap4_panda_i2c_init(); platform_add_devices(panda_devices, ARRAY_SIZE
[RFC PATCH 5/5] config omap2plus add ehci bits
omap2plus seems to have rotted a bit, this is the delta that appears if we enable modular build for ehci-hcd and smsc95xx. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/configs/omap2plus_defconfig | 42 ++ 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 6230304..2f858a3 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -1,14 +1,14 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,16 +20,15 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_OMAP=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y +CONFIG_SOC_OMAP5=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 -CONFIG_LEDS=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE=root=/dev/mmcblk0p2 rootwait console=ttyO2,115200 @@ -87,22 +86,21 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y -CONFIG_USB_NET_SMSC95XX=y +CONFIG_USB_NET_SMSC95XX=m CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_DEBUG=y CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -132,14 +130,13 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y -CONFIG_REGULATOR_TWL4030=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y @@ -154,7 +151,6 @@ CONFIG_PANEL_ACX565AKM=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -174,13 +170,15 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_HCD_PLATFORM=m CONFIG_USB_WDM=y CONFIG_USB_STORAGE=y -CONFIG_USB_LIBUSUAL=y CONFIG_USB_TEST=y +CONFIG_OMAP_USB2=m CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y CONFIG_USB_GADGET_DEBUG_FILES=y @@ -214,23 +212,18 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set @@ -239,4 +232,3 @@ CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_LIBCRC32C=y -CONFIG_SOC_OMAP5=y -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/27/2012 03:12 AM, the mail apparently from Alan Stern included: On Mon, 26 Nov 2012, Andy Green wrote: This adds a small optional API into drivers/base which deals with generating, matching and registration of wildcard device paths. From a struct device * you can generate a string like /platform/usbhs_omap/ehci-omap.0/usb1/1-1 which enapsulates the path of the device's connection to the board. These can be used to match up other assets, for example struct regulators, that have been registed elsewhere with a device instance that is probed asynchronously from the other board assets. If your device is on a bus, as it probably is, the device path will feature redundant bus indexes that do not contain information about the connectivity. For example if more than one driver can generate devices on the same bus, then the ordering of device probing will change the path, despite the connectivity remains the same. For that reason, to get a deterministic path for matching, wildcards are allowed. If your target device has the path /platform/usbhs_omap/ehci-omap.0/usb1/1-1 generated, in the asset you wish to match with it you can instead use /platform/usbhs_omap/ehci-omap.0/usb*/*-1 in order to only leave the useful, invariant parts of the path to match against. Have you considered limiting these wildcards in various useful ways? In this example, the wildcard must match a string of decimal digits. (Furthermore the two wildcard strings will always match each other, although it's probably not necessary to add this sort of constraint.) I don't know what sort of matches people will want in the future. Perhaps one for hex digits, or one for arbitrary text with the exception of a few characters (such as '/' but perhaps others too). To do what you want for now, the match should be restricted to digits. I'm not sure what we'd use that for... it doesn't seem the biggest problem we have at the moment ^^ To avoid having to adapt every kind of search by string api to also use the wildcards, the api takes the approach you can register your wildcard, and if a matching path is generated for a device, the wildcard itself is handed back as the device path instead. So if your board code or a (not yet done) DT binding registers this wildcard /platform/usbhs_omap/ehci-omap.0/usb* and the usb hub driver asks to generate its device path device_path_generate(dev, name, sizeof name); that is actually /platform/usbhs_omap/ehci-omap.0/usb1 then what will be returned is /platform/usbhs_omap/ehci-omap.0/usb* providing the same literal string for ehci-omap.0 hub no matter how many\ usb buses have been registered before. This wildcard string can then be matched to regulators or other string- searchable assets intended for the device on that hardware path. That's not how I would do it, at least, not for this application. I would register tuples containing a name, a pointer, and two callback routines. For example, (/platform/usbhs_omap/ehci-omap.0/usb*, omap_vhub_device, turn_on_regulator, turn_off_regulator) The when a device is registered whose path matches the string in such a tuple, the device core would know to invoke the first callback. The arguments would be a pointer to the device being registered and the pointer in the tuple. Similarly, the device core would invoke the second callback when the device is unregistered. There doesn't have to be anything in this scheme that's specific to hubs or even to USB. In particular, no changes to the hub driver would be needed. By just using paths, it's not restricted to regulators or binary operations on them but anything that needs a floating binding to another named kernel object can leverage it. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/27/2012 03:16 AM, the mail apparently from Greg KH included: On Mon, Nov 26, 2012 at 12:45:34PM +, Andy Green wrote: +struct device_path list; +DEFINE_MUTEX(lock); Those are some very descriptive global variables you just created :( I guess I can add the static if that will heal the emotional damage I caused. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/27/2012 03:22 AM, the mail apparently from Greg KH included: On Mon, Nov 26, 2012 at 12:45:34PM +, Andy Green wrote: This adds a small optional API into drivers/base which deals with generating, matching and registration of wildcard device paths. From a struct device * you can generate a string like /platform/usbhs_omap/ehci-omap.0/usb1/1-1 which enapsulates the path of the device's connection to the board. These can be used to match up other assets, for example struct regulators, that have been registed elsewhere with a device instance that is probed asynchronously from the other board assets. If your device is on a bus, as it probably is, the device path will feature redundant bus indexes that do not contain information about the connectivity. Huh? A bus index does show the connectivity, well, one type of connectivity, but perhaps it's not the one _you_ happen to want at the moment. Which is fine, but I don't see why you want to try to figure this out using the device path in the first place, surely you have some other way that the hardware can describe itself to the kernel as to where it needs to be hooked up to? The bus index is like a counter, it shows logical connectivity inside Linux that isn't repeatable and doesn't reflect hardware routing information directly. For example if more than one driver can generate devices on the same bus, then the ordering of device probing will change the path, despite the connectivity remains the same. That's an expected thing, I don't see the issue here. Alan brought up in a thread here the last days, wouldn't it be nice if we could arbitrarily bind regulators to asynchronously probed objects, and after discussion proposed this wildcard matching scheme to mask these generated bus numbers. For that reason, to get a deterministic path for matching, wildcards are allowed. If your target device has the path Wait, no, why would you want a deterministic path and have that hard-coded into the kernel here? You can't rely on that any more than userspace can, so let's not start making the mistake that lots of userspace programmers originally did when they started using sysfs please. We have learned from our past mistakes. I guess that is a fair point. I was going to say that it's no different than using any kernel API in code, which history proves is very mutable; people deal with it by changing the usages as they change the API definition. But it's complicated a bit by DTs meant to be more stable and these paths would turn up in the DT. In platform case though, a heuristic that leaving off the initial / and allowing matches anywhere along the path then to the end would get around it. /platform/usbhs_omap/ehci-omap.0/usb1/1-1 generated, in the asset you wish to match with it you can instead use /platform/usbhs_omap/ehci-omap.0/usb*/*-1 in order to only leave the useful, invariant parts of the path to match against. To avoid having to adapt every kind of search by string api to also use the wildcards, the api takes the approach you can register your wildcard, and if a matching path is generated for a device, the wildcard itself is handed back as the device path instead. So if your board code or a (not yet done) DT binding registers this wildcard /platform/usbhs_omap/ehci-omap.0/usb* Device tree lists sysfs paths in it's descriptions? That's news to me. It does not say that... and the usb hub driver asks to generate its device path device_path_generate(dev, name, sizeof name); that is actually /platform/usbhs_omap/ehci-omap.0/usb1 then what will be returned is /platform/usbhs_omap/ehci-omap.0/usb* providing the same literal string for ehci-omap.0 hub no matter how many\ usb buses have been registered before. This wildcard string can then be matched to regulators or other string- searchable assets intended for the device on that hardware path. Ah, here's the root of your problem, right? You need a way for your hardware to tell the kernel that you have a regulator attached to a specific device? Using the device path and hard-coding it into the kernel is not the proper way to solve this, sorry. Use some other unique way to describe the hardware, surely the hardware designers couldn't have been that foolish not to provide this [1]? thanks, greg k-h [1] Yeah, I know I'm being hopeful here, and probably wrong, but then you need to push back. We are not helpless here. Specific hardware information is something that's kept hidden away and private in the driver for good reasons. We could add elective, additional information at the driver for every physical interface it represented and match that way. But I am not sure the effort involved is repaid by the relatively few instances that need what is basically asynchronously probed platform_data. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http
Re: [RFC PATCH 1/5] drivers : introduce device_path api
On 11/27/2012 05:07 AM, the mail apparently from Alan Stern included: On Mon, 26 Nov 2012, Greg KH wrote: Ah, here's the root of your problem, right? You need a way for your hardware to tell the kernel that you have a regulator attached to a specific device? Using the device path and hard-coding it into the kernel is not the proper way to solve this, sorry. Use some other unique way to describe the hardware, surely the hardware designers couldn't have been that foolish not to provide this [1]? As far as I know, the kernel has no other way to describe devices. What about using partial matches? In this example, instead of doing a wildcard match against /platform/usbhs_omap/ehci-omap.0/usb* (which would fail if the platform part of the path changes), suppose the string ehci-omap.0/usb* could be associated with the usbhs_omap component somehow. Or even better, the string usb* could be associated with the ehci-omap.0 device. Then the path-matching code could restrict its attention to that part of the path and to devices below the specified one. Naming changes wouldn't be an issue, because the changes themselves would be made in the same source file that contains the partial path string. Yes just dropping the starting / on the match and allowing a fragment to match further up the string would solve it. ehci-omap.0 won't appear down any other earlier device paths than the right one. On the other hand, this may be way more general than we really need. For this particular case, all we need to do is take special action the first time any device is registered below the ehci-omap.0 platform device. There ought to be a more direct way to accomplish this, without using string pattern-matching or sysfs pathnames (and without adding overhead every time a device is added or deleted). There are no sysfs pathnames involved here at all. Greg invented that. I don't know if such an approach would be sufficiently general for future requirements, but it would solve the problem at hand. We can get a notification about device creation and do things there. But the cost of that is like the tuple suggestion, they'll only be able to do a fixed thing like operate on regulators. Actually the targeted device may have arbitrary associated assets like generic GPIO to turn on a flash for built-in webcam controlled out-of-band. These also can be reached by known names. And the driver may wish to do things with them that are more complex than enable / disable or follow logical lifecycle of the hub or whatever. However when the guidance from Greg is that we can do nothing except complain at hardware designers for some reason I failed to quite identify, I fear we are moving deckchairs on the titanic. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 4/5] omap4: panda: add smsc95xx regulator and reset dependent on root hub
On 11/27/2012 12:20 AM, the mail apparently from Roger Quadros included: Hi Andy, On 11/26/2012 02:45 PM, Andy Green wrote: This adds regulators which are controlled by the OMAP4 PandaBoard (ES)'s EHCI logical root hub existing. Without power control, the ULPI PHY + SMSC9614 on the Panda eats 700-900mW all the time, which is around the same as the idle power of the SoC and rest of the board. This allows us to start off with it depowered, and only power it if the ehci-hcd module is inserted. When the module is removed, it's depowered again. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 90 +--- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index d669e22..5105109 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -368,6 +368,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USB_HUB_DEVICE_PATH_REGULATOR config OMAP3_EMU bool OMAP3 debugging peripherals diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index bfcd397..b032b6b 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -154,11 +154,6 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = { .reset_gpio_port[2] = -EINVAL }; -static struct gpio panda_ehci_gpios[] __initdata = { - { GPIO_HUB_POWER, GPIOF_OUT_INIT_LOW, hub_power }, - { GPIO_HUB_NRESET, GPIOF_OUT_INIT_LOW, hub_nreset }, -}; - static void __init omap4_ehci_init(void) { int ret; @@ -173,23 +168,76 @@ static void __init omap4_ehci_init(void) clk_set_rate(phy_ref_clk, 1920); clk_prepare_enable(phy_ref_clk); - /* disable the power to the usb hub prior to init and reset phy+hub */ - ret = gpio_request_array(panda_ehci_gpios, -ARRAY_SIZE(panda_ehci_gpios)); - if (ret) { - pr_err(Unable to initialize EHCI power/reset\n); - return; - } + usbhs_init(usbhs_bdata); +} - gpio_export(GPIO_HUB_POWER, 0); - gpio_export(GPIO_HUB_NRESET, 0); - gpio_set_value(GPIO_HUB_NRESET, 1); +/* + * hub_nreset also resets the ULPI PHY and is required after powering SMSC chip + * ULPI PHY is always powered... need to do reset once for both once + * hub_power enables a 3.3V regulator for (hub + eth) chip + * however there's no point having ULPI PHY in use alone + * since it's only connected to the (hub + eth) chip + */ - usbhs_init(usbhs_bdata); +static struct regulator_init_data panda_hub = { + .constraints = { + .name = vhub, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; - /* enable power to hub */ - gpio_set_value(GPIO_HUB_POWER, 1); -} +static struct fixed_voltage_config panda_vhub = { + .supply_name = vhub, + .microvolts = 330, + .gpio = GPIO_HUB_POWER, + .startup_delay = 7, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = panda_hub, +}; + +static struct platform_device omap_vhub_device = { + .name = reg-fixed-voltage, + .id = 2, + .dev = { + .platform_data = panda_vhub, + }, +}; + +static struct regulator_init_data panda_ulpireset = { + /* +* idea is that when operating ulpireset, regulator api will make +* sure that the hub+eth chip is powered, since it's the parent +*/ + .supply_regulator = vhub, /* we are a child of vhub */ + .constraints = { + /* +* this magic string associates us with ehci-omap.0 root hub +* when the root hub logical device is up, we will power +* and reset [ ULPI PHY + [ HUB + ETH ] ] +*/ + .name = /platform/usbhs_omap/ehci-omap.0/usb*, + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, +}; + +static struct fixed_voltage_config panda_vulpireset = { + .supply_name = /platform/usbhs_omap/ehci-omap.0/usb*, Does this supply_name really needs to be the magic string? I believe that's how the two regulators bind together in the parent-child relationship. Having the literal twice is bad I agree... it could be moved to a const char * earlier and referenced as that. -Andy + .microvolts = 330, + .gpio = GPIO_HUB_NRESET, + .startup_delay = 7, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = panda_ulpireset, +}; + +static struct platform_device omap_vulpireset_device = { + .name = reg-fixed-voltage, + .id
Re: [PATCH 16/16] ARM: OMAP: omap4panda: Power down the USB PHY and ETH when not in use
On 11/24/12 23:38, the mail apparently from Alan Stern included: On Sat, 24 Nov 2012, Andy Green wrote: If we're just looking at fixing the current magic regulator name scheme of hsusb0 so that it can work with abstract devices like any hub / port, we could invert what my original device path scheme did. So instead of having a parser (which boiled down quite small, but is complicated by usb%d being the same for different usb drivers), we could just add a helper function that walks the device parents to generate a string representing the device instance. Like int device_path_generate(struct device *device, char *name, int len); if you called it from the hub driver's probe function (or anything else's probe function) with the new hub device pointer, it might fill name with ehci1/usbhub1-1/1-1.1 or somesuch. It's not that simple. In your example, the very same device might show up, after rebooting, as ehci2/usbhub2-1/2-1.1. Even if a more or less stable name for the controller is used, the bus-number parts of the name (the '2's in this example) are always subject to change. The Agreed; I pointed this out in a previous mail in this thread already, after someone else pointed it out to me some months ago. Indeed we can't use usb%d, the nth usb bus because the ordering of driver insertion for the various drivers that can create usb%ds breaks the determinism of it. So we can only use in the matching paths a %d that represents the nth instance of a device from a specific driver, the nth ehci host controller for example. device_path_generate routine would have to possess special knowledge about the USB subsystem's naming scheme to generate a truly stable name. I think there's enough info exposed to do everything generically with no access to driver-private info. When walking struct device path one of the things we know at each stage is matched driver name. So we might meet a device of name usb2 but afaik we can trivially also see the matched driver has the name ehci-hcd. If we can walk a list of usb%ds, we can determine that our device is the nth device of that type belonging to ehci-hcd driver. That list may be nondeterministic in terms of drivers getting modprobed in and out, say inserting themselves randomly in the ordering of the list before and after we modprobe ehci-hcd, but afaics no amount of insertion or removal will change the sequencing of other entries of the same type already there (first ehci-hcd one will always appear in the list in the same relative order to the second ehci-hcd one). I think this would be reliable for getting as far as ehci1/ and it's generic code walking device path and bus member lists that will work on all buses with that problem. Presumably the same would hold for other subsystems too. Although it looks like that method will bounce off of usbhub%d since the driver name does not vary, I think it can also be alright. If we can walk a list of usbhubs finding the ones that have the same parent pointer as the parent we arrived at in our walking, we should again get an ordinal we can use representing the nth hub on that particular host controller. Afaics that should work for m hub levels too if we just filter by an opaque parent device pointer. Of course the code should not particularly know it's looking at usb%d or usbhub just generic buses or classes or whatever it sees in use while walking the device path. And although there's some walking around described, we only do it at probe time and only for devices that are interested in getting a deterministic device name to bind assets with. The above is logically workable I think but to find out if it's practical to walk usbhubs and so on for me anyway the code needs to be attempted. So I'm curious if you see any flaw already with this scheme. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 16/16] ARM: OMAP: omap4panda: Power down the USB PHY and ETH when not in use
On 11/24/12 00:25, the mail apparently from Alan Stern included: On Fri, 23 Nov 2012, Felipe Balbi wrote: Thanks for the example. The only problem is, how do we associate a regulator to a specific port in the system. heh, that's the 1 million dollar question, isn't it ? :-) that's what we need to figure out now. Luckily we have Alan Stern helping us out ;-) Some people might think having me around to interfere was not so lucky after all... :-) First question: Should we worry about individual ports? Ordinarily I'd say No, because hubs always power up all of their ports. But with Lan Tianyu's recent work, that won't be true any more. In this case, it's conceivable that the user might want to power-off the LAN95xx in order to save energy, even though ehci-hcd is still loaded and managing other USB devices. Either way, the regulator has to be associated with _something_: either a root-hub port or the host controller itself. And this will most likely have to be done before the port's or the controller's struct device exists. Something like Andy's scheme might work. It would require the kernel to parse name strings in various formats, which could get complicated. It would be great if the difficult parts could be stuck in the PM core somewhere. If we're just looking at fixing the current magic regulator name scheme of hsusb0 so that it can work with abstract devices like any hub / port, we could invert what my original device path scheme did. So instead of having a parser (which boiled down quite small, but is complicated by usb%d being the same for different usb drivers), we could just add a helper function that walks the device parents to generate a string representing the device instance. Like int device_path_generate(struct device *device, char *name, int len); if you called it from the hub driver's probe function (or anything else's probe function) with the new hub device pointer, it might fill name with ehci1/usbhub1-1/1-1.1 or somesuch. That is then used in the hub probe function as the magic regulator name, if a regulator exists of that name it gets managed according to logical hub device lifecycle, same as the omap bit does at the moment. That way it'll work with DT alright (you just arrange the regulator name to be ehci1/usbhub1-1/1-1.1 or whatever) and you're just trying to sell device_path_generate() to someone else, which should be pretty small. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 16/16] ARM: OMAP: omap4panda: Power down the USB PHY and ETH when not in use
On 11/22/12 20:21, the mail apparently from Felipe Balbi included: Hi, On Thu, Nov 22, 2012 at 09:13:16AM +0800, Andy Green wrote: On 11/22/12 03:54, the mail apparently from Felipe Balbi included: Hi, On Wed, Nov 21, 2012 at 06:07:57PM +0200, Roger Quadros wrote: On 11/21/2012 05:32 PM, Alan Stern wrote: On Wed, 21 Nov 2012, Roger Quadros wrote: On 11/21/2012 04:52 PM, Alan Stern wrote: On Wed, 21 Nov 2012, Felipe Balbi wrote: On Thu, Nov 15, 2012 at 04:34:14PM +0200, Roger Quadros wrote: From: Andy Green andy.gr...@linaro.org This patch changes the management of the two GPIO for hub reset (actually controls enable of ULPI PHY and hub reset) and hub power (controls power to hub + eth). looks like this should be done by the hub driver. Alan, what would you say ? Should the hub driver know how to power itself up ? Not knowing the context, I'm a little confused. What is this hub you're talking about? Is it a separate USB hub incorporated into the IP (like Intel's rate-matching hubs in their later chipsets)? Or is it the root hub? This is actually a USB HUB + Ethernet combo chip (LAN9514) that is hard wired on the panda board with its Power and Reset pins controlled by 2 GPIOs from the OMAP SoC. When powered, this chip can consume significant power (~0.7 W) because of the (integrated Ethernet even when suspended. I suppose the ethernet driver SMSC95XX) doesn't put it into a low enough power state on suspend. It doesn't make sense to power the chip when USB is not required on the whole (e.g. ehci_hcd module is not loaded). This is what this patch is trying to fix. Ah, okay. Then yes, assuming you want to power this chip only when either ehci-hcd or the ethernet driver is loaded, the right places to manage the power GPIO are in the init and exit routines of the two drivers. The Ethernet function actually connects over USB within the chip. So managing the power only in the ehci-hcd driver should suffice. the thing is that this could cause code duplication all over. LAN95xx is I can see this point. However DT will soak up these regulator definitions, at that point it's for free. On Linaro tilt-3.4 we already have this on the dts hubpower: fixedregulator@0 { compatible = regulator-fixed; regulator-name = vhub0; regulator-min-microvolt = 330; regulator-max-microvolt = 330; gpio = gpio1 1 0; /* gpio 1 : HUB Power */ startup-delay-us = 7; enable-active-high; }; hubreset: fixedregulator@1 { compatible = regulator-fixed; regulator-name = hsusb0;/* tag to associate with PORT 1 */ regulator-min-microvolt = 330; regulator-max-microvolt = 330; gpio = gpio2 30 0; /* gpio 62 : HUB PHY Reset */ startup-delay-us = 7; enable-active-high; vin-supply = vhub0; /* Makes regulator f/w enable power before reset */ }; which is the equivalent to my patch: I don't think we need to sweat about code duplication. why not ? Just because you have some ready DT files outside of the mailine kernel ? Sorry, not a good argument. That's not my argument: it's the whole basis for bothering with DT, but never mind. a generic USB Hub + Ethernet combo on one of ports from SMSC. *Any* platform could use it and could hook those power and reset pins to a GPIO. If we handle this at ehci-omap level, we risk having to duplicate the same piece of code for ehci-*.c We need to consider power and reset separately. Reset is a safe bet as a GPIO but power to the smsc chip is not. so ? I'm saying that it *can* be attached to other architectures and they *can* decide to put both on GPIOs. I'm not considering the likelyhood of the situation. There's some confusion here --- On panda they happen to fit a gpio-controlled linear regulator to provide the smsc 3.3V supply. On another device that can just as good to know, then we need a regulator driver (as you added on your DT file the bindings for it) instead of poking into the GPIO directly. Assuming you mean regulator device, if you look at the patch, that is what it does. The original board file code just sets the GPIO as a one-off and forgets about it, so the whole show is permanently powered, which is objectionable since ~50% of Panda idle power is burned on that. My patch uses regulator definitions in the board file - I only touch the board file - to allow the omap ehci driver to control the power. Again it sounds like something that should be done at the hub driver level. I mean using the GPIO (for reset) and Power Regulator. not implementing the regulator part itself, but using it. If you mean change
Re: [PATCH 16/16] ARM: OMAP: omap4panda: Power down the USB PHY and ETH when not in use
On 11/22/12 03:54, the mail apparently from Felipe Balbi included: Hi, On Wed, Nov 21, 2012 at 06:07:57PM +0200, Roger Quadros wrote: On 11/21/2012 05:32 PM, Alan Stern wrote: On Wed, 21 Nov 2012, Roger Quadros wrote: On 11/21/2012 04:52 PM, Alan Stern wrote: On Wed, 21 Nov 2012, Felipe Balbi wrote: On Thu, Nov 15, 2012 at 04:34:14PM +0200, Roger Quadros wrote: From: Andy Green andy.gr...@linaro.org This patch changes the management of the two GPIO for hub reset (actually controls enable of ULPI PHY and hub reset) and hub power (controls power to hub + eth). looks like this should be done by the hub driver. Alan, what would you say ? Should the hub driver know how to power itself up ? Not knowing the context, I'm a little confused. What is this hub you're talking about? Is it a separate USB hub incorporated into the IP (like Intel's rate-matching hubs in their later chipsets)? Or is it the root hub? This is actually a USB HUB + Ethernet combo chip (LAN9514) that is hard wired on the panda board with its Power and Reset pins controlled by 2 GPIOs from the OMAP SoC. When powered, this chip can consume significant power (~0.7 W) because of the (integrated Ethernet even when suspended. I suppose the ethernet driver SMSC95XX) doesn't put it into a low enough power state on suspend. It doesn't make sense to power the chip when USB is not required on the whole (e.g. ehci_hcd module is not loaded). This is what this patch is trying to fix. Ah, okay. Then yes, assuming you want to power this chip only when either ehci-hcd or the ethernet driver is loaded, the right places to manage the power GPIO are in the init and exit routines of the two drivers. The Ethernet function actually connects over USB within the chip. So managing the power only in the ehci-hcd driver should suffice. the thing is that this could cause code duplication all over. LAN95xx is I can see this point. However DT will soak up these regulator definitions, at that point it's for free. On Linaro tilt-3.4 we already have this on the dts hubpower: fixedregulator@0 { compatible = regulator-fixed; regulator-name = vhub0; regulator-min-microvolt = 330; regulator-max-microvolt = 330; gpio = gpio1 1 0; /* gpio 1 : HUB Power */ startup-delay-us = 7; enable-active-high; }; hubreset: fixedregulator@1 { compatible = regulator-fixed; regulator-name = hsusb0;/* tag to associate with PORT 1 */ regulator-min-microvolt = 330; regulator-max-microvolt = 330; gpio = gpio2 30 0; /* gpio 62 : HUB PHY Reset */ startup-delay-us = 7; enable-active-high; vin-supply = vhub0; /* Makes regulator f/w enable power before reset */ }; which is the equivalent to my patch: I don't think we need to sweat about code duplication. a generic USB Hub + Ethernet combo on one of ports from SMSC. *Any* platform could use it and could hook those power and reset pins to a GPIO. If we handle this at ehci-omap level, we risk having to duplicate the same piece of code for ehci-*.c We need to consider power and reset separately. Reset is a safe bet as a GPIO but power to the smsc chip is not. On panda they happen to fit a gpio-controlled linear regulator to provide the smsc 3.3V supply. On another device that can just as easily be a PMIC regulator channel: it boils down to controlling a power rail. So using struct regulator as the abstraction for the power is the right way already. Since that's a hub driver anyway, I wonder if it would be better to play with those gpios somewhere else ?!? The patch creates a regulator that binds to a magic regulator name defined by the hsusb driver, hsusb0. That regulator is taken up and down by hsusb driver with the lifecycle of the logical hsusb device. So inserting ehci-hcd module powers the regulator until the module is removed. Originally I bound the regulator to the smsc95xx driver, which also offers a struct regulator. But there is a quirk on Panda that means that is not workable. On Panda, they share one SoC gpio to reset both an external ULPI PHY chip and the smsc95xx that is downstream of it. After you power up the smsc95xx, you must reset it in order for correct operation. This actually resets the ULPI PHY too. The ULPI PHY is permanently powered, only nRESET is provided to control it. For that reason, as an attribute of being on a Panda board, we need to do the (shared) reset meddling once at hsusb init, and that is why the patch is as it is. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs
Re: [PATCH 16/16] ARM: OMAP: omap4panda: Power down the USB PHY and ETH when not in use
On 11/23/12 01:36, the mail apparently from Alan Stern included: On Thu, 22 Nov 2012, Felipe Balbi wrote: Hi - If you mean change the regulator managing code from living in omap-hsusb to ehci-hcd, it sounds like a good idea. I mean that drivers/usb/core/hub.c should manage it, since that's what actually manages the HUB entity. This is an interesting problem. How should we handle devices which live on a discoverable bus but whose power is controlled by an undiscoverable platform-specific regulator? Has this sort of thing come up in the past with other types of devices? A big part of the problem is associating the hub, which is created dynamically by the USB core code, with the regulator, which is known from platform data at boot time. The suggestion that the regulator should really be associated with a port on the hub's parent is reasonable at first glance. But what if we don't know which port that is? Once we can solve this part of the problem, I think the rest of it will fall into place. as long as Alan is ok and it comes in the same series, I'd be really, really glad to see such a patch and would happily review it. If we can figure out a good way to set up the necessary association, I won't mind adding the appropriate calls to the USB core. But is the hub driver the right place? What if a similar power arrangement is used for a different kind of USB-connected chip (for example, a webcam or a fingerprint reader)? About 18 months ago I sent out an RFC for platform_data for asynchronously probed devices, aimed at exactly this problem. It got flamed to death. The core idea there was matching device paths like usb1/1-1/1-1.1/1-1.1:1.0 to bind platform data to an asynchronously-probed device, where the device is on hardwired connection. I provided an implementation that worked on both SDIO and usb buses on Panda, for the WLAN module and smsc95xx chip respectively. We have used this implementation to solve lack of hardware or assigned MAC addresses for wlan0 and eth0 on Panda in Linaro tilt kernels ever since. Most of the arguments against it were of the form, do MAC address setting in userspace which I felt did not understand the general use case outside of setting MAC addresses; such as we're talking about now with binding regulators for example. Some of the objectors did not seem to know what platform_data was either, others killed it because platform_data != device tree. There was one genuine objection that I did not solve, what about if people modprobe usb buses in different order, like ehci, xhci etc. So the device path would need to be qualified by the name of the driver targeted as well as the bus index of that driver we targeted, but that's easy enough. Anyway as a generic thing I think its ship has sailed (on a river of flames), but since you bring up attaching kernel objects to asynchronously probed devices: there's one way to do it for hardwired platform devices. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4 0/4] Add ability to set defaultless network device MAC addresses to deterministic computed locally administered values
On 10/07/12 20:37, the mail apparently from Florian Fainelli included: Hi - Le jeudi 05 juillet 2012 04:44:33, Andy Green a écrit : The following series adds some code to generate legal, locally administered MAC addresses from OMAP4 CPU Die ID fuse data, and then adds a helper at net/ethernet taking care of accepting device path / MAC mapping registrations and running a notifier to enforce the requested MAC when the matching network device turns up. This looks like something you can solve by user-space entirely. Expose the That might seem so from a openwrt perspective, where you custom cook the whole userland thing per-device, but it ain't so from a generic rootfs perspective. Why should Ubuntu, Fedora etc stink up their OSes with Panda-specific workarounds? And Panda is not the only device with this issue. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5 1/2] NET ethernet introduce eth-mac-platform helper
From: Andy Green a...@warmcat.com This introduces a small helper in net/ethernet, which registers a network notifier at core_initcall time, and accepts registrations mapping expected asynchronously-probed network device paths (like, usb1/1-1/1-1.1/1-1.1:1.0) and the MAC that is needed to be assigned to the device when it appears. This allows platform code to enforce valid, consistent MAC addresses on to devices that have not been probed at boot-time, but due to being wired on the board are always present at the same interface. It has been tested with USB and SDIO probed devices. Other parts of this series provide an OMAP API that computes a valid locally administered MAC address from CPU ID bits that are unique for each physical SoC, and register those against devices wired to the board. This solves a longstanding problem in at least Panda case that there are no reserved MACs for either onboard Ethernet nor onboard WLAN module, and without this patch a randomized MAC is assigned to Ethernet and 00:00:00:00:00:00 or 0xdeadbeef is assigned as the WLAN MAC address. The series provides sane, constant locally-administered MAC addresses that have a high probability of differing between boards. To make use of this safely you also need to make sure that any drivers that may compete for the bus ordinal you are using (eg, mUSB and ehci in Panda case) are loaded in a deterministic order. At registration it makes a copy of the incoming data, so the data may be __initdata or otherwise transitory. Registration can be called multiple times so registrations from Device Tree and platform may be mixed. Since it needs to be called quite early in boot and there is no lifecycle for what it does, it could not be modular and is not a driver. Via suggestions from Arnd Bergmann and Tony Lindgren (and Alan Cox for the network notifier concept). Cc: net...@vger.kernel.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Andy Green andy.gr...@linaro.org --- include/net/eth-mac-platform.h | 40 ++ net/Kconfig |5 + net/ethernet/Makefile |3 + net/ethernet/eth-mac-platform.c | 150 +++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 include/net/eth-mac-platform.h create mode 100644 net/ethernet/eth-mac-platform.c diff --git a/include/net/eth-mac-platform.h b/include/net/eth-mac-platform.h new file mode 100644 index 000..752f1de --- /dev/null +++ b/include/net/eth-mac-platform.h @@ -0,0 +1,40 @@ +/* + * eth-mac-platform.h: Enforces platform-defined MAC for Async probed devices + */ + +#ifndef __ETH_NET_MAC_PLATFORM_H__ +#define __ETH_NET_MAC_PLATFORM_H__ + +#include linux/if_ether.h + +/** + * struct eth_mac_platform - associates asynchronously probed device path with + * MAC address to be assigned to the device when it + * is created + * + * @device_path: device path name of network device + * @mac: MAC address to assign to network device matching device path + * @list: can be left uninitialized when passing from platform + */ + +struct eth_mac_platform { + char *device_path; + u8 mac[ETH_ALEN]; + struct list_head list; /* unused in platform data usage */ +}; + +#ifdef CONFIG_NET +/** + * eth_mac_platform_register_device_macs - add an array of device path to + * monitor and MAC to apply when the network + * device at the device path appears + * @macs: array of struct eth_mac_platform terminated by entry with + * NULL device_path + */ +int eth_mac_platform_register_device_macs(const struct eth_mac_platform *macs); +#else +static inline int eth_mac_platform_register_device_macs( +const struct eth_mac_platform *macs) { return 0; } +#endif /* !CONFIG_NET */ + +#endif /* __ETH_NET_MAC_PLATFORM_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 245831b..dd8ab96 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -335,9 +335,12 @@ source net/caif/Kconfig source net/ceph/Kconfig source net/nfc/Kconfig - endif # if NET +# used by board / dt platform to enforce Ethernet MACs for Async-probed devices +config ETH_MAC_PLATFORM + bool + # Used by archs to tell that they support BPF_JIT config HAVE_BPF_JIT bool diff --git a/net/ethernet/Makefile b/net/ethernet/Makefile index 7cef1d8..7362f46 100644 --- a/net/ethernet/Makefile +++ b/net/ethernet/Makefile @@ -5,3 +5,6 @@ obj-y += eth.o obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o +ifneq ($(CONFIG_NET),) +obj-$(CONFIG_ETH_MAC_PLATFORM) += eth-mac-platform.o +endif diff --git a/net/ethernet/eth-mac-platform.c b/net/ethernet/eth-mac-platform.c new file mode 100644 index 000..9b2ad69 --- /dev/null +++ b/net/ethernet/eth-mac-platform.c @@ -0,0 +1,150 @@ +/* + * Helper to allow platform code
[PATCH 5 2/2] OMAP4 PANDA register ethernet and wlan for automatic mac allocation
From: Andy Green a...@warmcat.com This provides the board-specific device paths needed to get the panda boardfile working with the eth-mac-platform api. On Pandaboard / ES, neither the onboard Ethernet or onboard WLAN module have onboard arrangements for MAC storage, without this series yielding randomized MAC per-boot and consequent DHCP problems, or in the case of wlan0 a MAC set by a firmware file in the rootfs which unless customized yields a MAC of 00:00:00:00:00:00. No official MAC is reserved for either network device even if you do take the approach to customize the firmware file. This gets sane, consistent MAC addresses on both devices which should stand a good probability of differing between PandaBoards. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 + arch/arm/mach-omap2/board-omap4panda.c | 30 ++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 83fb31c..61c6a3d 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -358,6 +358,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select ETH_MAC_PLATFORM config MACH_PCM049 bool OMAP4 based phyCORE OMAP4 diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb26..75d93cc 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,7 +32,10 @@ #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include net/eth-mac-platform.h + #include mach/hardware.h +#include mach/id.h #include asm/hardware/gic.h #include asm/mach-types.h #include asm/mach/arch.h @@ -486,16 +489,43 @@ static void omap4_panda_init_rev(void) } } +/* + * These device paths represent onboard network devices which have + * no MAC address set at boot, and need synthetic ones assigning + */ +static __initdata struct eth_mac_platform panda_eth_mac_platform[] = { + + { /* smsc USB - Ethernet bridge */ + .device_path = usb1/1-1/1-1.1/1-1.1:1.0, + }, + { /* wlan0 module */ + .device_path = wl12xx, + }, + { /* terminator */ + } +}; + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; int ret; + int n; if (omap_rev() == OMAP4430_REV_ES1_0) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, NULL, package); omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + + /* +* provide MAC addresses computed from device ID for network +* devices that have no MAC address otherwise on Panda +*/ + for (n = 0; n ARRAY_SIZE(panda_eth_mac_platform) - 1; n++) + omap_die_id_to_ethernet_mac(panda_eth_mac_platform[n].mac, n); + if (eth_mac_platform_register_device_macs(panda_eth_mac_platform)) + pr_err(Unable to register eth_mac_platform devices\n); + ret = wl12xx_set_platform_data(omap_panda_wlan_data); if (ret) pr_err(error setting wl12xx data: %d\n, ret); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4 0/4] Add ability to set defaultless network device MAC addresses to deterministic computed locally administered values
The following series adds some code to generate legal, locally administered MAC addresses from OMAP4 CPU Die ID fuse data, and then adds a helper at net/ethernet taking care of accepting device path / MAC mapping registrations and running a notifier to enforce the requested MAC when the matching network device turns up. On PandaBoard / ES, two devices have no board-level MAC either assigned by the manufacturer or stored on the board, the last patch in the series adds these device paths and gets them set when the network device is registered. Lastly for convenient testing, there's a little patch on omap2plus_defconfig that will get Ethernet and WLAN up on Pandaboard. The patches are against today's linux-omap. Thanks to Tony Lindgren and Arnd Bergmann for comments leading to the helper in net/ethernet. --- Andy Green (4): OMAP: add cpu id register to MAC address helper NET ethernet introduce mac_platform helper OMAP4 PANDA register ethernet and wlan for automatic mac allocation config test config extending omap2plus with wl12xx etc arch/arm/configs/omap2plus_defconfig | 35 +++ arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 30 ++ arch/arm/mach-omap2/id.c | 39 arch/arm/mach-omap2/include/mach/id.h |1 include/net/mac-platform.h | 39 net/Kconfig|5 + net/ethernet/Makefile |3 + net/ethernet/mac-platform.c| 151 9 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 include/net/mac-platform.h create mode 100644 net/ethernet/mac-platform.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4 1/4] OMAP: add cpu id register to MAC address helper
From: Andy Green a...@warmcat.com Introduce a generic helper function that can generate a valid MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:20:3c:ea:46:01 for the ethernet device on my PandaBoard ES. The MAC address space has space set aside for these kind of locally administered MAC addresses, analogous to IPv4 10.x.x.x range, and this patch marks the generated MAC addresses as such. The patch leaves two bits allowing elaborating 4 different MACs from the generated data. Signed-off-by: Andy Green andy.gr...@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Nicolas Pitre nicolas.pi...@linaro.org Tested-by: Steven Rostedt rost...@goodmis.org --- arch/arm/mach-omap2/id.c | 39 + arch/arm/mach-omap2/include/mach/id.h |1 + 2 files changed, 40 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 37eb95a..3ab5d4d 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -530,3 +530,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast, and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h index 02ed3aa..d6c8d63 100644 --- a/arch/arm/mach-omap2/include/mach/id.h +++ b/arch/arm/mach-omap2/include/mach/id.h @@ -18,5 +18,6 @@ struct omap_die_id { }; void omap_get_die_id(struct omap_die_id *odi); +void omap_die_id_to_ethernet_mac(u8 *mac, int subtype); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4 2/4] NET ethernet introduce mac_platform helper
From: Andy Green a...@warmcat.com This introduces a small helper in net/ethernet, which registers a network notifier at core_initcall time, and accepts registrations mapping expected asynchronously-probed network device paths (like, usb1/1-1/1-1.1/1-1.1:1.0) and the MAC that is needed to be assigned to the device when it appears. This allows platform code to enforce valid, consistent MAC addresses on to devices that have not been probed at boot-time, but due to being wired on the board are always present at the same interface. It has been tested with USB and SDIO probed devices. Other parts of this series provide an OMAP API that computes a valid locally administered MAC address from CPU ID bits that are unique for each physical SoC, and register those against devices wired to the board. This solves a longstanding problem in at least Panda case that there are no reserved MACs for either onboard Ethernet nor onboard WLAN module, and without this patch a randomized MAC is assigned to Ethernet and 00:00:00:00:00:00 or 0xdeadbeef is assigned as the WLAN MAC address. The series provides sane, constant locally-administered MAC addresses that have a high probability of differing between boards. To make use of this safely you also need to make sure that any drivers that may compete for the bus ordinal you are using (eg, mUSB and ehci in Panda case) are loaded in a deterministic order. At registration it makes a copy of the incoming data, so the data may be __initdata or otherwise transitory. Registration can be called multiple times so registrations from Device Tree and platform may be mixed. Since it needs to be called quite early in boot and there is no lifecycle for what it does, it could not be modular and is not a driver. Via suggestions from Arnd Bergmann and Tony Lindgren (and Alan Cox for the network notifier concept). Cc: net...@vger.kernel.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Andy Green andy.gr...@linaro.org --- include/net/mac-platform.h | 39 +++ net/Kconfig |5 + net/ethernet/Makefile |3 + net/ethernet/mac-platform.c | 151 +++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 include/net/mac-platform.h create mode 100644 net/ethernet/mac-platform.c diff --git a/include/net/mac-platform.h b/include/net/mac-platform.h new file mode 100644 index 000..3a59098 --- /dev/null +++ b/include/net/mac-platform.h @@ -0,0 +1,39 @@ +/* + * mac-platform.h: Enforces platform-defined MAC for Async probed devices + */ + +#ifndef __NET_MAC_PLATFORM_H__ +#define __NET_MAC_PLATFORM_H__ + +#include linux/if_ether.h + +/** + * struct mac_platform - associates asynchronously probed device path with + * MAC address to be assigned to the device when it + * is created + * + * @device_path: device path name of network device + * @mac: MAC address to assign to network device matching device path + * @list: can be left uninitialized when passing from platform + */ + +struct mac_platform { + char *device_path; + u8 mac[ETH_ALEN]; + struct list_head list; /* unused in platform data usage */ +}; + +#ifdef CONFIG_NET +/** + * mac_platform_register_device_macs - add an array of device path to monitor + * and MAC to apply when the network device + * at the device path appears + * @macs: array of struct mac_platform terminated by entry with + * NULL device_path + */ +int mac_platform_register_device_macs(const struct mac_platform *macs); +#else +static inline int mac_platform_register_device_macs(macs) { return 0; } +#endif /* !CONFIG_NET */ + +#endif /* __NET_MAC_PLATFORM_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 245831b..487c9e6 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -335,9 +335,12 @@ source net/caif/Kconfig source net/ceph/Kconfig source net/nfc/Kconfig - endif # if NET +# used by board / dt platform to enforce MACs for Async-probed devices +config MAC_PLATFORM + bool + # Used by archs to tell that they support BPF_JIT config HAVE_BPF_JIT bool diff --git a/net/ethernet/Makefile b/net/ethernet/Makefile index 7cef1d8..475db2b 100644 --- a/net/ethernet/Makefile +++ b/net/ethernet/Makefile @@ -5,3 +5,6 @@ obj-y += eth.o obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o +ifneq ($(CONFIG_NET),) +obj-$(CONFIG_MAC_PLATFORM) += mac-platform.o +endif diff --git a/net/ethernet/mac-platform.c b/net/ethernet/mac-platform.c new file mode 100644 index 000..88e50ce --- /dev/null +++ b/net/ethernet/mac-platform.c @@ -0,0 +1,151 @@ +/* + * Helper to allow platform code to enforce association of a locally- + * administered MAC address automatically on asynchronously probed devices, + * such as SDIO and USB based devices. + * + * Because the device
[PATCH 4 3/4] OMAP4 PANDA register ethernet and wlan for automatic mac allocation
From: Andy Green a...@warmcat.com This provides the board-specific device paths needed to get the panda boardfile working with the mac-platform api. On Pandaboard / ES, neither the onboard Ethernet or onboard WLAN module have onboard arrangements for MAC storage, without this series yielding randomized MAC per-boot and consequent DHCP problems, or in the case of wlan0 a MAC set by a firmware file in the rootfs which unless customized yields a MAC of 00:00:00:00:00:00. No official MAC is reserved for either network device even if you do take the approach to customize the firmware file. This gets sane, consistent MAC addresses on both devices which should stand a good probability of differing between PandaBoards. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 + arch/arm/mach-omap2/board-omap4panda.c | 30 ++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 83fb31c..06fadf4 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -358,6 +358,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select MAC_PLATFORM config MACH_PCM049 bool OMAP4 based phyCORE OMAP4 diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb26..b028141 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,7 +32,10 @@ #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include net/mac-platform.h + #include mach/hardware.h +#include mach/id.h #include asm/hardware/gic.h #include asm/mach-types.h #include asm/mach/arch.h @@ -486,16 +489,43 @@ static void omap4_panda_init_rev(void) } } +/* + * These device paths represent onboard network devices which have + * no MAC address set at boot, and need synthetic ones assigning + */ +static __initdata struct mac_platform panda_mac_platform[] = { + + { /* smsc USB - Ethernet bridge */ + .device_path = usb1/1-1/1-1.1/1-1.1:1.0, + }, + { /* wlan0 module */ + .device_path = wl12xx, + }, + { /* terminator */ + } +}; + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; int ret; + int n; if (omap_rev() == OMAP4430_REV_ES1_0) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, NULL, package); omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + + /* +* provide MAC addresses computed from device ID for network +* devices that have no MAC address otherwise on Panda +*/ + for (n = 0; n ARRAY_SIZE(panda_mac_platform) - 1; n++) + omap_die_id_to_ethernet_mac(panda_mac_platform[n].mac, n); + if (mac_platform_register_device_macs(panda_mac_platform)) + pr_err(Unable to register mac_platform devices\n); + ret = wl12xx_set_platform_data(omap_panda_wlan_data); if (ret) pr_err(error setting wl12xx data: %d\n, ret); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4 4/4] config test config extending omap2plus with wl12xx etc
From: Andy Green a...@warmcat.com This is just provided for testing convenience, it has enough config options to get Ethernet and WL12xx driver on PandaBoard / ES up You should be able to reproduce something like this, with different MAC addresses. # ifconfig -a eth0 Link encap:Ethernet HWaddr 2e:20:3c:ea:46:01 inet addr:10.42.0.98 Bcast:10.42.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:13 errors:0 dropped:0 overruns:0 frame:0 TX packets:31 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1647 (1.6 KB) TX bytes:5534 (5.5 KB) loLink encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:100 (100.0 B) TX bytes:100 (100.0 B) wlan0 Link encap:Ethernet HWaddr 2e:60:3c:ea:46:01 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/configs/omap2plus_defconfig | 35 ++ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index f3087cb..7dcd384 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -2,13 +2,13 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,13 +20,12 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_OMAP=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_LEDS=y @@ -60,6 +59,7 @@ CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_CFG80211=m +CONFIG_LIB80211=m CONFIG_MAC80211=m CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_DEFAULT_PID=y @@ -87,22 +87,20 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_WL_TI=y +CONFIG_WL12XX=m +CONFIG_WLCORE_SDIO=m CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -131,14 +129,14 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y -CONFIG_REGULATOR_TWL4030=y +CONFIG_MFD_WL1273_CORE=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y @@ -153,7 +151,6 @@ CONFIG_PANEL_ACX565AKM=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -173,7 +170,6 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y @@ -212,23 +208,20 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More
Re: [PATCH 4 2/4] NET ethernet introduce mac_platform helper
On 05/07/12 11:12, the mail apparently from Joe Perches included: Thanks for the comments. This introduces a small helper in net/ethernet, which registers a network notifier at core_initcall time, and accepts registrations mapping expected asynchronously-probed network device paths (like, usb1/1-1/1-1.1/1-1.1:1.0) and the MAC that is needed to be assigned to the device when it appears. The mac prefix is poor. I think eth_mac is better. OK. diff --git a/net/ethernet/mac-platform.c b/net/ethernet/mac-platform.c [] +static int mac_platform_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) alignment to parenthesis please. OK. Although different places in the kernel seem to have different expectations about that. +int mac_platform_register_device_macs(const struct mac_platform *macs) +{ [] + next = kmalloc(sizeof(struct mac_platform), GFP_KERNEL); + if (!next) { + ret = -ENOMEM; + goto bail; + } + + next-device_path = kmalloc(strlen(macs-device_path) + 1, + GFP_KERNEL); + if (!next-device_path) { + ret = -ENOMEM; + goto bail; + } + + strcpy(next-device_path, macs-device_path); + memcpy(next-mac, macs-mac, sizeof macs-mac); kmemdup and kstrdup() OK + list_add(next-list, mac_platform_list); + + macs++; + } + +bail: + mutex_unlock(mac_platform_mutex); + + return ret; +} leaking memory on failures. Right... I'll fix these and wait for more comments. Thanks again for the review. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 0/4] Add ability to set defaultless network device MAC addresses to deterministic computed locally administered values
The following series adds some code to generate legal, locally administered MAC addresses from OMAP4 CPU Die ID fuse data, and then adds a helper at net/ethernet taking care of accepting device path / MAC mapping registrations and running a notifier to enforce the requested MAC when the matching network device turns up. On PandaBoard / ES, two devices have no board-level MAC either assigned by the manufacturer or stored on the board, the last patch in the series adds these device paths and gets them set when the network device is registered. Lastly for convenient testing, there's a little patch on omap2plus_defconfig that will get Ethernet and WLAN up on Pandaboard. The patches are against today's linux-omap. Thanks to Tony Lindgren and Arnd Bergmann for comments leading to the helper in net/ethernet. --- Andy Green (4): OMAP: add cpu id register to MAC address helper NET ethernet introduce mac_platform helper OMAP4 PANDA register ethernet and wlan for automatic mac allocation config test config extending omap2plus with wl12xx etc arch/arm/configs/omap2plus_defconfig | 35 +++ arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 30 ++ arch/arm/mach-omap2/id.c | 39 arch/arm/mach-omap2/include/mach/id.h |1 include/net/mac-platform.h | 39 net/Kconfig|5 + net/ethernet/Makefile |3 + net/ethernet/mac-platform.c| 151 9 files changed, 282 insertions(+), 22 deletions(-) create mode 100644 include/net/mac-platform.h create mode 100644 net/ethernet/mac-platform.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 1/4] OMAP: add cpu id register to MAC address helper
From: Andy Green a...@warmcat.com Introduce a generic helper function that can generate a valid MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:20:3c:ea:46:01 for the ethernet device on my PandaBoard ES. The MAC address space has space set aside for these kind of locally administered MAC addresses, analogous to IPv4 10.x.x.x range, and this patch marks the generated MAC addresses as such. The patch leaves two bits allowing elaborating 4 different MACs from the generated data. Signed-off-by: Andy Green andy.gr...@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Nicolas Pitre nicolas.pi...@linaro.org Tested-by: Steven Rostedt rost...@goodmis.org --- arch/arm/mach-omap2/id.c | 39 + arch/arm/mach-omap2/include/mach/id.h |1 + 2 files changed, 40 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 00486a8..faff686 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -530,3 +530,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast, and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h index 02ed3aa..d6c8d63 100644 --- a/arch/arm/mach-omap2/include/mach/id.h +++ b/arch/arm/mach-omap2/include/mach/id.h @@ -18,5 +18,6 @@ struct omap_die_id { }; void omap_get_die_id(struct omap_die_id *odi); +void omap_die_id_to_ethernet_mac(u8 *mac, int subtype); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 2/4] NET ethernet introduce mac_platform helper
From: Andy Green a...@warmcat.com This introduces a small helper in net/ethernet, which registers a network notifier at core_initcall time, and accepts registrations mapping expected asynchronously-probed network device paths (like, usb1/1-1/1-1.1/1-1.1:1.0) and the MAC that is needed to be assigned to the device when it appears. This allows platform code to enforce valid, consistent MAC addresses on to devices that have not been probed at boot-time, but due to being wired on the board are always present at the same interface. It has been tested with USB and SDIO probed devices. Other parts of this series provide an OMAP API that computes a valid locally administered MAC address from CPU ID bits that are unique for each physical SoC, and register those against devices wired to the board. This solves a longstanding problem in at least Panda case that there are no reserved MACs for either onboard Ethernet nor onboard WLAN module, and without this patch a randomized MAC is assigned to Ethernet and 00:00:00:00:00:00 or 0xdeadbeef is assigned as the WLAN MAC address. The series provides sane, constant locally-administered MAC addresses that have a high probability of differing between boards. To make use of this safely you also need to make sure that any drivers that may compete for the bus ordinal you are using (eg, mUSB and ehci in Panda case) are loaded in a deterministic order. At registration it makes a copy of the incoming data, so the data may be __initdata or otherwise transitory. Registration can be called multiple times so registrations from Device Tree and platform may be mixed. Since it needs to be called quite early in boot and there is no lifecycle for what it does, it could not be modular and is not a driver. Via suggestions from Arnd Bergmann and Tony Lindgren (and Alan Cox for the network notifier concept). Cc: net...@vger.kernel.org Cc: linux-ker...@vger.kernel.org Signed-off-by: Andy Green andy.gr...@linaro.org --- include/net/mac-platform.h | 39 +++ net/Kconfig |5 + net/ethernet/Makefile |3 + net/ethernet/mac-platform.c | 151 +++ 4 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 include/net/mac-platform.h create mode 100644 net/ethernet/mac-platform.c diff --git a/include/net/mac-platform.h b/include/net/mac-platform.h new file mode 100644 index 000..3a59098 --- /dev/null +++ b/include/net/mac-platform.h @@ -0,0 +1,39 @@ +/* + * mac-platform.h: Enforces platform-defined MAC for Async probed devices + */ + +#ifndef __NET_MAC_PLATFORM_H__ +#define __NET_MAC_PLATFORM_H__ + +#include linux/if_ether.h + +/** + * struct mac_platform - associates asynchronously probed device path with + * MAC address to be assigned to the device when it + * is created + * + * @device_path: device path name of network device + * @mac: MAC address to assign to network device matching device path + * @list: can be left uninitialized when passing from platform + */ + +struct mac_platform { + char *device_path; + u8 mac[ETH_ALEN]; + struct list_head list; /* unused in platform data usage */ +}; + +#ifdef CONFIG_NET +/** + * mac_platform_register_device_macs - add an array of device path to monitor + * and MAC to apply when the network device + * at the device path appears + * @macs: array of struct mac_platform terminated by entry with + * NULL device_path + */ +int mac_platform_register_device_macs(const struct mac_platform *macs); +#else +static inline int mac_platform_register_device_macs(macs) { return 0; } +#endif /* !CONFIG_NET */ + +#endif /* __NET_MAC_PLATFORM_H__ */ diff --git a/net/Kconfig b/net/Kconfig index 245831b..487c9e6 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -335,9 +335,12 @@ source net/caif/Kconfig source net/ceph/Kconfig source net/nfc/Kconfig - endif # if NET +# used by board / dt platform to enforce MACs for Async-probed devices +config MAC_PLATFORM + bool + # Used by archs to tell that they support BPF_JIT config HAVE_BPF_JIT bool diff --git a/net/ethernet/Makefile b/net/ethernet/Makefile index 7cef1d8..475db2b 100644 --- a/net/ethernet/Makefile +++ b/net/ethernet/Makefile @@ -5,3 +5,6 @@ obj-y += eth.o obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o +ifneq ($(CONFIG_NET),) +obj-$(CONFIG_MAC_PLATFORM) += mac-platform.o +endif diff --git a/net/ethernet/mac-platform.c b/net/ethernet/mac-platform.c new file mode 100644 index 000..88e50ce --- /dev/null +++ b/net/ethernet/mac-platform.c @@ -0,0 +1,151 @@ +/* + * Helper to allow platform code to enforce association of a locally- + * administered MAC address automatically on asynchronously probed devices, + * such as SDIO and USB based devices. + * + * Because the device
[PATCH 3 3/4] OMAP4 PANDA register ethernet and wlan for automatic mac allocation
From: Andy Green a...@warmcat.com This provides the board-specific device paths needed to get the panda boardfile working with the mac-platform api. On Pandaboard / ES, neither the onboard Ethernet or onboard WLAN module have onboard arrangements for MAC storage, without this series yielding randomized MAC per-boot and consequent DHCP problems, or in the case of wlan0 a MAC set by a firmware file in the rootfs which unless customized yields a MAC of 00:00:00:00:00:00. No official MAC is reserved for either network device even if you do take the approach to customize the firmware file. This gets sane, consistent MAC addresses on both devices which should stand a good probability of differing between PandaBoards. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 + arch/arm/mach-omap2/board-omap4panda.c | 30 ++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 5e95aa6..e17eed1 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -348,6 +348,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select MAC_PLATFORM config MACH_PCM049 bool OMAP4 based phyCORE OMAP4 diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb26..b028141 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,7 +32,10 @@ #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include net/mac-platform.h + #include mach/hardware.h +#include mach/id.h #include asm/hardware/gic.h #include asm/mach-types.h #include asm/mach/arch.h @@ -486,16 +489,43 @@ static void omap4_panda_init_rev(void) } } +/* + * These device paths represent onboard network devices which have + * no MAC address set at boot, and need synthetic ones assigning + */ +static __initdata struct mac_platform panda_mac_platform[] = { + + { /* smsc USB - Ethernet bridge */ + .device_path = usb1/1-1/1-1.1/1-1.1:1.0, + }, + { /* wlan0 module */ + .device_path = wl12xx, + }, + { /* terminator */ + } +}; + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; int ret; + int n; if (omap_rev() == OMAP4430_REV_ES1_0) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, NULL, package); omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + + /* +* provide MAC addresses computed from device ID for network +* devices that have no MAC address otherwise on Panda +*/ + for (n = 0; n ARRAY_SIZE(panda_mac_platform) - 1; n++) + omap_die_id_to_ethernet_mac(panda_mac_platform[n].mac, n); + if (mac_platform_register_device_macs(panda_mac_platform)) + pr_err(Unable to register mac_platform devices\n); + ret = wl12xx_set_platform_data(omap_panda_wlan_data); if (ret) pr_err(error setting wl12xx data: %d\n, ret); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 4/4] config test config extending omap2plus with wl12xx etc
From: Andy Green a...@warmcat.com This is just provided for testing convenience, it has enough config options to get Ethernet and WL12xx driver on PandaBoard / ES up You should be able to reproduce something like this, with different MAC addresses. # ifconfig -a eth0 Link encap:Ethernet HWaddr 2e:20:3c:ea:46:01 inet addr:10.42.0.98 Bcast:10.42.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:13 errors:0 dropped:0 overruns:0 frame:0 TX packets:31 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1647 (1.6 KB) TX bytes:5534 (5.5 KB) loLink encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:100 (100.0 B) TX bytes:100 (100.0 B) wlan0 Link encap:Ethernet HWaddr 2e:60:3c:ea:46:01 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/configs/omap2plus_defconfig | 35 ++ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index f3087cb..7dcd384 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -2,13 +2,13 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,13 +20,12 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_OMAP=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_LEDS=y @@ -60,6 +59,7 @@ CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_CFG80211=m +CONFIG_LIB80211=m CONFIG_MAC80211=m CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_DEFAULT_PID=y @@ -87,22 +87,20 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_WL_TI=y +CONFIG_WL12XX=m +CONFIG_WLCORE_SDIO=m CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -131,14 +129,14 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y -CONFIG_REGULATOR_TWL4030=y +CONFIG_MFD_WL1273_CORE=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y @@ -153,7 +151,6 @@ CONFIG_PANEL_ACX565AKM=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -173,7 +170,6 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y @@ -212,23 +208,20 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More
Re: [PATCH 2 2/4] net ethernet introduce mac_la_ap helper
On 07/03/12 00:12, the mail apparently from Arnd Bergmann included: On Monday 02 July 2012, Andy Green wrote: From: Andy Green a...@warmcat.com This introduces a small helper in net/ethernet, which registers a network notifier on init, and accepts registrations of expected asynchronously- Yes, looks good to me in principle. It needs to get sent to the linux-kernel and netdev mailing lists for review though. A few small comments. I wanted to hear that it had actually converged with what was being talked about first. I just sent out a v3 with the relevant patch also cc-d to those lists but stg mail didn't seem to send it to them. I'll wait for any further comments here and resend the whole thing including those lists. I find the name a bit non-obvious, not sure if we can come up with the perfect one. How about mac-platform? Done. endif # if NET This one needs to be either a silent option (only selected by the platforms that want it) or the header file has to provide a static-inline fallback that does nothing, so we don't get a build failure on platforms that need it if the option gets disabled. I'd prefer making it a silent option because then we don't bloat the kernel if someone accidentally enables it on a platform that does not use it. Done. It's already added as a select on the Panda board config. I also moved it out of the if NET clause and took care about the case that CONFIG_NET is off but we still have mac-platform references. +static struct mac_la_ap mac_la_ap_list; The normal way to do this is to have just a list head that the entries get added to: static LIST_HEAD(mac_la_ap_list); That also takes care of the initialization. Thanks for normalizing it, done. +DEFINE_MUTEX(mac_la_ap_mutex); +bool mac_la_ap_started; These should all be static. Right, done. I think it would be simpler to register the notifier from an initcall and drop the mac_la_ap_started variable. That was my first approach, to structure it as a real driver. I had tried a few likely-looking initcall levels but the init of the helper was coming after the init of the network code. I found this time that core_initcall works, so I used that, dropped the flag. But isn't it a bit tricky with these to know if the prerequisite you're trying to ensure is already initialized might not actually be at the same initcall level and you're working by accident? +int mac_la_ap_register_device_macs(const struct mac_la_ap *macs) +{ +} +EXPORT_SYMBOL_GPL(mac_la_ap_register_device_macs); I'm not sure if there is any point in exporting this function, my feeling is that it would only ever be called from built-in code. If we can call it from a module, we should probably also allow this file to be a loadable module as well. Being a modular API for platform code to call doesn't make sense, I got rid of the export. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2 0/4] Add ability to set defaultless network device MAC addresses to deterministic computed locally administered values
The following series adds some code to generate legal, locally administered MAC addresses from OMAP4 CPU Die ID fuse data, and then adds a helper at net/ethernet taking care of accepting device path / MAC mapping registrations and running a notifier to enforce the requested MAC when the matching network device turns up. On PandaBoard / ES, two devices have no board-level MAC either assigned by the manufacturer or stored on the board, the last patch in the series adds these device paths and gets them set when the network device is registered. Lastly for convenient testing, there's a little patch on omap2plus_defconfig that will get Ethernet and WLAN up on Pandaboard. The patches are against today's linux-omap. Thanks to Tony Lindgren and Arnd Bergmann for comments leading to the helper in net/ethernet. --- Andy Green (4): OMAP2+: add cpu id register to MAC address helper net ethernet introduce mac_la_ap helper OMAP4 PANDA register ethernet and wlan for automatic mac allocation config test config extending omap2plus with wl12xx etc arch/arm/configs/omap2plus_defconfig | 35 +++ arch/arm/mach-omap2/Kconfig|1 arch/arm/mach-omap2/board-omap4panda.c | 30 ++ arch/arm/mach-omap2/id.c | 39 arch/arm/mach-omap2/include/mach/id.h |1 include/net/mac-la-ap.h| 28 + net/Kconfig| 14 +++ net/ethernet/Makefile |2 net/ethernet/mac-la-ap.c | 165 9 files changed, 294 insertions(+), 21 deletions(-) create mode 100644 include/net/mac-la-ap.h create mode 100644 net/ethernet/mac-la-ap.c -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2 1/4] OMAP2+: add cpu id register to MAC address helper
From: Andy Green a...@warmcat.com Introduce a generic helper function that can generate a valid MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:20:3c:ea:46:01 for the ethernet device on my PandaBoard ES. The MAC address space has space set aside for these kind of locally administered MAC addresses, analogous to IPv4 10.x.x.x range, and this patch marks the generated MAC addresses as such. The patch leaves two bits allowing elaborating 4 different MACs from the generated data. Signed-off-by: Andy Green andy.gr...@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Nicolas Pitre nicolas.pi...@linaro.org Tested-by: Steven Rostedt rost...@goodmis.org --- arch/arm/mach-omap2/id.c | 39 + arch/arm/mach-omap2/include/mach/id.h |1 + 2 files changed, 40 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 00486a8..2a44c42 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -530,3 +530,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast, and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h index 02ed3aa..373313a 100644 --- a/arch/arm/mach-omap2/include/mach/id.h +++ b/arch/arm/mach-omap2/include/mach/id.h @@ -18,5 +18,6 @@ struct omap_die_id { }; void omap_get_die_id(struct omap_die_id *odi); +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2 2/4] net ethernet introduce mac_la_ap helper
From: Andy Green a...@warmcat.com This introduces a small helper in net/ethernet, which registers a network notifier on init, and accepts registrations of expected asynchronously- probed network device paths (like, usb1/1-1/1-1.1/1-1.1:1.0) and the MAC that is needed to be assigned to the device when it appears. This allows platform code to enforce valid, consistent MAC addresses on to devices that have not been probed at boot-time, but due to being wired on the board are always present at the same interface. It has been tested with USB and SDIO probed devices. To make use of this safely you also need to make sure that any drivers that may compete for the bus ordinal you are using (eg, mUSB and ehci in Panda case) are loaded in a deterministic order. At registration it makes a copy of the incoming data, so the data may be __initdata or otherwise transitory. Registration can be called multiple times so registrations from Device Tree and platform may be mixed. Since it needs to be called quite early in boot and there is no lifecycle for what it does, it could not be modular and is not a driver. Via suggestions from Arnd Bergmann and Tony Lindgren. Signed-off-by: Andy Green andy.gr...@linaro.org --- include/net/mac-la-ap.h | 28 net/Kconfig | 14 net/ethernet/Makefile|2 + net/ethernet/mac-la-ap.c | 165 ++ 4 files changed, 209 insertions(+) create mode 100644 include/net/mac-la-ap.h create mode 100644 net/ethernet/mac-la-ap.c diff --git a/include/net/mac-la-ap.h b/include/net/mac-la-ap.h new file mode 100644 index 000..d5189b5 --- /dev/null +++ b/include/net/mac-la-ap.h @@ -0,0 +1,28 @@ +/* + * mac-la-ap.h: Locally Administered MAC address for Async probed devices + */ + +/** + * struct mac_la_ap - associates asynchronously probed device path with + * MAC address to be assigned to the device when it + * is created + * + * @device_path: device path name of network device + * @mac: MAC address to assign to network device matching device path + * @list: can be left uninitialized when passing from platform + */ + +struct mac_la_ap { + char *device_path; + u8 mac[6]; + struct list_head list; /* unused in platform data usage */ +}; + +/** + * mac_la_ap_register_device_macs - add an array of device path to monitor + * and MAC to apply when the network device + * at the device path appears + * @macs: array of struct mac_la_ap terminated by entry with NULL device_path + */ +int mac_la_ap_register_device_macs(const struct mac_la_ap *macs); + diff --git a/net/Kconfig b/net/Kconfig index 245831b..76ba70e 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -335,6 +335,20 @@ source net/caif/Kconfig source net/ceph/Kconfig source net/nfc/Kconfig +config MAC_LA_AP + bool Locally Administered MAC for Aysnchronously Probed devices + ---help--- + This helper allows platforms to mandate a locally-administered + sythesized MAC address for network devices that are on asynchronously- + probed buses like USB or SDIO. This is necessary when the board has + these network assets but no arrangements for storing or setting the + MAC address of the network asset (nor any official MAC address + reserved for the device). In that case, seen in Panda and other + boards, the platform can synthesize a constant locally-administered + MAC address from SoC UID bits that has a good probability of differing + between boards but will be constant on any give board. This helper + will take care of watching for the network devices to appear and + force the MAC to the synthesized one when they do. endif # if NET diff --git a/net/ethernet/Makefile b/net/ethernet/Makefile index 7cef1d8..94ee883 100644 --- a/net/ethernet/Makefile +++ b/net/ethernet/Makefile @@ -5,3 +5,5 @@ obj-y += eth.o obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o +obj-$(CONFIG_MAC_LA_AP)+= mac-la-ap.o + diff --git a/net/ethernet/mac-la-ap.c b/net/ethernet/mac-la-ap.c new file mode 100644 index 000..4216c41 --- /dev/null +++ b/net/ethernet/mac-la-ap.c @@ -0,0 +1,165 @@ +/* + * Helper to allow setting locally-administered MAC addresses automatically on + * asynchronously probed devices, such as SDIO and USB based devices. + * + * Because the device path is used for matching, this is only useful for + * network assets physcally wired on the board, and also requires any + * different drivers that can compete for bus ordinals (eg mUSB vs ehci) to + * have fixed initialization ordering, eg, by having ehci in monolithic + * kernel + * + * Neither a driver nor a module as needs to be callable from machine file + * before the network devices are registered. + * + * (c) 2012 Andy
[PATCH 2 3/4] OMAP4 PANDA register ethernet and wlan for automatic mac allocation
From: Andy Green a...@warmcat.com This provides the board-specific device paths needed to get the panda boardfile working with the mac-la-ap api. On Pandaboard / ES, neither the onboard Ethernet or onboard WLAN module have onboard arrangements for MAC storage, without this series yielding randomized MAC per-boot and consequent DHCP problems, or in the case of wlan0 a MAC set by a firmware file in the rootfs which unless customized yields a MAC of 00:00:00:00:00:00. No official MAC is reserved for either network device even if you do take the approach to customize the firmware file. This gets sane, consistent MAC addresses on both devices which should stand a good probability of differing between PandaBoards. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/Kconfig|1 + arch/arm/mach-omap2/board-omap4panda.c | 30 ++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 5e95aa6..d968e7f 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -348,6 +348,7 @@ config MACH_OMAP4_PANDA select OMAP_PACKAGE_CBL select OMAP_PACKAGE_CBS select REGULATOR_FIXED_VOLTAGE if REGULATOR + select MAC_LA_AP config MACH_PCM049 bool OMAP4 based phyCORE OMAP4 diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb26..8f4984b 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -32,7 +32,10 @@ #include linux/wl12xx.h #include linux/platform_data/omap-abe-twl6040.h +#include net/mac-la-ap.h + #include mach/hardware.h +#include mach/id.h #include asm/hardware/gic.h #include asm/mach-types.h #include asm/mach/arch.h @@ -486,16 +489,43 @@ static void omap4_panda_init_rev(void) } } +/* + * These device paths represent onboard network devices which have + * no MAC address set at boot, and need synthetic ones assigning + */ +static __initdata struct mac_la_ap panda_mac_la_ap[] = { + + { /* smsc USB - Ethernet bridge */ + .device_path = usb1/1-1/1-1.1/1-1.1:1.0, + }, + { /* wlan0 module */ + .device_path = wl12xx, + }, + { /* terminator */ + } +}; + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; int ret; + int n; if (omap_rev() == OMAP4430_REV_ES1_0) package = OMAP_PACKAGE_CBL; omap4_mux_init(board_mux, NULL, package); omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + + /* +* provide MAC addresses computed from device ID for network +* devices that have no MAC address otherwise on Panda +*/ + for (n = 0; n ARRAY_SIZE(panda_mac_la_ap) - 1; n++) + omap2_die_id_to_ethernet_mac(panda_mac_la_ap[n].mac, n); + if (mac_la_ap_register_device_macs(panda_mac_la_ap)) + pr_err(Unable to register mac_la_ap devices\n); + ret = wl12xx_set_platform_data(omap_panda_wlan_data); if (ret) pr_err(error setting wl12xx data: %d\n, ret); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2 4/4] config test config extending omap2plus with wl12xx etc
From: Andy Green a...@warmcat.com This is just provided for testing convenience, it has enough config options to get Ethernet and WL12xx driver on PandaBoard / ES up You should be able to reproduce something like this, with different MAC addresses. # ifconfig -a eth0 Link encap:Ethernet HWaddr 2e:20:3c:ea:46:01 inet addr:10.42.0.98 Bcast:10.42.0.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:13 errors:0 dropped:0 overruns:0 frame:0 TX packets:31 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1647 (1.6 KB) TX bytes:5534 (5.5 KB) loLink encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:2 errors:0 dropped:0 overruns:0 frame:0 TX packets:2 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:100 (100.0 B) TX bytes:100 (100.0 B) wlan0 Link encap:Ethernet HWaddr 2e:60:3c:ea:46:01 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/configs/omap2plus_defconfig | 35 ++ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index f3087cb..7dcd384 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -2,13 +2,13 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_BSD_PROCESS_ACCT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS_EXTRA_PASS=y CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y @@ -20,13 +20,12 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_OMAP=y CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_MUX_DEBUG=y CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_LEDS=y @@ -60,6 +59,7 @@ CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_CFG80211=m +CONFIG_LIB80211=m CONFIG_MAC80211=m CONFIG_MAC80211_RC_PID=y CONFIG_MAC80211_RC_DEFAULT_PID=y @@ -87,22 +87,20 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_MD=y CONFIG_NETDEVICES=y -CONFIG_SMSC_PHY=y -CONFIG_NET_ETHERNET=y -CONFIG_SMC91X=y -CONFIG_SMSC911X=y CONFIG_KS8851=y CONFIG_KS8851_MLL=y -CONFIG_LIBERTAS=m -CONFIG_LIBERTAS_USB=m -CONFIG_LIBERTAS_SDIO=m -CONFIG_LIBERTAS_DEBUG=y +CONFIG_SMC91X=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_EPSON2888=y CONFIG_USB_KC2190=y +CONFIG_WL_TI=y +CONFIG_WL12XX=m +CONFIG_WLCORE_SDIO=m CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y @@ -131,14 +129,14 @@ CONFIG_POWER_SUPPLY=y CONFIG_WATCHDOG=y CONFIG_OMAP_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y -CONFIG_REGULATOR_TWL4030=y +CONFIG_MFD_WL1273_CORE=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y +CONFIG_REGULATOR_TWL4030=y CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP_LCD_VGA=y CONFIG_OMAP2_DSS=m CONFIG_OMAP2_DSS_RFBI=y CONFIG_OMAP2_DSS_SDI=y @@ -153,7 +151,6 @@ CONFIG_PANEL_ACX565AKM=m CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y -CONFIG_DISPLAY_SUPPORT=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y @@ -173,7 +170,6 @@ CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m CONFIG_USB=y CONFIG_USB_DEBUG=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_DEVICEFS=y CONFIG_USB_SUSPEND=y CONFIG_USB_MON=y CONFIG_USB_EHCI_HCD=y @@ -212,23 +208,20 @@ CONFIG_JFFS2_RUBIN=y CONFIG_UBIFS_FS=y CONFIG_CRAMFS=y CONFIG_NFS_FS=y -CONFIG_NFS_V3=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y -CONFIG_PARTITION_ADVANCED=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_KERNEL=y CONFIG_SCHEDSTATS=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_DEBUG_INFO=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set +CONFIG_DEBUG_LL=y +CONFIG_EARLY_PRINTK=y CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y # CONFIG_CRYPTO_ANSI_CPRNG is not set -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More
Re: [PATCH 2/3] OMAP2+ devices add mac address allocation register api
On 06/29/12 16:51, the mail apparently from Arnd Bergmann included: On Friday 29 June 2012, Andy Green wrote: +static int omap_panda_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + struct sockaddr sa; + int n; + + if (event != NETDEV_REGISTER) + return NOTIFY_DONE; + + n = omap_device_path_need_mac(dev-dev.parent); + if (n 0) + return NOTIFY_DONE; + + sa.sa_family = dev-type; + omap2_die_id_to_ethernet_mac(sa.sa_data, n); + dev-netdev_ops-ndo_set_mac_address(dev, sa); + + return NOTIFY_DONE; +} + +static struct notifier_block omap_panda_netdev_notifier = { + .notifier_call = omap_panda_netdev_event, + .priority = 1, +}; + +int omap_register_mac_device_fixup_paths(const char * const *paths, int count) +{ + mac_device_fixup_paths = paths; + count_mac_device_fixup_paths = count; + + return register_netdevice_notifier(omap_panda_netdev_notifier); +} The omap_panda_netdev_event and omap_panda_netdev_notifier symbols should probably lose the panda_ part of their names, because they are now located in a common file and are not panda specific any more. Good point thanks, I'll sort it out after waiting for any more comments. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] OMAP2+: add cpu id register to MAC address helper
On 06/29/12 17:05, the mail apparently from Tony Lindgren included: * Andy Green andy.gr...@linaro.org [120628 22:59]: Introduce a generic helper function that can generate a valid MAC address using data from the OMAP unique CPU ID register. ... --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -530,3 +530,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast, and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} Let's just make this omap_die_id_to_ethernet_mac, no need to keep the omap2 naming there as this should not conflict with any omap1 stuff. Okay, will do thanks. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] OMAP2+ devices add mac address allocation register api
On 06/29/12 17:40, the mail apparently from Tony Lindgren included: * Andy Green andy.gr...@linaro.org [120628 22:59]: From: Andy Green a...@warmcat.com This exposes a new API in devices.c that lets a board register a list of device paths representing network devices that have no arrangements for their MAC address to be set by the board. It watches network device registrations via a notifier and gives the devices requiring them a synthetic - but constant for a given board - MAC address immediately. ... --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -39,6 +42,9 @@ #define L3_MODULES_MAX_LEN 12 #define L3_MODULES 3 +static const char * const *mac_device_fixup_paths; +int count_mac_device_fixup_paths; This too should be static it seems to me. Or just make the paths array NULL terminated to get rid of the count. static int __init omap3_l3_init(void) { struct omap_hwmod *oh; @@ -627,6 +633,89 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +static int omap_device_path_need_mac(struct device *dev) +{ + const char **try = (const char **)mac_device_fixup_paths; This cast you should be able to remove by setting the types right to start with? I guess so, I recall meddling with it and throwing a cast at it. + const char *path; + int count = count_mac_device_fixup_paths; + const char *p; + int len; + struct device *devn; + + while (count--) { + + p = *try + strlen(*try); + devn = dev; + + while (devn) { + + path = dev_name(devn); + len = strlen(path); + + if ((p - *try) len) { + devn = NULL; + continue; + } + + p -= len; + + if (strncmp(path, p, len)) { + devn = NULL; + continue; + } + + devn = devn-parent; + if (p == *try) + return count; + + if (devn != NULL (p - *try) 2) + devn = NULL; + + p--; + if (devn != NULL *p != '/') + devn = NULL; + } + + try++; + } + + return -ENOENT; +} I don't quite like having this device parsing code here. This should probably be a generic helper function somewhere under drivers. I would assume other SoCs could use it too? OK... is it a job for drivers/misc or is there a better idea? +static int omap_panda_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + struct sockaddr sa; + int n; + + if (event != NETDEV_REGISTER) + return NOTIFY_DONE; + + n = omap_device_path_need_mac(dev-dev.parent); + if (n 0) + return NOTIFY_DONE; + + sa.sa_family = dev-type; + omap2_die_id_to_ethernet_mac(sa.sa_data, n); + dev-netdev_ops-ndo_set_mac_address(dev, sa); + + return NOTIFY_DONE; +} + +static struct notifier_block omap_panda_netdev_notifier = { + .notifier_call = omap_panda_netdev_event, + .priority = 1, +}; This is a bit similar to platform data callback functions that we are trying to get rid of. And as the question how do we replace platform data callback functions is still open for things like this, few questions come to mind that should be discussed: 1. How is this a better solution to passing the generated mac address in platform data to the driver? Well, I initially did this over a year ago as a generic way to pass platform data to devices that are appearing through deferred or async probing, like USB bus and SDIO bus. It was not understood what the goal was by the people looking after those subsystems. 2. Is this really how we want to pass the board generated mac addresses and other dynamically generated data to the drivers that are device tree based? The issue is that both these busses have an async probe, in the case of USB stack the maintainer was not interested last year in adding platform data. Maybe it changed but that's my understanding. 3. What about mac address in board-generic.c when booting panda with device tree? I don't mind adapting it for that case. Also, what happens if the user has set the mac address and you replugs the cable or device? Do we now overwrite it? Might be worth checking that this follows the standard behaviour.. This is only useful for devices that are soldered on your board, and have deterministic device paths as is the case with Panda Ethernet and Wlan module that both benefit from this treatment. If you
Re: [PATCH 2/3] OMAP2+ devices add mac address allocation register api
On 06/29/12 21:55, the mail apparently from Tony Lindgren included: * Arnd Bergmann a...@arndb.de [120629 06:50]: On Friday 29 June 2012, Tony Lindgren wrote: * Andy Green andy.gr...@linaro.org [120629 03:12]: 2. Is this really how we want to pass the board generated mac addresses and other dynamically generated data to the drivers that are device tree based? The issue is that both these busses have an async probe, in the case of USB stack the maintainer was not interested last year in adding platform data. Maybe it changed but that's my understanding. OK, I'd like to hear Arnds comments on the #2 above too as this is a more generic issue. In case we have a device tree, we should just be using the USB binding to find the specific device node, and add the property there. Then the device driver can use of_get_mac_address() on the usb device itself. But would you generate the mac address then in the bootloader already? I'm pretty sure correct answer does not introduce more dependencies on bootloader code. I'm not sure what it takes to add the link for the device node in the usb probing code, but my feeling is that it's not too hard. Right now, USB is probed entirely without DT, so the patch is about the best we can do. Right, but that still assumes a static mac from the bootloader unless we do a generic driver as below? Or do you have some other ideas? What happens without this patch is randomized MAC address assigned by Linux in smsc Ethernet case. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] OMAP2+ devices add mac address allocation register api
On 06/29/12 21:45, the mail apparently from Arnd Bergmann included: On Friday 29 June 2012, Tony Lindgren wrote: * Andy Green andy.gr...@linaro.org [120629 03:12]: 2. Is this really how we want to pass the board generated mac addresses and other dynamically generated data to the drivers that are device tree based? The issue is that both these busses have an async probe, in the case of USB stack the maintainer was not interested last year in adding platform data. Maybe it changed but that's my understanding. OK, I'd like to hear Arnds comments on the #2 above too as this is a more generic issue. In case we have a device tree, we should just be using the USB binding to find the specific device node, and add the property there. Then the device driver can use of_get_mac_address() on the usb device itself. I'm not sure what it takes to add the link for the device node in the usb probing code, but my feeling is that it's not too hard. Right now, USB is probed entirely without DT, so the patch is about the best we can do. Yes none of this was really hard the problem with more generic approach was getting comprehension and not auto-reject at the other subsystems. To be fair USB is USB and DT is Arm-specific issue. 3. What about mac address in board-generic.c when booting panda with device tree? I don't mind adapting it for that case. Just to try to think about some alternatives, how about something like this: This all could be a driver called soft-mac or something that does what your patches are doing. Except then it would be completely generic and would be able to take device names and mac addresses from platform data or from devicetree. That driver would be completely generic to all platforms, but be very specific to finding the mac address of a device, as opposed to other properties. I suspect that if we do that, we will still need a way to bind a device_node to a usb device for the purpose of finding other properties, such as external regulators or clocks that are connected to a hardwired USB device. There's no standardized exposure of logical regulators over USB afaik so you won't be able to 'find' them without a VID:PID -bound specific driver that already knew about them. Normally USB tends to just work because the device is expected to be hot-pluggable anyway. If the USB device is soldered to the board, the hardware designers can take some shortcuts Tony's point about modularized host drivers coming in random order seems to be a fair one. We don't build ehci modular so we don't care about it but from maintainer pov it's a legit issue. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] OMAPDSS: HDMI: Cache EDID
On 06/28/12 19:10, the mail apparently from Tomi Valkeinen included: On Thu, 2012-06-28 at 16:28 +0530, Jassi Brar wrote: On 28 June 2012 16:17, Jassi Brar jaswinder.si...@linaro.org wrote: On 28 June 2012 15:44, Tomi Valkeinen tomi.valkei...@ti.com wrote: On Thu, 2012-06-28 at 15:18 +0530, Jassi Brar wrote: --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -243,10 +243,13 @@ static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data) hpd = gpio_get_value(ip_data-hpd_gpio); - if (hpd) + if (hpd) { r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); - else + } else { + /* Invalidate EDID Cache */ + ip_data-edid_len = 0; r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); + } There's a problem with this patch, which leaves a wrong EDID in the cache: if you first have the cable connected and hdmi is enabled, you then turn off the HDMI display device via sysfs, we do not go to hdmi_check_hpd_state at all. The next time hdmi is enabled, we only get the plug-in event, and thus EDID cache is never invalidated. If the hdmi cable is not replugged during that period, I don't see why would you want the EDID invalidated ? I wasn't very clear with my comment. When the display device is disabled, we're not listening to the hpd interrupt anymore. So when it's disabled, the cable can be replugged and the monitor changed, and the driver won't know about it. And so it'll return the old EDID for the new monitor. If that could be a problem, then we already have some problem with current omapdss. I think among the first things, while enabling HDMI, should be to see if there is really some display connected on the port i.e, HPD asserted. Only if ti_hdmi_4_detect() returned true, should we proceed otherwise wait for HPQ irq. Unconditionally invalidating edid really seems like a regression - we impose atleast 50ms (edid read) as extra cost on hdmi_check_hpd_state(), which kills half the purpose of this patch. Sorry a correction. Reading detect() won't work. I suggest we keep HPD IRQ enabled for the lifetime of the driver. Ok, I see. But that's not acceptable. It would require us to keep the TPD12S015 always powered and enabled. Even if you're not interested in using HDMI at all. For this to work like you want we need a bigger restructuring of HDMI and partly omapdss also. Currently we have just one big enabled or disabled state. We need multiple states. Probably something like: - disabled, everything totally off - low power, hotplug detection enabled - powered on, but no video - video enabled Been long in my mind, but I'm not very familiar with HDMI so I could get my simple prototypes to work when I tried something like this once. That doesn't sound too hard since the difference between the first three states at the HDMI chip is just whether the two gpio controlling it are 00, 10 or 11. If Jassi's alright with it we might have a go at implementing this, but can you define a bit more about how we logically tell DSS that we want to, eg, disable HDMI totally? -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] OMAPDSS: HDMI: Cache EDID
On 06/28/12 19:38, the mail apparently from Tomi Valkeinen included: On Thu, 2012-06-28 at 14:10 +0300, Tomi Valkeinen wrote: On Thu, 2012-06-28 at 16:28 +0530, Jassi Brar wrote: Sorry a correction. Reading detect() won't work. I suggest we keep HPD IRQ enabled for the lifetime of the driver. Ok, I see. But that's not acceptable. It would require us to keep the TPD12S015 always powered and enabled. Even if you're not interested in using HDMI at all. Btw, a bigger problem that I see is how we have to do read_edid() (and detect(), if I recall correctly): we enable the whole video pipeline and output. We should only enable enough of the HW to be able to read the EDID or read the HPD GPIO. I've noticed that this leads to sync losts quite easily, as we switch the hdmi output on and off quickly multiple times. I couldn't figure out why the sync losts happen though, and I did try quite many different combinations how to handle it. SYNC LOST is one evil lurking in there, the other evil is EDID fetch operation stopped error. We were unable to figure out what was trampling on what there without the SoC HDMI PHY IP data which we don't have. Also at the moment I think we depower / repower the internal SoC and external PHY chip more than we need. Each time we remove the HDMI link power, after a short time where the big capacitor at the charge pump output decays enough (a time dependent on exact details of load presented by the TV or monitor...), hpd from the monitor goes low and remains there until we power the charge pump again. In turn the new hpd recognition provokes a new edid fetch. Something about that sequence provokes the operation stopped on EDID fetch, with Jassi's patches we manage to avoid it. Removing that syndrome, and just not enabling and disabling stuff like SoC HDMI PHY willy nilly can maybe be something else targeted by this proposed 4-state power scheme. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 0/2] OMAP2+: PANDA: Provide unique-ish MAC addresses for Ethernet and WLAN interfaces
On 06/28/12 22:45, the mail apparently from Steven Rostedt included: On Thu, 2012-06-28 at 14:18 +, Arnd Bergmann wrote: It's been a while since we discussed these patches, but Steven Rostedt just tripped over the same problem and the patches work for him, so he says Tested-by: Steven Rostedt rost...@goodmis.org. Can we get the patches into linux-3.6 please? Yes please. Right now I have my ktest.pl setup adding these patches before running tests. I really dislike having to modify a kernel that I'm testing, because I'm not really testing that said kernel, but a modified version of it. Guys I am glad you're finding the patches useful; I've been using them in the Linaro TI Lnding Team trees ever since. I adapted them a bit to live mainly in devices.c, tomorrow I'll send this version cleaned up and we can deal with any further changes needed hopefully quickly. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] Add ability to set defaultless network device MAC addresses to deterministic computed locally administered values
The following series adds some code to generate legal, locally administered MAC addresses from OMAP4 CPU Die ID fuse data, and then adds an api to devices.c allowing board files to register device paths for network devices that wish to use them. On PandaBoard / ES, two devices have no board-level MAC either assigned by the manufacturer or stored on the board, the last patch in the series adds these device paths and gets them set when the network device is registered. The patches are against today's linux-omap. --- Andy Green (3): OMAP2+: add cpu id register to MAC address helper OMAP2+ devices add mac address allocation register api OMAP4 PANDA register ethernet and wlan for automatic mac allocation arch/arm/mach-omap2/board-omap4panda.c | 13 + arch/arm/mach-omap2/common.h |2 + arch/arm/mach-omap2/devices.c | 89 arch/arm/mach-omap2/id.c | 39 ++ arch/arm/mach-omap2/include/mach/id.h |1 5 files changed, 144 insertions(+) -- Signature -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] OMAP2+: add cpu id register to MAC address helper
From: Andy Green a...@warmcat.com Introduce a generic helper function that can generate a valid MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:40:70:f0:12:06 for the ethernet device on my Panda. The MAC address space has space set aside for these kind of locally administered MAC addresses, analogous to IPv4 10.x.x.x range, and this patch marks the generated MAC addresses as such. The patch leaves two bits allowing elaborating 4 different MACs from the generated data. Signed-off-by: Andy Green andy.gr...@linaro.org Acked-by: Arnd Bergmann a...@arndb.de Signed-off-by: Nicolas Pitre nicolas.pi...@linaro.org Tested-by: Steven Rostedt rost...@goodmis.org --- arch/arm/mach-omap2/id.c | 39 + arch/arm/mach-omap2/include/mach/id.h |1 + 2 files changed, 40 insertions(+) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 00486a8..2a44c42 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -530,3 +530,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast, and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h index 02ed3aa..373313a 100644 --- a/arch/arm/mach-omap2/include/mach/id.h +++ b/arch/arm/mach-omap2/include/mach/id.h @@ -18,5 +18,6 @@ struct omap_die_id { }; void omap_get_die_id(struct omap_die_id *odi); +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] OMAP2+ devices add mac address allocation register api
From: Andy Green a...@warmcat.com This exposes a new API in devices.c that lets a board register a list of device paths representing network devices that have no arrangements for their MAC address to be set by the board. It watches network device registrations via a notifier and gives the devices requiring them a synthetic - but constant for a given board - MAC address immediately. This approach is compatible with devices with asynchronous probe such as the USB-based Etherent PHY and SDIO-based wlan module found on PandaBoard / ES. It has also been tested on PandaBoard 5 successfully but that support is not part of this series. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/common.h |2 + arch/arm/mach-omap2/devices.c | 89 + 2 files changed, 91 insertions(+) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 5d99c1b..ae4d8a9 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -116,6 +116,8 @@ static inline int omap_mux_late_init(void) #endif extern void omap2_init_common_infrastructure(void); +extern int omap_register_mac_device_fixup_paths(const char * const *paths, + int count); extern struct sys_timer omap2_timer; extern struct sys_timer omap3_timer; diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 91ef6699..d0a3d2d 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -18,12 +18,15 @@ #include linux/slab.h #include linux/of.h #include linux/platform_data/omap4-keypad.h +#include linux/netdevice.h +#include linux/if_ether.h #include mach/hardware.h #include mach/irqs.h #include asm/mach-types.h #include asm/mach/map.h #include asm/pmu.h +#include mach/id.h #include iomap.h #include plat/board.h @@ -39,6 +42,9 @@ #define L3_MODULES_MAX_LEN 12 #define L3_MODULES 3 +static const char * const *mac_device_fixup_paths; +int count_mac_device_fixup_paths; + static int __init omap3_l3_init(void) { struct omap_hwmod *oh; @@ -627,6 +633,89 @@ static void omap_init_vout(void) static inline void omap_init_vout(void) {} #endif +static int omap_device_path_need_mac(struct device *dev) +{ + const char **try = (const char **)mac_device_fixup_paths; + const char *path; + int count = count_mac_device_fixup_paths; + const char *p; + int len; + struct device *devn; + + while (count--) { + + p = *try + strlen(*try); + devn = dev; + + while (devn) { + + path = dev_name(devn); + len = strlen(path); + + if ((p - *try) len) { + devn = NULL; + continue; + } + + p -= len; + + if (strncmp(path, p, len)) { + devn = NULL; + continue; + } + + devn = devn-parent; + if (p == *try) + return count; + + if (devn != NULL (p - *try) 2) + devn = NULL; + + p--; + if (devn != NULL *p != '/') + devn = NULL; + } + + try++; + } + + return -ENOENT; +} + +static int omap_panda_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + struct sockaddr sa; + int n; + + if (event != NETDEV_REGISTER) + return NOTIFY_DONE; + + n = omap_device_path_need_mac(dev-dev.parent); + if (n 0) + return NOTIFY_DONE; + + sa.sa_family = dev-type; + omap2_die_id_to_ethernet_mac(sa.sa_data, n); + dev-netdev_ops-ndo_set_mac_address(dev, sa); + + return NOTIFY_DONE; +} + +static struct notifier_block omap_panda_netdev_notifier = { + .notifier_call = omap_panda_netdev_event, + .priority = 1, +}; + +int omap_register_mac_device_fixup_paths(const char * const *paths, int count) +{ + mac_device_fixup_paths = paths; + count_mac_device_fixup_paths = count; + + return register_netdevice_notifier(omap_panda_netdev_notifier); +} + /*-*/ static int __init omap2_init_devices(void) -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] OMAP4 PANDA register ethernet and wlan for automatic mac allocation
From: Andy Green a...@warmcat.com This provides the board-specific device paths needed to get the panda boardfile working with the MAC address fixup api. On Pandaboard / ES, neither the onboard Ethernet or onboard WLAN module have onboard arrangements for MAC storage, without this series yielding randomized MAC per-boot and consequent DHCP problems, or in the case of wlan0 a MAC set by a firmware file in the rootfs which unless customized yields a MAC of 00:00:00:00:00:00. No official MAC is reserved for either network device even if you do take the approach to customize the firmware file. This gets sane, consistent MAC addresses on both devices which should stand a good probability of differing between PandaBoards. Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/board-omap4panda.c | 13 + 1 file changed, 13 insertions(+) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 982fb26..07a17b0 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -486,6 +486,15 @@ static void omap4_panda_init_rev(void) } } +/* + * These device paths represent onboard network devices which have + * no MAC address set at boot, and need synthetic ones assigning + */ +static const char * const panda_fixup_mac_device_paths[] = { + usb1/1-1/1-1.1/1-1.1:1.0, /* smsc USB - Ethernet bridge */ + wl12xx, /* wlan0 module */ +}; + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; @@ -496,6 +505,10 @@ static void __init omap4_panda_init(void) omap4_mux_init(board_mux, NULL, package); omap_panda_wlan_data.irq = gpio_to_irq(GPIO_WIFI_IRQ); + + omap_register_mac_device_fixup_paths(panda_fixup_mac_device_paths, +ARRAY_SIZE(panda_fixup_mac_device_paths)); + ret = wl12xx_set_platform_data(omap_panda_wlan_data); if (ret) pr_err(error setting wl12xx data: %d\n, ret); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAPDSS: Check if RPM enabled before trying to change state
On 06/26/12 16:32, the mail apparently from Jassi Brar included: On 26 June 2012 12:49, Tomi Valkeinen tomi.valkei...@ti.com wrote: On Mon, 2012-06-25 at 22:36 +0530, Jassi Brar wrote: Normally if the driver does dispc_runtime_get() and dispc_read_reg(), the first call will enable the HW so the reg read works. But if the pm_runtime is disabled, say, during system suspend, with your patch dispc_runtime_get() will just return 0 without doing anything, and the dispc_read_reg() will crash because the HW is disabled (because nobody enabled it). Hmm, I am not sure if new calls would/should be made to dispc.c after the system has suspended and before resumed. That is, anything other than from runtime_resume/suspend callbacks of DSS, DISPC, HDMI, VENC and RFBI, which rightly don't touch any dss reg but only enable/disable a clock. They do touch the registers. For example, dispc's callbacks save and restore the registers. The HW should be fully functional during the callbacks. The point of the callbacks is to suspend/resume the HW in question, which of course requires accessing the HW. DISPC being held by HDMI, VENC and RFBI would be the last to suspend and first to resume. And it won't have its registers touched between dispc_runtime_suspend() and dispc_runtime_resume(), which seems ok to me (?) HDMI, VENC and RFBI directly fooling around with DISPC regs would have been a problem, which isn't the case. As we know, a subsystem should make sure any active work is cleared out before suspending and set some flag so that nothing runs until it has resumed. I don't say we can't crash the system with this patch, but then we would be violating rules of suspend-resume. Let's go back a bit. I feel like I'm missing some pieces of information, as I still don't quite grasp the problem. In the patch you said this fixes an issue with HDMI. Can you tell more about the problem? What code path is being run? Any error messages? I tried system suspend with omap4-sdp and panda, with 3.5-rc2, but neither board seems to wake up from the suspend. Does it work for you? Something non-omapdss in vanilla breaks suspend/resume. Without this patch I see the upstream's display broken after the suspend attempt. $ echo mem /sys/power/state I work on TILT tree, which has suspend/resume working after some more local patches. http://git.linaro.org/gitweb?p=people/andygreen/kernel-tilt.git;a=shortlog;h=refs/heads/tilt-3.4 I don't have SDP so not sure, but it should simply be testable with Panda4460 and the omap4plus_defconfig there. Please feel free to ask if you have any issue checking that out. We don't have access to Blaze and don't test that tree against it, but it's worth trying on PandaBoard ES which we do have and test against (omap4plus_defconfig). Here, mem suspend is working with HDMI raster coming back on resume, but we don't always get a desktop redraw (suspending again can correct that). Jassi's patches are present in this tree. A slightly side-issue, I have a TV here that only issues hpd 700ms after the Panda provides 5V at the HDMI link. It has always been touch-and-go if dss will recognize it or not, compared to a monitor which issues hpd high within some us of the link being powered. The patches from Jassi about permanently enabling the external HDMI PHY chip section that performs level-conversion for hpd, and the existing work to use irq management of hpd, seems to have really solved detecting that TV for the first time. -Andy -- Andy Green | TI Landing Team Leader Linaro.org │ Open source software for ARM SoCs | Follow Linaro http://facebook.com/pages/Linaro/155974581091106 - http://twitter.com/#!/linaroorg - http://linaro.org/linaro-blog -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] OMAP4: I2C: Enable the wakeup in I2C_WE
On 07/29/2011 01:07 PM, Somebody in the thread at some point said: Hi - - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + if (dev-rev OMAP_I2C_REV_ON_3530_4430) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, + dev-westate); Andy, can you clarify why you added the revision check which didn't exist before ? [1] http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=commitdiff;h=a3a7acbcc3df4e9ecc12aa1fc435534d74ebbdf4 At the time I wrote the patches back in March, the code there was different: there was a pre-extant test avoiding that line on 4430, and the patch is simply converting it to the new scheme. You can see it here: http://permalink.gmane.org/gmane.linux.ports.arm.omap/54940 @@ -379,7 +379,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - if (dev-rev OMAP_I2C_REV_ON_4430) + if (dev-rev OMAP_I2C_REV_ON_3530_4430) omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); } I guess since March and before this got committed for 3.1, someone got a patch in first removing the test, so when my patchset was uplevelled for commit against 3.1-rc this conflict was dealt with by re-introducing the test. Long story short, it's there from me as a mechanical 1:1 renaming action as part of the fix that 3530 and 4430 (different) IPs return the same rev number. Despite how it now looks I didn't add it, so if Shubhrajyoti has reasons to think it should be gone again I have nothing against that at all. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ARM: omap4: i2c reset regs postidle
On 05/16/2011 09:56 AM, Somebody in the thread at some point said: Am Donnerstag, den 21.04.2011, 13:13 +0100 schrieb Andy Green: On 04/21/2011 12:47 PM, Somebody in the thread at some point said: Without OMAP_I2C_FLAG_RESET_REGS_POSTIDLE I got i2c controller timeouts on each accsess after an NACK message. Taking this flag fix it. Ahhh that will explain why if you accidentally configure LM75 system monitor support, which isn't there on Panda, the I2C controllers die slowly on boot. Good catch! Can I get an Acked-by ? Sure, I had it on my tree for a while too. Tested-by: Andy Green andy.gr...@linaro.org Acked-by: Andy Green andy.gr...@linaro.org -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] ARM: omap4: i2c reset regs postidle
On 04/21/2011 12:47 PM, Somebody in the thread at some point said: Without OMAP_I2C_FLAG_RESET_REGS_POSTIDLE I got i2c controller timeouts on each accsess after an NACK message. Taking this flag fix it. Ahhh that will explain why if you accidentally configure LM75 system monitor support, which isn't there on Panda, the I2C controllers die slowly on boot. Good catch! -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] OMAP2+: add cpu id register to MAC address helper
On 03/25/2011 11:49 AM, Somebody in the thread at some point said: On Thursday 24 March 2011, Andy Green wrote: Introduce a generic helper function that can set a MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:40:70:f0:12:06 for the ethernet device on my Panda. Note that this patch requires the fix patch for CPU ID register indexes previously posted to linux-omap, otherwise the CPU ID is misread on Panda by the existing function to do it. This patch is already on linux-omap. OMAP2+:Common CPU DIE ID reading code reads wrong registers for OMAP4430 http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=b235e007831dbf57710e59cd4a120e2f374eecb9 Signed-off-by: Andy Greenandy.gr...@linaro.org Acked-by: Arnd Bergmanna...@arndb.de Thanks. TI folks: While this is a working solution, I still think it would be good to get an officially sanctioned method that allows the creation of a IEEE 802 MAC address in a range assigned to TI instead of using an address from the locally administered range. Is that something that can be done? Having a proper MAC from IEEE assigned for each interface is of course ideal. But even if that happened today though, on Panda there is no board identity storage to put the reserved MAC addresses in to bind it to the physical board. If you try to manage them on SD Card, you have the problem of dealing with correct MAC addresses needing putting there again every time it is nuked. So it doesn't in itself help in the Panda case. David Anders mentioned yesterday that for next OMAP board, he probably puts a general board identity EEPROM where one could stash MACs. This kind of API can be extended to query the EEPROM at device-register-time and fetch the MAC instead of compute it. So I think we go in a reasonable direction even when it is possible to get assigned MACs. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] OMAP2+: add cpu id register to MAC address helper
On 03/25/2011 01:24 PM, Somebody in the thread at some point said: On Friday 25 March 2011, Andy Green wrote: Having a proper MAC from IEEE assigned for each interface is of course ideal. But even if that happened today though, on Panda there is no board identity storage to put the reserved MAC addresses in to bind it to the physical board. If you try to manage them on SD Card, you have the problem of dealing with correct MAC addresses needing putting there again every time it is nuked. So it doesn't in itself help in the Panda case. What I meant is computing an official MAC address from the same input data as you already do. Unfortunately that would mean having at most 24 bits available instead of the 44 or so bits you currently use, because the upper half of the address then becomes fixed. Also it would require 1. defining an new algorithm that computes the lower 24 bits from the die ID in a way that minimises the chances of collision 2. Getting an official identifier for the upper half of the address assigned to the OMAP3/OMAP4 CPUs 3. Documenting this method in the OMAP data sheets. I see. It would work OK then. They probably wouldn't want to blow their $1750 just on Panda though, so maybe they set 4 bits or whatever and let 20 be computed. However, the only practical advantage is that it would show up as a TI MAC in an OUI database. The locally administered address as used at the moment is otherwise legal in every respect AFAIK. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 1/2] OMAP2+: add cpu id register to MAC address helper
On 03/25/2011 02:50 PM, Somebody in the thread at some point said: On Friday 25 March 2011, Andy Green wrote: I see. It would work OK then. They probably wouldn't want to blow their $1750 just on Panda though, so maybe they set 4 bits or whatever and let 20 be computed. Well, if the algorithm is defined well, it could be used for any device based on OMAP. The marketing department could turn this into a win by declaring does not require external EEPROM for ethernet mac address ;-) Okay, can't argue with it ^^ * Some places try to keep a database of all used machines and their MAC addresses to monitor who connects to the network. This requires the address to be stable. It also prevents the use of virtualization, so it's becoming less common. They will probably just be happy the crazy noise they have been seeing from current Panda MACs changing every session will go away, it doesn't seem to add anything it's an OUI namespace MAC. In the patch case the locally administered mac will be stable. Anyway since I understood it, I can see your idea is a cool approach, it's up to TI what they will do about it but I guess it's OK with or without it. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] OMAP2+: PANDA: Fix up random or missing MAC addresses for eth0 and wlan0
On 03/25/2011 08:13 PM, Somebody in the thread at some point said: Hi - I very much like this approach. I believed the ability to use the die ID to get a unique code was reasonable approach and that is why I didn't get an EEPROM put onto the BeagleBoard, though Gerald is looking at adding one on a future revision because the lack of one wasn't well received. Minor questions below. Great. FWIW I think it'd be a lost opportunity to wire the EEPROM direct to the network device. It's more flexible and powerful to regard the EEPROM as general board identity storage, a way to bind information to the physical board. Then you can stick any kind of information that you need to bind to the board in the same 25c device and in-kernel code can take care of discovering that data when needed on any subsystem that takes an interest. The use of the OMAP die id below makes this OMAP specific and the list referenced below of the devices to be referenced makes it Panda specific. Is there a way to make the list board specific, but to make these functions that will be used across many OMAP platforms reusable? I believe that this current code will result in a lot of cut-and-paste. My preference is that this is accepted and that we make this more general when we add this to other OMAP platforms, but it'd be great to capture your suggestions on how to do so before those cut-and-paste patch sets start coming in. Sure, I would be happy to put this stuff at OMAP platform layer for example if it makes sense to OMAP guys more generally. I just want to make sure I understand how this works. When a new network device is added, if the device name matches one of the above listed device paths, then the die id based MAC id is applied. This must be done via a device registration notifier as the registration is triggered when the device is detected. That's right. Arguably it would be better if there was a core API to register your board-specific uniqueness / entropy, and the drivers were able to use that instead of random ethernet address all in network layer. But after wasting two weeks getting pointlessly beaten up on lkml largely on the question of how generic this issue is, I would rather restart somewhere specific where everyone can see the obvious benefit and if it's seen as more useful migrate it. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 0/2] OMAP2+: PANDA: Provide unique-ish MAC addresses for Ethernet and WLAN interfaces
The following series solves a problem Panda suffers from where because there is no local MAC address storage on the board, a new random MAC address is applied to the onboard Ethernet interface each time, and the wl12xx module's wlan0 interface is always found with an unworkable 00:00:00:00:00:00 MAC. The series adds an omap id-related API to generate a 6-byte Ethernet MAC address from hashing a little the CPU ID registers. It is understood from TI that these contain data that at least in a subset of the 128 bits of the ID are unique per-CPU. It then introduces code in the Panda board definition file to watch network interface creation and if the device's path is on a list, set its MAC address to the CPU ID-generated one, plus two bits which differ according to which interface in the list is being changed. (This scheme was suggested by Alan Cox). The device paths for the onboard Ethernet smsc95xx, and the onboard WLAN wl12xx are listed, so both of these will get assigned a consistent, unique-ish locally administered MAC address with these patches. It's beleived the current scheme for MAC generation from ID data captures most of the entropy, but if there is a better scheme more closely mapped to what the unique factory areas are advice is welcome. The patches are against linux-omap which already has a prerequisite patch that fixes a problem with device ID capture on OMAP4. --- Andy Green (2): OMAP2+: PANDA: Fix up random or missing MAC addresses for eth0 and wlan0 OMAP2+: add cpu id register to MAC address helper arch/arm/mach-omap2/board-omap4panda.c | 91 arch/arm/mach-omap2/id.c | 39 ++ arch/arm/mach-omap2/include/mach/id.h |1 3 files changed, 131 insertions(+), 0 deletions(-) -- Signature -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 1/2] OMAP2+: add cpu id register to MAC address helper
Introduce a generic helper function that can set a MAC address using data from the OMAP unique CPU ID register. For comparison purposes this produces a MAC address of 2e:40:70:f0:12:06 for the ethernet device on my Panda. Note that this patch requires the fix patch for CPU ID register indexes previously posted to linux-omap, otherwise the CPU ID is misread on Panda by the existing function to do it. This patch is already on linux-omap. OMAP2+:Common CPU DIE ID reading code reads wrong registers for OMAP4430 http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=b235e007831dbf57710e59cd4a120e2f374eecb9 Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/id.c | 39 + arch/arm/mach-omap2/include/mach/id.h |1 + 2 files changed, 40 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 2537090..e46b430 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -557,3 +557,42 @@ void __init omap2_set_globals_tap(struct omap_globals *omap2_globals) else tap_prod_id = 0x0208; } + +/* + * this uses the unique per-cpu info from the cpu fuses set at factory to + * generate a 6-byte MAC address. Two bits in the generated code are used + * to elaborate the generated address into four, so it can be used on multiple + * network interfaces. + */ + +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype) +{ + struct omap_die_id odi; + u32 tap = read_tap_reg(OMAP_TAP_IDCODE); + + omap_get_die_id(odi); + + mac[0] = odi.id_2; + mac[1] = odi.id_2 8; + mac[2] = odi.id_1; + mac[3] = odi.id_1 8; + mac[4] = odi.id_1 16; + mac[5] = odi.id_1 24; + + /* XOR other chip-specific data with ID */ + + tap ^= odi.id_3; + + mac[0] ^= tap; + mac[1] ^= tap 8; + mac[2] ^= tap 16; + mac[3] ^= tap 24; + + /* allow four MACs from this same basic data */ + + mac[1] = (mac[1] ~0xc0) | ((subtype 3) 6); + + /* mark it as not multicast and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h index 02ed3aa..373313a 100644 --- a/arch/arm/mach-omap2/include/mach/id.h +++ b/arch/arm/mach-omap2/include/mach/id.h @@ -18,5 +18,6 @@ struct omap_die_id { }; void omap_get_die_id(struct omap_die_id *odi); +void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype); #endif -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 2/2] OMAP2+: PANDA: Fix up random or missing MAC addresses for eth0 and wlan0
This patch registers a network device notifier callback to set the mac addresses for the onboard network assets of Panda correctly, despite the drivers involved have used a random or all-zeros MAC address. The technique was suggested by Alan Cox on lkml. It works by device path so it corrects the MAC addresses even if the drivers are in modules loaded in an order that changes their interface name from usual (eg, the onboard module might be wlan1 if there is a USB wireless stick plugged in and its module is inserted first.) Cc: Alan Cox a...@lxorguk.ukuu.org.uk Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/mach-omap2/board-omap4panda.c | 91 1 files changed, 91 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c index 80b8860..0b92873 100644 --- a/arch/arm/mach-omap2/board-omap4panda.c +++ b/arch/arm/mach-omap2/board-omap4panda.c @@ -28,9 +28,12 @@ #include linux/regulator/machine.h #include linux/regulator/fixed.h #include linux/wl12xx.h +#include linux/netdevice.h +#include linux/if_ether.h #include mach/hardware.h #include mach/omap4-common.h +#include mach/id.h #include asm/mach-types.h #include asm/mach/arch.h #include asm/mach/map.h @@ -506,6 +509,92 @@ static inline void board_serial_init(void) } #endif +/* + * These device paths represent the onboard USB - Ethernet bridge, and + * the WLAN module on Panda, both of which need their random or all-zeros + * mac address replacing with a per-cpu stable generated one + */ + +static const char * const panda_fixup_mac_device_paths[] = { + usb1/1-1/1-1.1/1-1.1:1.0, + mmc1:0001:2, +}; + +static int panda_device_path_need_mac(struct device *dev) +{ + const char **try = panda_fixup_mac_device_paths; + const char *path; + int count = ARRAY_SIZE(panda_fixup_mac_device_paths); + const char *p; + int len; + struct device *devn; + + while (count--) { + + p = *try + strlen(*try); + devn = dev; + + while (devn) { + + path = dev_name(devn); + len = strlen(path); + + if ((p - *try) len) { + devn = NULL; + continue; + } + + p -= len; + + if (strncmp(path, p, len)) { + devn = NULL; + continue; + } + + devn = devn-parent; + if (p == *try) + return count; + + if (devn != NULL (p - *try) 2) + devn = NULL; + + p--; + if (devn != NULL *p != '/') + devn = NULL; + } + + try++; + } + + return -ENOENT; +} + +static int omap_panda_netdev_event(struct notifier_block *this, +unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + struct sockaddr sa; + int n; + + if (event != NETDEV_REGISTER) + return NOTIFY_DONE; + + n = panda_device_path_need_mac(dev-dev.parent); + if (n = 0) { + sa.sa_family = dev-type; + omap2_die_id_to_ethernet_mac(sa.sa_data, n); + dev-netdev_ops-ndo_set_mac_address(dev, sa); + } + + return NOTIFY_DONE; +} + +static struct notifier_block omap_panda_netdev_notifier = { + .notifier_call = omap_panda_netdev_event, + .priority = 1, +}; + + static void __init omap4_panda_init(void) { int package = OMAP_PACKAGE_CBS; @@ -517,6 +606,8 @@ static void __init omap4_panda_init(void) if (wl12xx_set_platform_data(omap_panda_wlan_data)) pr_err(error setting wl12xx data\n); + register_netdevice_notifier(omap_panda_netdev_notifier); + omap4_panda_i2c_init(); platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); platform_device_register(omap_vwlan_device); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/5] OMAP2+: add cpu id register to MAC address helper
On 03/18/2011 08:34 AM, Somebody in the thread at some point said: +void omap2_die_id_to_mac(u8 *mac, int length) +{ + struct omap_die_id odi; + + omap_get_die_id(odi); + memcpy(mac,odi.id_0, length); + + /* mark it as not multicast and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; +} This is a pretty clever trick, but it's not an official globally unique MAC address, right? Maybe we can ask TI to officially request a MAC address range for OMAP SoCs and document an official procedure to compute it. This was an idea from Loic Minier. 80211 allows local namespace MACs, this one is marked up as such, so it is as OK as the CPU ID bits are reasonably well distributed in terms of collision. You are right though the overall correct solution from the board side is to have paid for two (WLAN has the same problem -- worse right now it comes up with 00:00:00:00:00:00) proper namespace MACs. That's still not enough because there must be somewhere on the board to store it, I call this board identity storage, and there is nowhere on Panda. If you put it on SD card, it has the effect that your MAC address moves with the SD card between boards which is less than ideal, you have to make sure if he rewrites his SD card somehow it knows to use the right mac address... it's not credible. The problem with what you suggested is that CPU ID is just a static token chosen arbitrarily by TI in the factory so you can't somehow compute the MAC which is assigned by IEEE, which is also an arbitrary range chosen by them, from the unrelated CPU ID content. It is interesting to use CPU ID though because it will not vary per-board. So this is why the patch arrives at what it is doing using the legal private namespace concept. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/5] OMAP2+: add cpu id register to MAC address helper
On 03/18/2011 08:52 AM, Somebody in the thread at some point said: + /* mark it as not multicast and outside official 80211 MAC namespace */ + + mac[0] = (mac[0] ~1) | 2; so here lies the answer to my question From where do you get the MAC :) Is there a guarantee that this MAC will work in all Ethernet setups? Yeah it's in 80211 spec. You have to buy the spec, I can't point you to it directly, but here is the wikipedia article showing the structure http://en.wikipedia.org/wiki/MAC_address#Address_details the random mac addresses generated by the kernel also use this scheme. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/5] OMAP2+: add cpu id register to MAC address helper
On 03/18/2011 02:37 PM, Somebody in the thread at some point said: Hi - [sp] This 'trick' has been tried earlier in u-boot. See: http://www.mail-archive.com/u-boot@lists.denx.de/msg19915.html I am also not sure whether DIE_ID would really be unique. It doesn't actually need all the bits to be unique for this, just have a low probability of collision with a reasonable number of devices sharing the same network. If there is not enough variation as it stands in the first 6 bytes of it, all the 128 bit ID can be xor'd together, use the other registers about die revision, hawkeye also xored in, etc. I'll ask about what can be expected from this at TI. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3 00/18] I2C: OMAP1: OMAP2+: I2C fixes, removal of cpu_is... from driver
On 03/15/2011 10:28 PM, Somebody in the thread at some point said: Hi, * Andy Greena...@warmcat.com [110315 12:53]: The following series removes cpu_...() usage completely from the omap-i2c driver by having decisions about functional implementation choices in the SoC held in cpu-specific hwmod tables that are already established, or for OMAP1 where there is no hwmod, set at OMAP1-specific i2c bus addition time. You should send this to the i2c list with Ben Cc'd. Done... sorry for the fumble. Ben is already CC'd, sorry for spamming his mailbox too. -Andy -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 01/18] OMAP2+: hwmod data: Set hwmod flags to only allow 16-bit accesses to i2c
Peter Maydell noticed when running under QEMU he was getting errors reporting 32-bit access to I2C peripheral unit registers that are documented to be 8 or 16-bit only[1][2] The I2C driver is blameless as it wraps its accesses in a function using __raw_writew and __raw_readw, it turned out it is the hwmod stuff. However the hwmod code already has a flag to force a peripheral unit to only be accessed using 16-bit operations. This patch applies the 16-bit only flag to the 2430, OMAP3xxx and OMAP44xx hwmod structs. 2420 was already correctly marked up as 16-bit. The 2430 change will need testing by TI as arranged in the comments to the previous patch version. When the 16-bit flag is or-ed with other flags, it is placed first as requested in comments. [1] OMAP4430 Technical reference manual section 23.1.6.2 [2] OMAP3530 Technical reference manual section 18.6 Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org Acked-by: Benoit Cousson b-cous...@ti.com Acked-by: Paul Walmsley p...@pwsan.com --- arch/arm/mach-omap2/omap_hwmod_2430_data.c |2 ++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |3 +++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c |8 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 8ecfbcd..eeb6348 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -504,6 +504,7 @@ static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = { static struct omap_hwmod omap2430_i2c1_hwmod = { .name = i2c1, + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c1_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), .sdma_reqs = i2c1_sdma_reqs, @@ -550,6 +551,7 @@ static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = { static struct omap_hwmod omap2430_i2c2_hwmod = { .name = i2c2, + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c2_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), .sdma_reqs = i2c2_sdma_reqs, diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8d81813..cc94616 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -685,6 +685,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = { static struct omap_hwmod omap3xxx_i2c1_hwmod = { .name = i2c1, + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c1_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), .sdma_reqs = i2c1_sdma_reqs, @@ -727,6 +728,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = { static struct omap_hwmod omap3xxx_i2c2_hwmod = { .name = i2c2, + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c2_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), .sdma_reqs = i2c2_sdma_reqs, @@ -769,6 +771,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = { static struct omap_hwmod omap3xxx_i2c3_hwmod = { .name = i2c3, + .flags = HWMOD_16BIT_REG, .mpu_irqs = i2c3_mpu_irqs, .mpu_irqs_cnt = ARRAY_SIZE(i2c3_mpu_irqs), .sdma_reqs = i2c3_sdma_reqs, diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c2806bd..f8400a1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1150,7 +1150,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { static struct omap_hwmod omap44xx_i2c1_hwmod = { .name = i2c1, .class = omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .flags = HWMOD_16BIT_REG | HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_i2c1_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs), .sdma_reqs = omap44xx_i2c1_sdma_reqs, @@ -1203,7 +1203,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { static struct omap_hwmod omap44xx_i2c2_hwmod = { .name = i2c2, .class = omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .flags = HWMOD_16BIT_REG | HWMOD_INIT_NO_RESET, .mpu_irqs = omap44xx_i2c2_irqs, .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs), .sdma_reqs = omap44xx_i2c2_sdma_reqs, @@ -1256,7 +1256,7 @@ static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { static struct omap_hwmod omap44xx_i2c3_hwmod = { .name = i2c3, .class = omap44xx_i2c_hwmod_class, - .flags = HWMOD_INIT_NO_RESET, + .flags
[PATCH 3 00/18] I2C: OMAP1: OMAP2+: I2C fixes, removal of cpu_is... from driver
The following series removes cpu_...() usage completely from the omap-i2c driver by having decisions about functional implementation choices in the SoC held in cpu-specific hwmod tables that are already established, or for OMAP1 where there is no hwmod, set at OMAP1-specific i2c bus addition time. Along the way it solves two issues with the existing implementation, that only 16-bit accesses are documented to be allowed to the I2C peripheral unit, and that due to a confusion in the existing driver about whether it is faced with a newer IP version on OMAP3530, currently it writes to a random non-existent I2C register at times on that platform. The patch series is quite extended from the first try thanks to comments from Benoit Cousson. This 3rd try is based on 2.6.38-rc8 as requested. --- Andy Green (18): I2C: OMAP1/OMAP2+: prepend I2C IP version to probed version shown in dev_info I2C: OMAP2+: Convert omap I2C driver to use feature implementation flags from platform data I2C: OMAP1: set i2c unit feature implementation flags in platform data OMAP2+: hwmod data: add correct functionality flags to all omap2plus i2c dev_attr I2C: OMAP1/OMAP2+: create omap I2C functionality flags for each cpu_... test I2C: OMAP2+: Pass flags up to omap i2c platform_data as well I2C: OMAP1/OMAP2+: add flags field to omap i2c platform data I2C: OMAP2+: increase omap_i2c_dev_attr flags from u8 to u32 I2C: OMAP2+: address confused probed version naming I2C: OMAP2+: Solve array bounds overflow error on i2c idle I2C: OMAP2+: use platform_data ip revision to select register map I2C: OMAP2+: Pass hwmod rev knowledge via platform_data when i2c bus added I2C: OMAP1: set IP revision in platform data I2C: OMAP: add rev to omap i2c platform data I2C: OMAP2+: hwmod data: Tag all OMAP2+ hwmod definitions with I2C IP revision I2C: OMAP2+: Introduce I2C IP versioning constants I2C: OMAP2+: Name registers in I2C IP V2 only accordingly OMAP2+: hwmod data: Set hwmod flags to only allow 16-bit accesses to i2c arch/arm/mach-omap2/omap_hwmod_2420_data.c |8 ++ arch/arm/mach-omap2/omap_hwmod_2430_data.c |6 ++ arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 13 arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 19 - arch/arm/plat-omap/i2c.c | 27 arch/arm/plat-omap/include/plat/i2c.h |3 + drivers/i2c/busses/i2c-omap.c | 98 +++- include/linux/i2c-omap.h | 29 8 files changed, 152 insertions(+), 51 deletions(-) -- Signature -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 02/18] I2C: OMAP2+: Name registers in I2C IP V2 only accordingly
The OMAP I2C driver dynamically chooses between two register sets of differing sizes depending on the cpu type it finds itself on. It has been observed that the existing code references non-existing registers on OMAP3530, because while it correctly chose the smaller register layout based on cpu type, the code uses the probed register ID to decide if to execute code referencing an extra register, and both register layout devices on OMAP3530 and OMAP4430 report the same probed ID of 0x40. This patch changes the extended register names only found on IP V2 of the I2C peripheral unit accordingly to help show up errors in usage. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/i2c/busses/i2c-omap.c | 23 --- 1 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 829a2a1..2826c13 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -72,11 +72,12 @@ enum { OMAP_I2C_SCLH_REG, OMAP_I2C_SYSTEST_REG, OMAP_I2C_BUFSTAT_REG, - OMAP_I2C_REVNB_LO, - OMAP_I2C_REVNB_HI, - OMAP_I2C_IRQSTATUS_RAW, - OMAP_I2C_IRQENABLE_SET, - OMAP_I2C_IRQENABLE_CLR, + /* only on OMAP4430 */ + OMAP_I2C_IP_V2_REVNB_LO, + OMAP_I2C_IP_V2_REVNB_HI, + OMAP_I2C_IP_V2_IRQSTATUS_RAW, + OMAP_I2C_IP_V2_IRQENABLE_SET, + OMAP_I2C_IP_V2_IRQENABLE_CLR, }; /* I2C Interrupt Enable Register (OMAP_I2C_IE): */ @@ -244,11 +245,11 @@ const static u8 omap4_reg_map[] = { [OMAP_I2C_SCLH_REG] = 0xb8, [OMAP_I2C_SYSTEST_REG] = 0xbC, [OMAP_I2C_BUFSTAT_REG] = 0xc0, - [OMAP_I2C_REVNB_LO] = 0x00, - [OMAP_I2C_REVNB_HI] = 0x04, - [OMAP_I2C_IRQSTATUS_RAW] = 0x24, - [OMAP_I2C_IRQENABLE_SET] = 0x2c, - [OMAP_I2C_IRQENABLE_CLR] = 0x30, + [OMAP_I2C_IP_V2_REVNB_LO] = 0x00, + [OMAP_I2C_IP_V2_REVNB_HI] = 0x04, + [OMAP_I2C_IP_V2_IRQSTATUS_RAW] = 0x24, + [OMAP_I2C_IP_V2_IRQENABLE_SET] = 0x2c, + [OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30, }; static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, @@ -309,7 +310,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) dev-iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); if (dev-rev = OMAP_I2C_REV_ON_4430) - omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); + omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1); else omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 03/18] I2C: OMAP2+: Introduce I2C IP versioning constants
These represent the two kinds of (incompatible) OMAP I2C peripheral unit in use so far. The constants are in linux/i2c-omap.h so the omap i2c driver can have them too. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/plat-omap/include/plat/i2c.h |1 + include/linux/i2c-omap.h | 12 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h index 878d632..a1d3d06 100644 --- a/arch/arm/plat-omap/include/plat/i2c.h +++ b/arch/arm/plat-omap/include/plat/i2c.h @@ -22,6 +22,7 @@ #define __ASM__ARCH_OMAP_I2C_H #include linux/i2c.h +#include linux/i2c-omap.h #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) extern int omap_register_i2c_bus(int bus_id, u32 clkrate, diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 7472449..701886d 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -3,6 +3,18 @@ #include linux/platform_device.h +/* + * Version 2 of the I2C peripheral unit has a different register + * layout and extra registers. The ID register in the V2 peripheral + * unit on the OMAP4430 reports the same ID as the V1 peripheral + * unit on the OMAP3530, so we must inform the driver which IP + * version we know it is running on from platform / cpu-specific + * code using these constants in the hwmod class definition. + */ + +#define OMAP_I2C_IP_VERSION_1 1 +#define OMAP_I2C_IP_VERSION_2 2 + struct omap_i2c_bus_platform_data { u32 clkrate; void(*set_mpu_wkup_lat)(struct device *dev, long set); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 05/18] I2C: OMAP: add rev to omap i2c platform data
We need to pass the I2C IP revision from the hwmod class up into the OMAP I2C driver, which does not have direct access to it. This adds a member to the platform data the OMAP I2C driver does use already to hold the I2C IP revision. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- include/linux/i2c-omap.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 701886d..b321211 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -17,6 +17,7 @@ struct omap_i2c_bus_platform_data { u32 clkrate; + u32 rev; void(*set_mpu_wkup_lat)(struct device *dev, long set); int (*device_enable) (struct platform_device *pdev); int (*device_shutdown) (struct platform_device *pdev); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 06/18] I2C: OMAP1: set IP revision in platform data
All OMAP1 are using IP revision 1 in terms of register layout. We set this information in omap1_i2c_add_bus() so we don't have to use cpu_is_xxx() any more in the omap i2c driver. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/plat-omap/i2c.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a4f8003..0a1b5af 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -108,6 +108,9 @@ static inline int omap1_i2c_add_bus(int bus_id) res[1].start = INT_I2C; pdata = i2c_pdata[bus_id - 1]; + /* all OMAP1 have IP version 1 register set */ + pdata-rev = OMAP_I2C_IP_VERSION_1; + return platform_device_register(pdev); } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 07/18] I2C: OMAP2+: Pass hwmod rev knowledge via platform_data when i2c bus added
Mark each OMAP I2C bus with the hwmod's knowledge of which I2C IP version is in the chip we're running on. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- arch/arm/plat-omap/i2c.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 0a1b5af..34a3319 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -155,6 +155,12 @@ static inline int omap2_i2c_add_bus(int bus_id) pdata = i2c_pdata[bus_id - 1]; /* +* pass the hwmod class's CPU-specific knowledge of I2C IP revision in +* use up to the OMAP I2C driver via platform data +*/ + pdata-rev = oh-class-rev; + + /* * When waiting for completion of a i2c transfer, we need to * set a wake up latency constraint for the MPU. This is to * ensure quick enough wakeup from idle, when transfer -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 08/18] I2C: OMAP2+: use platform_data ip revision to select register map
Change the register map names to reflect the IP revision they are representing, and use the platform_data IP revision index to select between them at init time. Eliminates 1 of 17 cpu_...() calls in the driver. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/i2c/busses/i2c-omap.c | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2826c13..eee0bb8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -205,7 +205,7 @@ struct omap_i2c_dev { u16 errata; }; -const static u8 reg_map[] = { +const static u8 reg_map_ip_v1[] = { [OMAP_I2C_REV_REG] = 0x00, [OMAP_I2C_IE_REG] = 0x01, [OMAP_I2C_STAT_REG] = 0x02, @@ -226,7 +226,7 @@ const static u8 reg_map[] = { [OMAP_I2C_BUFSTAT_REG] = 0x10, }; -const static u8 omap4_reg_map[] = { +const static u8 reg_map_ip_v2[] = { [OMAP_I2C_REV_REG] = 0x04, [OMAP_I2C_IE_REG] = 0x2c, [OMAP_I2C_STAT_REG] = 0x28, @@ -1037,10 +1037,10 @@ omap_i2c_probe(struct platform_device *pdev) else dev-reg_shift = 2; - if (cpu_is_omap44xx()) - dev-regs = (u8 *) omap4_reg_map; + if (pdata-rev == OMAP_I2C_IP_VERSION_2) + dev-regs = (u8 *)reg_map_ip_v2; else - dev-regs = (u8 *) reg_map; + dev-regs = (u8 *)reg_map_ip_v1; pm_runtime_enable(pdev-dev); omap_i2c_unidle(dev); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 09/18] I2C: OMAP2+: Solve array bounds overflow error on i2c idle
This solves the main problem the patch series is about. Prior to this patch on OMAP3530 the driver wrongly interprets the I2C peripheral unit's own reported revision as meaning it is running on an IP V2 device and must use the extended registers. In fact OMAP3530 is IP V1 with the smaller register set, the reason for the confusion is that the hardware does in fact report having the same IP revision index as is found on an OMAP4430, which really is IP V2 and has the extended registers. This corrects the test for which registers to use so that it decides using hwmod knowledge found in the platform_data. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/i2c/busses/i2c-omap.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index eee0bb8..14f5b50 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -309,7 +309,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) pdata = pdev-dev.platform_data; dev-iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); - if (dev-rev = OMAP_I2C_REV_ON_4430) + if (pdata-rev == OMAP_I2C_IP_VERSION_2) omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1); else omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3 10/18] I2C: OMAP2+: address confused probed version naming
The driver reflects the confusion that probed I2C revision from the hardware of 0x40 means it is on an OMAP4430. However, you will probe the same 0x40 ID on an OMAP3530. So this patch changes the name to reflect that. It also clarifies that the original name OMAP_I2C_REV_2 is referring to some ancient OMAP1 revision number, not to be confused with the IP revisions this patch series introduces. Similarly the term rev is used in the ancient OMAP1 ISR, the term is changed to use omap1 instead. Cc: patc...@linaro.org Cc: Ben Dooks ben-li...@fluff.org Reported-by: Peter Maydell peter.mayd...@linaro.org Signed-off-by: Andy Green andy.gr...@linaro.org --- drivers/i2c/busses/i2c-omap.c | 19 ++- 1 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 14f5b50..ecb48c7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -42,12 +42,12 @@ #include linux/pm_runtime.h /* I2C controller revisions */ -#define OMAP_I2C_REV_2 0x20 +#define OMAP_I2C_OMAP1_REV_2 0x20 /* I2C controller revisions present on specific hardware */ #define OMAP_I2C_REV_ON_2430 0x36 #define OMAP_I2C_REV_ON_3430 0x3C -#define OMAP_I2C_REV_ON_4430 0x40 +#define OMAP_I2C_REV_ON_3530_4430 0x40 /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -314,7 +314,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) else omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); - if (dev-rev OMAP_I2C_REV_2) { + if (dev-rev OMAP_I2C_OMAP1_REV_2) { iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ } else { omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev-iestate); @@ -336,7 +336,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) unsigned long internal_clk = 0; struct clk *fclk; - if (dev-rev = OMAP_I2C_REV_2) { + if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) @@ -379,7 +379,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - if (dev-rev OMAP_I2C_REV_ON_4430) + if (dev-rev OMAP_I2C_REV_ON_3530_4430) omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); } @@ -723,7 +723,7 @@ static inline void i2c_omap_errata_i207(struct omap_i2c_dev *dev, u16 stat) #ifdef CONFIG_ARCH_OMAP15XX static irqreturn_t -omap_i2c_rev1_isr(int this_irq, void *dev_id) +omap_i2c_omap1_isr(int this_irq, void *dev_id) { struct omap_i2c_dev *dev = dev_id; u16 iv, w; @@ -777,7 +777,7 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id) return IRQ_HANDLED; } #else -#define omap_i2c_rev1_isr NULL +#define omap_i2c_omap1_isr NULL #endif /* @@ -1062,7 +1062,7 @@ omap_i2c_probe(struct platform_device *pdev) * size. This is to ensure that we can handle the status on int * call back latencies. */ - if (dev-rev = OMAP_I2C_REV_ON_4430) { + if (dev-rev = OMAP_I2C_REV_ON_3530_4430) { dev-fifo_size = 0; dev-b_hw = 0; /* Disable hardware fixes */ } else { @@ -1078,7 +1078,8 @@ omap_i2c_probe(struct platform_device *pdev) /* reset ASAP, clearing any IRQs */ omap_i2c_init(dev); - isr = (dev-rev OMAP_I2C_REV_2) ? omap_i2c_rev1_isr : omap_i2c_isr; + isr = (dev-rev OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : + omap_i2c_isr; r = request_irq(dev-irq, isr, 0, pdev-name, dev); if (r) { -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html