Re: [PATCH v7 0/2] phy: bcm63xx-usbh: Add BCM63xx USBH driver
On 2020-07-17 10:47, Álvaro Fernández Rojas wrote: Add BCM63xx USBH PHY driver for BMIPS. v7: remove Simon from authors and introduce changes suggested by Rob: I asked you to remove my email address from the source code. All you've done is update it. I don't want spam. I know the address appears in the commit but you don't have to spray it around everywhere else. You can keep my name in the MODULE_AUTHOR text but you need to omit the email address. None of the original copyright notices included email addresses so I don't know why you think it is appropriate for you to add them. Please only Cc: this email address, I don't want multiple copies of everything. -- Simon Arlott
Re: [PATCH] ata: Disable queued TRIM for Samsung 860 SSDs
On 15/07/2020 21:53, Martin K. Petersen wrote: >> Despite the unsubstantiated claim from Samsung that "the improved >> queued trim enhances Linux compatibility" this does not appear to be >> true, even on Intel SATA controllers: > > I am aware of several people using 860 drives with queued TRIM. And I > haven't heard any complaints outside of the bug you referenced. > > Also, I have tested both 860 2.5" Pro and 860 mSATA EVO on a few > different systems in my lab without any problems. See: > > https://lore.kernel.org/stable/yq1h87du82d@oracle.com/T/ I've just checked and it happens on both my SATA 860s: 860 EVO 2TB (RVT04B6Q) on Intel Z170 860 PRO 1TB (RVM02B6Q) on Intel H170 > I really wish we had some more data to work with :( Is there a reliable way of reproducing this? I have a Marvell 88SE9235 that I could try with the EVO. > Lacking a proper heuristic I guess we don't have any choice to disable > the feature. But that's sad news for the people who currently don't have > problems since their performance will inevitably suffer. Samsung need to identify what the problem is before claiming that their Linux support is better, especially if specific chipsets are known to have issues... -- Simon Arlott
Re: [PATCH v6 2/2] phy: bcm63xx-usbh: Add BCM63xx USBH driver
On 2020-07-15 14:39, Álvaro Fernández Rojas wrote: Hello Simon, This is based on your work: https://github.com/nomis/linux/commit/c4c55b603a78e2732044a833e248c1a1087e7053 https://github.com/nomis/linux/commit/f153a58b9e6f88e72c3ef34dc076118f8b3ade5b Ok, it has been a long time and I couldn't find a branch with those in locally. Please remove my *email address* from the source code and MODULE_AUTHOR text. Historical signed-off-by lines can be updated to: Signed-off-by: Simon Arlott -- Simon Arlott
Re: [PATCH v6 2/2] phy: bcm63xx-usbh: Add BCM63xx USBH driver
On 2020-07-15 14:18, Álvaro Fernández Rojas wrote: Add BCM63xx USBH PHY driver for BMIPS. Signed-off-by: Álvaro Fernández Rojas --- ... +MODULE_DESCRIPTION("BCM63xx USBH PHY driver"); +MODULE_AUTHOR("Álvaro Fernández Rojas "); +MODULE_AUTHOR("Simon Arlott "); +MODULE_LICENSE("GPL"); I'm not the author of this. Nacked-by: Simon Arlott -- Simon Arlott
[PATCH] ata: Disable queued TRIM for Samsung 860 SSDs
Despite the unsubstantiated claim from Samsung that "the improved queued trim enhances Linux compatibility" this does not appear to be true, even on Intel SATA controllers: Bug 203475 - Samsung 860 EVO queued TRIM issues https://bugzilla.kernel.org/show_bug.cgi?id=203475 Disable queued TRIM for all Samsung 860 SSDs. Only the EVO has been reported as having this problem, but the original justification for enabling appears to be based on marketing material with no explanation of what has been changed to make the 860 work properly when the earlier 840 and 850 both have the same issue. Signed-off-by: Simon Arlott Cc: Park Ju Hyung Cc: sta...@vger.kernel.org Fixes: ca6bfcb2f6d9 ("libata: Enable queued TRIM for Samsung SSD 860") --- drivers/ata/libata-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index b1cd4d97bc2a..02e861aac5ec 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3951,6 +3951,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "Samsung SSD 850*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, + { "Samsung SSD 860*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | + ATA_HORKAGE_ZERO_AFTER_TRIM, }, { "FCCT*M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, -- 2.17.1 -- Simon Arlott
Re: [PATCH (v2)] scsi: sd: add parameter to stop disks before reboot
On 30/06/2020 02:35, Martin K. Petersen wrote: What happened to the suggestion to treat reboot=p like a poweroff instead? That seems to be fundamentally the right thing to do. I agree! I've done that but so far it has been ignored: https://lore.kernel.org/lkml/f4a7b539-eeac-1a59-2350-3eefc8c17801@0882a8b5-c6c3-11e9-b005-00805fc181fe/ -- Simon Arlott
[PATCH 2/2] x86/reboot/quirks: Add ASRock Z170 Extreme4
If a PCI mode reboot is performed on the ASRock Z170 Extreme4, a power cycle will occur. Automatically set the reboot quirk for this to prepare for the power off (i.e. stop all disks). This will only take effect if PCI mode is manually used. It'll be too late in the reboot process to prepare for power off if the other reboot methods fail. It is necessary to re-order the processing of DMI checks because this quirk must apply even if a reboot= command line parameter is used as that's the only way to specify a PCI mode reboot. Signed-off-by: Simon Arlott --- Previous patches to make scsi/sd stop before a reboot: https://lore.kernel.org/lkml/499138c8-b6d5-ef4a-2780-4f750ed337d3@0882a8b5-c6c3-11e9-b005-00805fc181fe/ https://lore.kernel.org/lkml/e726ffd8-8897-4a79-c3d6-6271eda8aebb@0882a8b5-c6c3-11e9-b005-00805fc181fe/ arch/x86/kernel/reboot.c | 51 ++-- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 0ec7ced727fe..a82d5db1c8ca 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -147,6 +147,13 @@ STACK_FRAME_NON_STANDARD(machine_real_restart); */ static int __init set_pci_reboot(const struct dmi_system_id *d) { + /* +* Only apply the DMI-based change if reboot_type hasn't been +* overridden on the command line. +*/ + if (!reboot_default) + return 0; + if (reboot_type != BOOT_CF9_FORCE) { reboot_type = BOOT_CF9_FORCE; pr_info("%s series board detected. Selecting %s-method for reboots.\n", @@ -157,6 +164,13 @@ static int __init set_pci_reboot(const struct dmi_system_id *d) static int __init set_kbd_reboot(const struct dmi_system_id *d) { + /* +* Only apply the DMI-based change if reboot_type hasn't been +* overridden on the command line. +*/ + if (!reboot_default) + return 0; + if (reboot_type != BOOT_KBD) { reboot_type = BOOT_KBD; pr_info("%s series board detected. Selecting %s-method for reboot.\n", @@ -165,6 +179,21 @@ static int __init set_kbd_reboot(const struct dmi_system_id *d) return 0; } +static int __init set_pci_power_cycle_reboot(const struct dmi_system_id *d) +{ + /* +* This has to be applied even if reboot_type has been set on the +* command line because that's the only way to enable PCI mode. +*/ + + if (reboot_type == BOOT_CF9_FORCE) { + reboot_quirks |= REBOOT_QUIRK_POWER_CYCLE; + pr_info("%s series board detected. Assume that a PCI reboot includes a power cycle.\n", + d->ident); + } + return 0; +} + /* * This is a single dmi_table handling all reboot quirks. */ @@ -247,6 +276,14 @@ static const struct dmi_system_id reboot_dmi_table[] __initconst = { DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"), }, }, + { /* PCI reboots cause a power cycle */ + .callback = set_pci_power_cycle_reboot, + .ident = "ASRock Z170 Extreme4", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"), + DMI_MATCH(DMI_BOARD_NAME, "Z170 Extreme4"), + }, + }, /* ASUS */ { /* Handle problems with rebooting on ASUS P4S800 */ @@ -494,13 +531,6 @@ static int __init reboot_init(void) { int rv; - /* -* Only do the DMI check if reboot_type hasn't been overridden -* on the command line -*/ - if (!reboot_default) - return 0; - /* * The DMI quirks table takes precedence. If no quirks entry * matches and the ACPI Hardware Reduced bit is set and EFI @@ -508,6 +538,13 @@ static int __init reboot_init(void) */ rv = dmi_check_system(reboot_dmi_table); + /* +* Only force EFI reboot if reboot_type hasn't been overridden +* on the command line. +*/ + if (!reboot_default) + return 0; + if (!rv && efi_reboot_required() && !efi_runtime_disabled()) reboot_type = BOOT_EFI; -- 2.17.1 -- Simon Arlott
[PATCH 1/2] reboot: add a "power cycle" quirk to prepare for a power off on reboot
I need to use "reboot=p" on my desktop because one of the PCIe devices does not appear after a warm boot. This results in a very cold boot because the BIOS turns the PSU off and on. The scsi sd shutdown process does not send a stop command to disks before the reboot happens (stop commands are only sent for a shutdown). The result is that all of my SSDs experience a sudden power loss on every reboot, which is undesirable behaviour because it could cause data to be corrupted. These events are recorded in the SMART attributes. Add a "power cycle" quirk to the reboot options to prepare all devices for a power off by setting the system_state to SYSTEM_POWER_OFF instead of SYSTEM_RESTART while still performing a restart as requested. This uses the letter "C" for the parameter because of numerous uses of "reboot=pci" that would otherwise trigger this behaviour if "c" was used. Signed-off-by: Simon Arlott --- Previous patches to make scsi/sd stop before a reboot: https://lore.kernel.org/lkml/499138c8-b6d5-ef4a-2780-4f750ed337d3@0882a8b5-c6c3-11e9-b005-00805fc181fe/ https://lore.kernel.org/lkml/e726ffd8-8897-4a79-c3d6-6271eda8aebb@0882a8b5-c6c3-11e9-b005-00805fc181fe/ Documentation/admin-guide/kernel-parameters.txt | 8 ++-- include/linux/reboot.h | 4 kernel/reboot.c | 15 ++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index bee3b83d6f84..91359fd4fbcc 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -4422,9 +4422,10 @@ reboot= [KNL] Format (x86 or x86_64): [w[arm] | c[old] | h[ard] | s[oft] | g[pio]] \ - [[,]s[mp] \ + [[,]s[mp]] \ [[,]b[ios] | a[cpi] | k[bd] | t[riple] | e[fi] | p[ci]] \ - [[,]f[orce] + [[,]f[orce]] \ + [[,]C] Where reboot_mode is one of warm (soft) or cold (hard) or gpio (prefix with 'panic_' to set mode for panic reboot only), @@ -4432,6 +4433,9 @@ reboot_force is either force or not specified, reboot_cpu is s[mp] with being the processor to be used for rebooting. + Quirks: + C = Rebooting includes a power cycle, prepare + for a power off instead of a restart. refscale.holdoff= [KNL] Set test-start holdoff period. The purpose of diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 3734cd8f38a8..b49559ba825a 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -39,6 +39,10 @@ extern int reboot_default; extern int reboot_cpu; extern int reboot_force; +#define REBOOT_QUIRK_POWER_CYCLEBIT(0) + +extern int reboot_quirks; + extern int register_reboot_notifier(struct notifier_block *); extern int unregister_reboot_notifier(struct notifier_block *); diff --git a/kernel/reboot.c b/kernel/reboot.c index 491f1347bf43..5605c2894f2b 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -45,6 +45,7 @@ int reboot_default = 1; int reboot_cpu; enum reboot_type reboot_type = BOOT_ACPI; int reboot_force; +int reboot_quirks; /* * If set, this is used for preparing the system to power off. @@ -71,7 +72,15 @@ EXPORT_SYMBOL_GPL(emergency_restart); void kernel_restart_prepare(char *cmd) { blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); - system_state = SYSTEM_RESTART; + if (reboot_quirks & REBOOT_QUIRK_POWER_CYCLE) { + /* +* The reboot will include a power cycle, so prepare all +* devices for a power off. +*/ + system_state = SYSTEM_POWER_OFF; + } else { + system_state = SYSTEM_RESTART; + } usermodehelper_disable(); device_shutdown(); } @@ -583,6 +592,10 @@ static int __init reboot_setup(char *str) case 'f': reboot_force = 1; break; + + case 'C': + reboot_quirks |= REBOOT_QUIRK_POWER_CYCLE; + break; } str = strchr(str, ','); -- 2.17.1 -- Simon Arlott
[PATCH (v2)] scsi: sd: add parameter to stop disks before reboot
I need to use "reboot=p" on my desktop because one of the PCIe devices does not appear after a warm boot. This results in a very cold boot because the BIOS turns the PSU off and on. The scsi sd shutdown process does not send a stop command to disks before the reboot happens (stop commands are only sent for a shutdown). The result is that all of my SSDs experience a sudden power loss on every reboot, which is undesirable behaviour because it could cause data to be corrupted. These events are recorded in the SMART attributes. Add a "stop_before_reboot" module parameter that can be used to control the shutdown behaviour of disks before a reboot. The default will be the existing behaviour (disks are not stopped). sd_mod.stop_before_reboot= 0 = disabled (default) 1 = enabled The behaviour on shutdown is unchanged: all disks are unconditionally stopped. Signed-off-by: Simon Arlott --- Documentation/scsi/scsi-parameters.rst | 5 + drivers/scsi/sd.c | 14 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Documentation/scsi/scsi-parameters.rst b/Documentation/scsi/scsi-parameters.rst index 9aba897c97ac..324610870de5 100644 --- a/Documentation/scsi/scsi-parameters.rst +++ b/Documentation/scsi/scsi-parameters.rst @@ -101,6 +101,11 @@ parameters may be changed at runtime by the command allowing boot to proceed. none ignores them, expecting user space to do the scan. + sd_mod.stop_before_reboot= + [SCSI] configure stop action for disks before a reboot + Format: + 0 = disabled (default), 1 = enabled + sim710= [SCSI,HW] See header of drivers/scsi/sim710.c. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d90fefffe31b..506904bf15da 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -98,6 +98,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC); +static unsigned int stop_before_reboot = 0; + +module_param(stop_before_reboot, uint, 0644); +MODULE_PARM_DESC(stop_before_reboot, +"stop disks before reboot"); + #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 #else @@ -3576,9 +3582,11 @@ static void sd_shutdown(struct device *dev) sd_sync_cache(sdkp, NULL); } - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); + if (sdkp->device->manage_start_stop) { + if (system_state != SYSTEM_RESTART || stop_before_reboot) { + sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_start_stop_device(sdkp, 0); + } } } -- 2.17.1 -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 23/06/2020 21:42, Henrique de Moraes Holschuh wrote: > [1] I have long lost the will and energy to pursue this, so *this* is a > throw-away anecdote for anyone that cares: I reported here a few years > ago that many models of *SATA* based SSDs from Crucial/Micron, Samsung > and Intel were complaining (through their SMART attributes) that Linux > was causing unsafe shutdowns. > > https://lkml.org/lkml/2017/4/10/1181 > > TL;DR: wait one *extra* second after the SSD acknowleged the STOP > command as complete before you trust the SSD device is safe to be > powered down (i.e. before reboot, suspend, poweroff/shutdown, and device > removal/detach). This worked around the issue for every vendor and > model of SSD we tested. Looking through that thread, it looks like a simple 1 second delay on shutdown/reboot patch hasn't been proposed yet? In my case none of the SSDs are recording unexpected power loss if they are stopped before the reboot, but the reboot won't necessarily be instantaneous after the last stop command returns. -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 19/06/2020 00:31, Damien Le Moal wrote: > On 2020/06/18 21:26, Simon Arlott wrote: >> I haven't verified it, but the BIOS leaves the power off for several >> seconds which should be long enough for the HDDs to spin down. >> >> I'm less concerned about those suddenly losing power but it would be >> nice to have a stop command sent to them too. > > OK. So maybe the patch should be as simple as changing SYSTEM_RESTART state to > SYSTEM_POWER_OFF if reboot=p is set, no ? Since that is consistent with the > fact > that reboot=p will cause power to go off, exactly the same as a regular > shutdown, it seems cleaner and safer to use SYSTEM_POWER_OFF for the entire > system, not just scsi disks. That could be a bit misleading because the power isn't going to stay off. Some of the network drivers have specific WOL behaviour changes for a power off. Power cycling the PSU is not something that every BIOS will do, so it's not that simple. It could be a module parameter but I'd be concerned that some other code will assuming the system should be powered off and all of my reboots will become power off events. -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 23/06/2020 14:36, Pavel Machek wrote: > Many SSDs are buggy, and will eventually corrupt themselves if you do enough > sudden power loss experiments. > > HDDs don't like their power cut, either. You can hear the difference > between normal power off and power cut... I will change the patch so that it doesn't distinguish between types of disks. The default will have to be the existing behaviour (don't stop disks) because most reboots shouldn't result in a loss of power. -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 18/06/2020 08:21, Christoph Hellwig wrote: > On Wed, Jun 17, 2020 at 07:49:57PM +0100, Simon Arlott wrote: >> Avoiding a stop of the disk on a reboot is appropriate for HDDs because >> they're likely to continue to be powered (and should not be told to spin >> down only to spin up again) but the default behaviour for SSDs should >> be changed to stop them before the reboot. > > I don't think that is true in general. At least for most current server > class and older desktop and laptop class systems they use the same > format factors and enclosures, although they are slightly divering now. > > So I think this needs to be quirked based on the platform and/or > enclosure. Are you referring to the behaviour for handling HDDs or SSDs? For HDDs, the default "1" option could mean "automatic" and apply to rotational disks when power loss is expected. For SSDs, I don't think an extra stop should ever be an issue. -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 18/06/2020 09:36, Damien Le Moal wrote: > On 2020/06/18 3:50, Simon Arlott wrote: >> I need to use "reboot=p" on my desktop because one of the PCIe devices >> does not appear after a warm boot. This results in a very cold boot >> because the BIOS turns the PSU off and on. >> >> The scsi sd shutdown process does not send a stop command to disks >> before the reboot happens (stop commands are only sent for a shutdown). >> >> The result is that all of my SSDs experience a sudden power loss on >> every reboot, which is undesirable behaviour. These events are recorded >> in the SMART attributes. > > Why is it undesirable for an SSD ? The sequence you are describing is not > different from doing "shutdown -h now" and then pressing down the power button > again immediately after power is cut... On a shutdown the kernel will send a stop command to the SSD. It does not currently do this for a reboot so I observe the unexpected power loss counters increasing. > Are you experiencing data loss or corruption ? If yes, since a clean reboot or > shutdown issues a synchronize cache to all devices, a corruption would mean > that > your SSD is probably not correctly processing flush cache commands. No, I'm not experiencing any data loss or corruption that I'm aware of. We can argue whether or not any given SSD correctly processes commands to flush the cache, but they are expecting to be stopped before power is removed. >> Avoiding a stop of the disk on a reboot is appropriate for HDDs because >> they're likely to continue to be powered (and should not be told to spin >> down only to spin up again) but the default behaviour for SSDs should >> be changed to stop them before the reboot. > > If your BIOS turns the PSU down and up, then the HDDs too will lose power... > The > difference will be that the disks will still be spinning from inertia on the > power up, and so the HDD spin up processing will be faster than for a pure > cold > boot sequence. I haven't verified it, but the BIOS leaves the power off for several seconds which should be long enough for the HDDs to spin down. I'm less concerned about those suddenly losing power but it would be nice to have a stop command sent to them too. -- Simon Arlott
Re: [PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
On 17/06/2020 20:19, Bart Van Assche wrote: > On 2020-06-17 11:49, Simon Arlott wrote: >> @@ -3576,9 +3582,19 @@ static void sd_shutdown(struct device *dev) >> sd_sync_cache(sdkp, NULL); >> } >> >> -if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { >> -sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); >> -sd_start_stop_device(sdkp, 0); >> +if (sdkp->device->manage_start_stop) { >> +bool stop_disk = (system_state != SYSTEM_RESTART); >> + >> +if (stop_before_reboot > 1) { /* stop all disks */ >> +stop_disk = true; >> +} else if (stop_before_reboot) { /* non-rotational only */ >> +stop_disk |= blk_queue_nonrot(sdkp->disk->queue); >> +} >> + >> +if (stop_disk) { >> +sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); >> +sd_start_stop_device(sdkp, 0); >> +} >> } >> } > > Is introduction of a new kernel module parameter essential? It is system-dependent whether or not a reboot is going to result in a loss of power, so it's required to be able to stop the HDDs too. They're already always stopped on shutdown where power is definitely going to be lost. I can't do that by default on a reboot because the usual convention is that the power stays on during a reboot and it would be expected that the HDDs keep spinning. > Or in other > words, has it been considered to apply the new behavior to all SSDs? The default value is 1, so it does apply to all SSDs. I want to be able to configure it to apply to HDDs too. -- Simon Arlott
[PATCH] scsi: sd: stop SSD (non-rotational) disks before reboot
I need to use "reboot=p" on my desktop because one of the PCIe devices does not appear after a warm boot. This results in a very cold boot because the BIOS turns the PSU off and on. The scsi sd shutdown process does not send a stop command to disks before the reboot happens (stop commands are only sent for a shutdown). The result is that all of my SSDs experience a sudden power loss on every reboot, which is undesirable behaviour. These events are recorded in the SMART attributes. Avoiding a stop of the disk on a reboot is appropriate for HDDs because they're likely to continue to be powered (and should not be told to spin down only to spin up again) but the default behaviour for SSDs should be changed to stop them before the reboot. Add a "stop_before_reboot" module parameter that can be used to control the shutdown behaviour of disks before a reboot. The default will be to stop non-rotational disks (SSDs) only, but it can be configured to stop all disks if it is known that power will be lost completely on a reboot. sd_mod.stop_before_reboot= 0 = never 1 = non-rotational disks only (default) 2 = all disks The behaviour on shutdown is unchanged: all disks are unconditionally stopped. The disk I/O will be mostly quiescent at reboot time (and there is a sync first) but this should be added to stable kernels to protect all SSDs from unexpected power loss during a reboot by default. There is the potential for an unexpected power loss to corrupt data depending on the SSD model/firmware. Cc: sta...@vger.kernel.org Signed-off-by: Simon Arlott --- Documentation/scsi/scsi-parameters.rst | 7 +++ drivers/scsi/sd.c | 22 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Documentation/scsi/scsi-parameters.rst b/Documentation/scsi/scsi-parameters.rst index 9aba897c97ac..fd64d0d43861 100644 --- a/Documentation/scsi/scsi-parameters.rst +++ b/Documentation/scsi/scsi-parameters.rst @@ -101,6 +101,13 @@ parameters may be changed at runtime by the command allowing boot to proceed. none ignores them, expecting user space to do the scan. + sd_mod.stop_before_reboot= + [SCSI] configure stop action for disks before a reboot + Format: + 0 = never + 1 = non-rotational disks only (default) + 2 = all disks + sim710= [SCSI,HW] See header of drivers/scsi/sim710.c. diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d90fefffe31b..1cd652e037ab 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -98,6 +98,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC); +static unsigned int stop_before_reboot = 1; + +module_param(stop_before_reboot, uint, 0644); +MODULE_PARM_DESC(stop_before_reboot, +"stop disks before reboot (1=non-rotational, 2=all)"); + #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 #else @@ -3576,9 +3582,19 @@ static void sd_shutdown(struct device *dev) sd_sync_cache(sdkp, NULL); } - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); + if (sdkp->device->manage_start_stop) { + bool stop_disk = (system_state != SYSTEM_RESTART); + + if (stop_before_reboot > 1) { /* stop all disks */ + stop_disk = true; + } else if (stop_before_reboot) { /* non-rotational only */ + stop_disk |= blk_queue_nonrot(sdkp->disk->queue); + } + + if (stop_disk) { + sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); + sd_start_stop_device(sdkp, 0); + } } } -- 2.17.1 -- Simon Arlott
[PATCH v2 2/2] scsi: sr: Fix sr_probe() missing deallocate of device minor
If the cdrom fails to be registered then the device minor should be deallocated. Signed-off-by: Simon Arlott Cc: sta...@vger.kernel.org --- On 30/05/2020 17:24, Bart Van Assche wrote: > On 2020-05-30 02:33, Simon Arlott wrote: >> If the cdrom fails to be registered then the device minor should be >> deallocated. > > Also for this patch, please add Fixes: and Cc: stable tags. I've Cc:'d stable. There is no specific previous commit that this fixes. I was just checking the rest of sr_probe when making a patch for the first issue. drivers/scsi/sr.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 8d062d4f3ce0..1e13c6a0f0ca 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -797,7 +797,7 @@ static int sr_probe(struct device *dev) cd->cdi.disk = disk; if (register_cdrom(&cd->cdi)) - goto fail_put; + goto fail_minor; /* * Initialize block layer runtime PM stuffs before the @@ -815,6 +815,10 @@ static int sr_probe(struct device *dev) return 0; +fail_minor: + spin_lock(&sr_index_lock); + clear_bit(minor, sr_index_bits); + spin_unlock(&sr_index_lock); fail_put: put_disk(disk); mutex_destroy(&cd->lock); -- 2.17.1 -- Simon Arlott
[PATCH v2 1/2] scsi: sr: Fix sr_probe() missing mutex_destroy
If the device minor cannot be allocated or the cdrom fails to be registered then the mutex should be destroyed. Signed-off-by: Simon Arlott Fixes: 51a858817dcd ("scsi: sr: get rid of sr global mutex") Cc: sta...@vger.kernel.org --- On 30/05/2020 17:41, James Bottomley wrote: > On Sat, 2020-05-30 at 09:24 -0700, Bart Van Assche wrote: >> Please add Fixes: and Cc: stable tags. I've added a Fixes: tag and Cc:'d stable. > This isn't really a bug, is it? mutex_destroy is a nop unless lock > debugging is enabled in which case it checks the lock is unlocked and > marks it as unusable to detect a use after destroy. Since the > structure containing the mutex is kfree'd in the next statement, kasan > would also detect any use after free. That's not to say we shouldn't > do this to be fully correct ... just that it has no potential ever to > have user visible impact so there doesn't seem to be much point > cluttering up the stable process with it. If the current lock debugging implementation in stable will be ok with it then I'd agree there's no reason to put it in stable kernels, except that the commit this fixes was added to stable with this bug and one in sr_block_release (72655c0ebd1d). drivers/scsi/sr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d2fe3fa470f9..8d062d4f3ce0 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -817,6 +817,7 @@ static int sr_probe(struct device *dev) fail_put: put_disk(disk); + mutex_destroy(&cd->lock); fail_free: kfree(cd); fail: -- 2.17.1 -- Simon Arlott
[PATCH 2/2] scsi: sr: Fix sr_probe() missing deallocate of device minor
If the cdrom fails to be registered then the device minor should be deallocated. Signed-off-by: Simon Arlott --- drivers/scsi/sr.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 8d062d4f3ce0..1e13c6a0f0ca 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -797,7 +797,7 @@ static int sr_probe(struct device *dev) cd->cdi.disk = disk; if (register_cdrom(&cd->cdi)) - goto fail_put; + goto fail_minor; /* * Initialize block layer runtime PM stuffs before the @@ -815,6 +815,10 @@ static int sr_probe(struct device *dev) return 0; +fail_minor: + spin_lock(&sr_index_lock); + clear_bit(minor, sr_index_bits); + spin_unlock(&sr_index_lock); fail_put: put_disk(disk); mutex_destroy(&cd->lock); -- 2.17.1 -- Simon Arlott
[PATCH 1/2] scsi: sr: Fix sr_probe() missing mutex_destroy
If the device minor cannot be allocated or the cdrom fails to be registered then the mutex should be destroyed. Signed-off-by: Simon Arlott --- drivers/scsi/sr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d2fe3fa470f9..8d062d4f3ce0 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -817,6 +817,7 @@ static int sr_probe(struct device *dev) fail_put: put_disk(disk); + mutex_destroy(&cd->lock); fail_free: kfree(cd); fail: -- 2.17.1 -- Simon Arlott
[PATCH] mailmap: Add Simon Arlott (replacement for expired email address)
Add replacement email address for the one on my expired domain. Signed-off-by: Simon Arlott --- I'd prefer not to be in this "list of email addresses to spam" but it appears to be the only way to stop people searching for other addresses to misuse after I had to let my domain expire: "Where, as of the withdrawal date and as a result of the withdrawal of the United Kingdom, a holder of a domain name does no longer fulfil the general eligibility criteria pursuant to Article 4(2)(b) of Regulation (EC) 733/2002, the Registry for .eu will be entitled to revoke such domain name on its own initiative and without submitting the dispute to any extrajudicial settlement of conflicts in accordance with point (b) of Article 20, first subparagraph, of Commission Regulation (EC) No 874/2004." .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index acba1a6163f1..468e328ee572 100644 --- a/.mailmap +++ b/.mailmap @@ -214,6 +214,7 @@ Shuah Khan Shuah Khan Shuah Khan Shuah Khan +Simon Arlott Simon Kelley Stéphane Witzmann Stephen Hemminger -- 2.17.1 -- Simon Arlott
[tip:irq/core] irqchips/bmips: Add bcm6345-l1 interrupt controller
Commit-ID: c7c42ec2baa1de7ab3965e4f1bf5073bee6065e4 Gitweb: http://git.kernel.org/tip/c7c42ec2baa1de7ab3965e4f1bf5073bee6065e4 Author: Simon Arlott AuthorDate: Sun, 22 Nov 2015 14:30:14 + Committer: Thomas Gleixner CommitDate: Mon, 8 Feb 2016 15:03:42 +0100 irqchips/bmips: Add bcm6345-l1 interrupt controller Add the BCM6345 interrupt controller based on the SMP-capable BCM7038 and the BCM3380 but with packed interrupt registers. Add the BCM6345 interrupt controller to a list with the existing BCM7038 so that interrupts on CPU1 are not ignored. Update the maintainers file list for BMIPS to include this driver. Signed-off-by: Simon Arlott Cc: Mark Rutland Cc: devicet...@vger.kernel.org Cc: Ian Campbell Cc: Florian Fainelli Cc: Jason Cooper Cc: Pawel Moll Cc: linux-m...@linux-mips.org Cc: Marc Zyngier Cc: Kevin Cernekee Cc: Ralf Baechle Cc: Jonas Gorski Cc: Kumar Gala Cc: Rob Herring Link: http://lkml.kernel.org/r/5651d176.6030...@simon.arlott.org.uk Signed-off-by: Thomas Gleixner --- MAINTAINERS | 1 + arch/mips/Kconfig| 1 + arch/mips/bmips/irq.c| 10 +- drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-bcm6345-l1.c | 364 +++ 6 files changed, 380 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 7f1fa4f..b5fab14f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2423,6 +2423,7 @@ F:arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: include/linux/bcm963xx_nvram.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 57a945e..eb079ac 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -151,6 +151,7 @@ config BMIPS_GENERIC select CSRC_R4K select SYNC_R4K select COMMON_CLK + select BCM6345_L1_IRQ select BCM7038_L1_IRQ select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c index e7fc6f934..7efefcf 100644 --- a/arch/mips/bmips/irq.c +++ b/arch/mips/bmips/irq.c @@ -15,6 +15,12 @@ #include #include +static const struct of_device_id smp_intc_dt_match[] = { + { .compatible = "brcm,bcm7038-l1-intc" }, + { .compatible = "brcm,bcm6345-l1-intc" }, + {} +}; + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -24,8 +30,8 @@ void __init arch_init_irq(void) { struct device_node *dn; - /* Only the STB (bcm7038) controller supports SMP IRQ affinity */ - dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc"); + /* Only these controllers support SMP IRQ affinity */ + dn = of_find_matching_node(NULL, smp_intc_dt_match); if (dn) of_node_put(dn); else diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index fb50911..abe7a57 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -78,6 +78,11 @@ config I8259 bool select IRQ_DOMAIN +config BCM6345_L1_IRQ + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + config BCM7038_L1_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 18caacb..d91d99d 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX)+= irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_SOC_VF610)+= irq-vf610-mscm-ir.o +obj-$(CONFIG_BCM6345_L1_IRQ) += irq-bcm6345-l1.o obj-$(CONFIG_BCM7038_L1_IRQ) += irq-bcm7038-l1.o obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c new file mode 100644 index 000..b844c89 --- /dev/null +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -0,0 +1,364 @@ +/* + * Broadcom BCM6345 style Level 1 interrupt controller driver + * + * Copyright (C) 2014 Broadcom Corporation + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is based on the BCM7038 (which supports SMP) but with a single + * enable register instead of separate mask/set/clear registers. + * + * The BCM3380 has a similar mask/status register layout, but each pair + * of words is at separate locations (and SMP is not supported). + * + * ENABLE/STATUS words are packed next to each other
[tip:irq/core] irqchips/bmips: Add bcm6345-l1 interrupt controller
Commit-ID: 64e1741f92191a9d8c3949eff48a4670b440c9f8 Gitweb: http://git.kernel.org/tip/64e1741f92191a9d8c3949eff48a4670b440c9f8 Author: Simon Arlott AuthorDate: Sun, 22 Nov 2015 14:30:14 + Committer: Thomas Gleixner CommitDate: Mon, 8 Feb 2016 11:45:21 +0100 irqchips/bmips: Add bcm6345-l1 interrupt controller Add the BCM6345 interrupt controller based on the SMP-capable BCM7038 and the BCM3380 but with packed interrupt registers. Add the BCM6345 interrupt controller to a list with the existing BCM7038 so that interrupts on CPU1 are not ignored. Update the maintainers file list for BMIPS to include this driver. Signed-off-by: Simon Arlott Cc: Mark Rutland Cc: devicet...@vger.kernel.org Cc: Ian Campbell Cc: Florian Fainelli Cc: Jason Cooper Cc: Pawel Moll Cc: linux-m...@linux-mips.org Cc: Marc Zyngier Cc: Kevin Cernekee Cc: Ralf Baechle Cc: Jonas Gorski Cc: Kumar Gala Cc: Rob Herring Link: http://lkml.kernel.org/r/5651d176.6030...@simon.arlott.org.uk Signed-off-by: Thomas Gleixner --- MAINTAINERS | 1 + arch/mips/Kconfig| 1 + arch/mips/bmips/irq.c| 10 +- drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-bcm6345-l1.c | 364 +++ 6 files changed, 380 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 7f1fa4f..b5fab14f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2423,6 +2423,7 @@ F:arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: include/linux/bcm963xx_nvram.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 57a945e..eb079ac 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -151,6 +151,7 @@ config BMIPS_GENERIC select CSRC_R4K select SYNC_R4K select COMMON_CLK + select BCM6345_L1_IRQ select BCM7038_L1_IRQ select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c index e7fc6f934..7efefcf 100644 --- a/arch/mips/bmips/irq.c +++ b/arch/mips/bmips/irq.c @@ -15,6 +15,12 @@ #include #include +static const struct of_device_id smp_intc_dt_match[] = { + { .compatible = "brcm,bcm7038-l1-intc" }, + { .compatible = "brcm,bcm6345-l1-intc" }, + {} +}; + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -24,8 +30,8 @@ void __init arch_init_irq(void) { struct device_node *dn; - /* Only the STB (bcm7038) controller supports SMP IRQ affinity */ - dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc"); + /* Only these controllers support SMP IRQ affinity */ + dn = of_find_matching_node(NULL, smp_intc_dt_match); if (dn) of_node_put(dn); else diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index fb50911..abe7a57 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -78,6 +78,11 @@ config I8259 bool select IRQ_DOMAIN +config BCM6345_L1_IRQ + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + config BCM7038_L1_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 18caacb..d91d99d 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX)+= irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_SOC_VF610)+= irq-vf610-mscm-ir.o +obj-$(CONFIG_BCM6345_L1_IRQ) += irq-bcm6345-l1.o obj-$(CONFIG_BCM7038_L1_IRQ) += irq-bcm7038-l1.o obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c new file mode 100644 index 000..b844c89 --- /dev/null +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -0,0 +1,364 @@ +/* + * Broadcom BCM6345 style Level 1 interrupt controller driver + * + * Copyright (C) 2014 Broadcom Corporation + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is based on the BCM7038 (which supports SMP) but with a single + * enable register instead of separate mask/set/clear registers. + * + * The BCM3380 has a similar mask/status register layout, but each pair + * of words is at separate locations (and SMP is not supported). + * + * ENABLE/STATUS words are packed next to each other
[PATCH linux-next v4 11/11] mtd: bcm63xxpart: Add NAND partitioning support
Add partitioning support for BCM963xx boards with NAND flash. The following partitions are defined: "boot": CFE and nvram data "rootfs": Currently selected rootfs "data": Configuration data "rootfs1_update": Container for the whole flash area used for the first rootfs to allow it to be updated "rootfs2_update": Container for the whole flash area used for the second rootfs to allow it to be updated "rootfs_other": The other (not currently selected) rootfs Example: [2.157094] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1 [2.163796] nand: Macronix NAND 128MiB 3,3V 8-bit [2.168648] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [2.176588] bcm6368_nand 1200.nand: detected 128MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, Hamming ECC [2.189782] Bad block table found at page 65472, version 0x01 [2.196910] Bad block table found at page 65408, version 0x01 [2.204003] nand_read_bbt: bad block at 0x0748 [2.225220] bcm63xxpart: rootfs1: CFE image tag found at 0x2 with version 6, board type 963168VX [2.236188] bcm63xxpart: rootfs2: CFE image tag found at 0x400 with version 6, board type 963168VX [2.246165] bcm63xxpart: CFE bootline selected latest image rootfs1 (rootfs1_seq=2, rootfs2_seq=1) [2.255800] 6 bcm63xxpart partitions found on MTD device brcmnand.0 [2.275360] Creating 6 MTD partitions on "brcmnand.0": [2.280804] 0x-0x0002 : "boot" [2.294609] 0x0004-0x0112 : "rootfs" [2.310078] 0x07b0-0x07f0 : "data" [2.324052] 0x0002-0x03ac : "rootfs1_update" [2.339190] 0x0400-0x07ac : "rootfs2_update" [2.354290] 0x0402-0x0506 : "rootfs_other" The nvram contains the offset and size of the boot, rootfs1, rootfs2 and data partitions. The presence of CFE and nvram is already verified by reading from the boot partition which is assumed to be at offset 0 and the NAND process aborts if the nvram read indicates that this is not the case. There is bcm_tag information at the start of each rootfs that is used to determine which rootfs is newer and what its real offset/size is. The CFE bootline is used to select a rootfs. Signed-off-by: Simon Arlott --- v4: Reorganised functions based on earlier new patches in the series, no real logic changes other than having to check for nvram->version >= 6 within the nand function instead of the nvram read function. Renamed "curpart" to "i" because it allows the partition layout lines to be under 80 characters. v3: Use COMPILE_TEST. Ensure that strings read from flash are null terminated and validate bcm_tag integer values (this also moves reporting of rootfs sequence numbers to later on). v2: Use external struct bcm963xx_nvram definition for bcm963268part. Removed support for the nand partition number field, it's not a standard Broadcom field (was added by MitraStar Technology Corp.). drivers/mtd/bcm63xxpart.c | 196 -- 1 file changed, 190 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 26c38a1..4576b78 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * + * NAND flash layout derived from bcm963xx_4.12L.06B_consumer/bcmdrivers/opensource/char/board/bcm963xx/impl1/board.c, + * bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/bcm_hwdefs.h: + * Copyright (c) 2002 Broadcom Corporation */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -124,6 +123,25 @@ static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name, return 1; } +static bool bcm63xx_boot_latest(struct bcm963xx_nvram *nvram) +{ + char *p; + + STR_NULL_TERMINATE(nvram->bootline); + + /* Find previous image parameter "p" */ + if (!strncmp(nvram->bootline, "p=", 2)) + p = nvram->bootline; + else + p = strstr(nvram->bootline, " p="); + + if (p == NULL) + return true; + + p += 2; + return *p != '0'; +} + static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master, const struct mtd_partition **ppar
[PATCH linux-next v4 10/11] mtd: bcm63xxpart: Move NOR flash layout to a separate function
Move the NOR flash layout to a separate function to allow the NAND flash layout to be supported. Signed-off-by: Simon Arlott --- v4: New patch. drivers/mtd/bcm63xxpart.c | 54 --- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 41aa202..26c38a1 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -124,13 +124,11 @@ static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name, return 1; } -static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, - const struct mtd_partition **pparts, - struct mtd_part_parser_data *data) +static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master, + const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram) { /* CFE, NVRAM and global Linux are always present */ int nrparts = 3, curpart = 0; - struct bcm963xx_nvram *nvram = NULL; struct bcm_tag *buf = NULL; struct mtd_partition *parts; int ret; @@ -141,17 +139,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, int i; bool rootfs_first = false; - if (bcm63xx_detect_cfe(master)) - return -EINVAL; - - nvram = vzalloc(sizeof(*nvram)); - if (!nvram) - return -ENOMEM; - - ret = bcm63xx_read_nvram(master, nvram); - if (ret) - goto out; - cfe_erasesize = max_t(uint32_t, master->erasesize, BCM963XX_CFE_BLOCK_SIZE); @@ -159,12 +146,9 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, nvramlen = nvram->psi_size * SZ_1K; nvramlen = roundup(nvramlen, cfe_erasesize); - /* Allocate memory for buffer */ buf = vmalloc(sizeof(struct bcm_tag)); - if (!buf) { - ret = -ENOMEM; - goto out; - } + if (!buf) + return -ENOMEM; /* Get the tag */ ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf); @@ -234,7 +218,6 @@ invalid_tag: if (kernellen > 0) nrparts++; - /* Ask kernel for more memory */ parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); if (!parts) { ret = -ENOMEM; @@ -292,13 +275,40 @@ invalid_tag: ret = 0; out: - vfree(nvram); vfree(buf); if (ret) return ret; return nrparts; +} + +static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + struct bcm963xx_nvram *nvram = NULL; + int ret; + + if (bcm63xx_detect_cfe(master)) + return -EINVAL; + + nvram = vzalloc(sizeof(*nvram)); + if (!nvram) + return -ENOMEM; + + ret = bcm63xx_read_nvram(master, nvram); + if (ret) + goto out; + + if (!mtd_type_is_nand(master)) + ret = bcm63xx_parse_cfe_nor_partitions(master, pparts, nvram); + else + ret = -EINVAL; + +out: + vfree(nvram); + return ret; }; static struct mtd_part_parser bcm63xx_cfe_parser = { -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 09/11] mtd: bcm63xxpart: Null terminate and validate conversion of flash strings
Strings read from flash could be missing null termination characters, or not contain valid integers. Null terminate the strings and check for errors when converting them to integers. Also validate that the addresses are at least BCM963XX_EXTENDED_SIZE because this will be subtracted from them. Signed-off-by: Simon Arlott --- v4: New patch. drivers/mtd/bcm63xxpart.c | 38 ++ 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index eafbf52..41aa202 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -169,10 +169,39 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, /* Get the tag */ ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf); if (!ret) { - sscanf(buf->flash_image_start, "%u", &rootfsaddr); - sscanf(buf->kernel_address, "%u", &kerneladdr); - sscanf(buf->kernel_length, "%u", &kernellen); - sscanf(buf->total_length, "%u", &totallen); + STR_NULL_TERMINATE(buf->flash_image_start); + if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) || + rootfsaddr < BCM963XX_EXTENDED_SIZE) { + pr_err("invalid rootfs address: %*ph\n", + sizeof(buf->flash_image_start), + buf->flash_image_start); + goto invalid_tag; + } + + STR_NULL_TERMINATE(buf->kernel_address); + if (kstrtouint(buf->kernel_address, 10, &kerneladdr) || + kerneladdr < BCM963XX_EXTENDED_SIZE) { + pr_err("invalid kernel address: %*ph\n", + sizeof(buf->kernel_address), + buf->kernel_address); + goto invalid_tag; + } + + STR_NULL_TERMINATE(buf->kernel_length); + if (kstrtouint(buf->kernel_length, 10, &kernellen)) { + pr_err("invalid kernel length: %*ph\n", + sizeof(buf->kernel_length), + buf->kernel_length); + goto invalid_tag; + } + + STR_NULL_TERMINATE(buf->total_length); + if (kstrtouint(buf->total_length, 10, &totallen)) { + pr_err("invalid total length: %*ph\n", + sizeof(buf->total_length), + buf->total_length); + goto invalid_tag; + } kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; @@ -188,6 +217,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, rootfslen = spareaddr - rootfsaddr; } } else if (ret > 0) { +invalid_tag: kernellen = 0; rootfslen = 0; rootfsaddr = 0; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 08/11] mtd: bcm63xxpart: Extract read of image tag to separate function
Extract image tag reading and CRC check to a separate function. Signed-off-by: Simon Arlott --- v4: New patch. drivers/mtd/bcm63xxpart.c | 62 ++- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 1eea8b6..eafbf52 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -41,6 +41,10 @@ #define BCM963XX_CFE_VERSION_OFFSET0x570 #define BCM963XX_NVRAM_OFFSET 0x580 +/* Ensure strings read from flash structs are null terminated */ +#define STR_NULL_TERMINATE(x) \ + do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0) + static int bcm63xx_detect_cfe(struct mtd_info *master) { char buf[9]; @@ -89,6 +93,37 @@ static int bcm63xx_read_nvram(struct mtd_info *master, return 0; } +static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name, + loff_t tag_offset, struct bcm_tag *buf) +{ + int ret; + size_t retlen; + u32 computed_crc; + + ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf); + if (ret) + return ret; + + if (retlen != sizeof(*buf)) + return -EIO; + + computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, + offsetof(struct bcm_tag, header_crc)); + if (computed_crc == buf->header_crc) { + STR_NULL_TERMINATE(buf->board_id); + STR_NULL_TERMINATE(buf->tag_version); + + pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n", + name, tag_offset, buf->tag_version, buf->board_id); + + return 0; + } + + pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n", + name, tag_offset, buf->header_crc, computed_crc); + return 1; +} + static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data) @@ -99,13 +134,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, struct bcm_tag *buf = NULL; struct mtd_partition *parts; int ret; - size_t retlen; unsigned int rootfsaddr, kerneladdr, spareaddr; unsigned int rootfslen, kernellen, sparelen, totallen; unsigned int cfelen, nvramlen; unsigned int cfe_erasesize; int i; - u32 computed_crc; bool rootfs_first = false; if (bcm63xx_detect_cfe(master)) @@ -134,28 +167,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, } /* Get the tag */ - ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, - (void *)buf); - - if (retlen != sizeof(struct bcm_tag)) { - ret = -EIO; - goto out; - } - - computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, - offsetof(struct bcm_tag, header_crc)); - if (computed_crc == buf->header_crc) { - char *boardid = &(buf->board_id[0]); - char *tagversion = &(buf->tag_version[0]); - + ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf); + if (!ret) { sscanf(buf->flash_image_start, "%u", &rootfsaddr); sscanf(buf->kernel_address, "%u", &kerneladdr); sscanf(buf->kernel_length, "%u", &kernellen); sscanf(buf->total_length, "%u", &totallen); - pr_info("CFE boot tag found with version %s and board type %s\n", - tagversion, boardid); - kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; spareaddr = roundup(totallen, master->erasesize) + cfelen; @@ -169,13 +187,13 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, rootfsaddr = kerneladdr + kernellen; rootfslen = spareaddr - rootfsaddr; } - } else { - pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", - buf->header_crc, computed_crc); + } else if (ret > 0) { kernellen = 0; rootfslen = 0; rootfsaddr = 0; spareaddr = cfelen; + } else { + goto out; } sparelen = master->size - spareaddr - nvramlen; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 07/11] MIPS: bcm63xx: nvram: Remove unused bcm63xx_nvram_get_psi_size() function
Remove bcm63xx_nvram_get_psi_size() as it now has no users. Signed-off-by: Simon Arlott --- v4: New patch. arch/mips/bcm63xx/nvram.c | 11 --- arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 2 -- 2 files changed, 13 deletions(-) diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 05757ae..5f2bc1e 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -19,8 +19,6 @@ #include -#define BCM63XX_DEFAULT_PSI_SIZE 64 - static struct bcm963xx_nvram nvram; static int mac_addr_used; @@ -87,12 +85,3 @@ int bcm63xx_nvram_get_mac_address(u8 *mac) return 0; } EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); - -int bcm63xx_nvram_get_psi_size(void) -{ - if (nvram.psi_size > 0) - return nvram.psi_size; - - return BCM63XX_DEFAULT_PSI_SIZE; -} -EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 348df49..4e0b6bc 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -30,6 +30,4 @@ u8 *bcm63xx_nvram_get_name(void); */ int bcm63xx_nvram_get_mac_address(u8 *mac); -int bcm63xx_nvram_get_psi_size(void); - #endif /* BCM63XX_NVRAM_H */ -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 06/11] mtd: bcm63xxpart: Remove dependency on mach-bcm63xx
Read nvram directly from flash instead of using the in-memory copy that mach-bcm63xx has, to remove the dependency on mach-bcm63xx and allow the parser to work on bmips too. Rename remaining BCM63XX defines to BCM963XX as these are properties of the flash layout on the board. BCM963XX_DEFAULT_PSI_SIZE changes from SZ_64K to 64 because it will be multiplied by SZ_1K later on. Signed-off-by: Simon Arlott --- v4: New patch. drivers/mtd/Kconfig | 2 +- drivers/mtd/bcm63xxpart.c | 72 +-- 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 42cc953..e83a279 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -142,7 +142,7 @@ config MTD_AR7_PARTS config MTD_BCM63XX_PARTS tristate "BCM63XX CFE partitioning support" - depends on BCM63XX + depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST select CRC32 help This provides partions parsing for BCM63xx devices with CFE diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index cec3188..1eea8b6 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -24,6 +24,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -34,12 +35,11 @@ #include #include -#include -#include +#define BCM963XX_CFE_BLOCK_SIZESZ_64K /* always at least 64KiB */ -#define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ - -#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 +#define BCM963XX_CFE_MAGIC_OFFSET 0x4e0 +#define BCM963XX_CFE_VERSION_OFFSET0x570 +#define BCM963XX_NVRAM_OFFSET 0x580 static int bcm63xx_detect_cfe(struct mtd_info *master) { @@ -58,20 +58,45 @@ static int bcm63xx_detect_cfe(struct mtd_info *master) return 0; /* very old CFE's do not have the cfe-v string, so check for magic */ - ret = mtd_read(master, BCM63XX_CFE_MAGIC_OFFSET, 8, &retlen, + ret = mtd_read(master, BCM963XX_CFE_MAGIC_OFFSET, 8, &retlen, (void *)buf); buf[retlen] = 0; return strncmp("CFE1CFE1", buf, 8); } +static int bcm63xx_read_nvram(struct mtd_info *master, + struct bcm963xx_nvram *nvram) +{ + u32 actual_crc, expected_crc; + size_t retlen; + int ret; + + /* extract nvram data */ + ret = mtd_read(master, BCM963XX_NVRAM_OFFSET, BCM963XX_NVRAM_V5_SIZE, + &retlen, (void *)nvram); + if (ret) + return ret; + + ret = bcm963xx_nvram_checksum(nvram, &expected_crc, &actual_crc); + if (ret) + pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", + expected_crc, actual_crc); + + if (!nvram->psi_size) + nvram->psi_size = BCM963XX_DEFAULT_PSI_SIZE; + + return 0; +} + static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { /* CFE, NVRAM and global Linux are always present */ int nrparts = 3, curpart = 0; - struct bcm_tag *buf; + struct bcm963xx_nvram *nvram = NULL; + struct bcm_tag *buf = NULL; struct mtd_partition *parts; int ret; size_t retlen; @@ -86,25 +111,35 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, if (bcm63xx_detect_cfe(master)) return -EINVAL; + nvram = vzalloc(sizeof(*nvram)); + if (!nvram) + return -ENOMEM; + + ret = bcm63xx_read_nvram(master, nvram); + if (ret) + goto out; + cfe_erasesize = max_t(uint32_t, master->erasesize, - BCM63XX_CFE_BLOCK_SIZE); + BCM963XX_CFE_BLOCK_SIZE); cfelen = cfe_erasesize; - nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K; + nvramlen = nvram->psi_size * SZ_1K; nvramlen = roundup(nvramlen, cfe_erasesize); /* Allocate memory for buffer */ buf = vmalloc(sizeof(struct bcm_tag)); - if (!buf) - return -ENOMEM; + if (!buf) { + ret = -ENOMEM; + goto out; + } /* Get the tag */ ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, (void *)buf); if (retlen != sizeof(struct bcm_tag)) { - vfree(buf); - return -EIO; + ret = -EIO; + goto out; } computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, @@ -154,8 +189,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, /* Ask kernel for more memo
[PATCH linux-next v4 05/11] MIPS: bcm963xx: Update bcm_tag field image_sequence
The "dual_image" and "inactive_flag" fields should be merged into a single "image_sequence" field. Signed-off-by: Simon Arlott --- v4: New patch. include/linux/bcm963xx_tag.h | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/linux/bcm963xx_tag.h b/include/linux/bcm963xx_tag.h index 08e0133..161c7b3 100644 --- a/include/linux/bcm963xx_tag.h +++ b/include/linux/bcm963xx_tag.h @@ -12,8 +12,7 @@ #define CHIPID_LEN 6 /* Chip Id Length */ #define IMAGE_LEN 10 /* Length of Length Field */ #define ADDRESS_LEN12 /* Length of Address field */ -#define DUALFLAG_LEN 2 /* Dual Image flag Length */ -#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ +#define IMAGE_SEQUENCE_LEN 4 /* Image sequence Length */ #define RSASIG_LEN 20 /* Length of RSA Signature in tag */ #define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ #define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ @@ -72,10 +71,10 @@ struct bcm_tag { char kernel_address[ADDRESS_LEN]; /* 128-137: Size of kernel */ char kernel_length[IMAGE_LEN]; - /* 138-139: Unused at the moment */ - char dual_image[DUALFLAG_LEN]; - /* 140-141: Unused at the moment */ - char inactive_flag[INACTIVEFLAG_LEN]; + /* 138-141: Image sequence number +* (to be incremented when flashed with a new image) +*/ + char image_sequence[IMAGE_SEQUENCE_LEN]; /* 142-161: RSA Signature (not used; some vendors may use this) */ char rsa_signature[RSASIG_LEN]; /* 162-191: Compilation and related information (not used in OpenWrt) */ -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 04/11] MIPS: bcm963xx: Move extended flash address to bcm_tag header file
The extended flash address needs to be subtracted from bcm_tag flash image offsets. Move this value to the bcm_tag header file. Renamed define name to consistently use bcm963xx for flash layout which should be considered a property of the board and not the SoC (i.e. bcm63xx could theoretically be used on a board without CFE or any flash). Signed-off-by: Simon Arlott --- v4: New patch. drivers/mtd/bcm63xxpart.c| 6 ++ include/linux/bcm963xx_tag.h | 5 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index b5bad1f..cec3188 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -37,8 +37,6 @@ #include #include -#define BCM63XX_EXTENDED_SIZE 0xBFC0 /* Extended flash address */ - #define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 @@ -123,8 +121,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, pr_info("CFE boot tag found with version %s and board type %s\n", tagversion, boardid); - kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; - rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; + kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; + rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; spareaddr = roundup(totallen, master->erasesize) + cfelen; if (rootfsaddr < kerneladdr) { diff --git a/include/linux/bcm963xx_tag.h b/include/linux/bcm963xx_tag.h index f389dac..08e0133 100644 --- a/include/linux/bcm963xx_tag.h +++ b/include/linux/bcm963xx_tag.h @@ -28,6 +28,11 @@ "DWV-S0", \ } +/* Extended flash address, needs to be subtracted + * from bcm_tag flash image offsets. + */ +#define BCM963XX_EXTENDED_SIZE 0xBFC0 + /* * The broadcom firmware assumes the rootfs starts the image, * therefore uses the rootfs start (flash_image_address) -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 03/11] MIPS: bcm963xx: Move Broadcom BCM963xx image tag data structure
Move Broadcom BCM963xx image tag data structure to include/linux/ so that drivers outside of mach-bcm63xx can use it. Signed-off-by: Simon Arlott --- v4: New patch. MAINTAINERS | 1 + arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h | 96 -- drivers/mtd/bcm63xxpart.c | 2 +- include/linux/bcm963xx_tag.h | 98 +++ 4 files changed, 100 insertions(+), 97 deletions(-) delete mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h create mode 100644 include/linux/bcm963xx_tag.h diff --git a/MAINTAINERS b/MAINTAINERS index ac7de1a..b2ef403 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2392,6 +2392,7 @@ F:arch/mips/boot/dts/brcm/bcm*.dts* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: include/linux/bcm963xx_nvram.h +F: include/linux/bcm963xx_tag.h BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h deleted file mode 100644 index 1e6b587..000 --- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef __BCM963XX_TAG_H -#define __BCM963XX_TAG_H - -#define TAGVER_LEN 4 /* Length of Tag Version */ -#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ -#define SIG1_LEN 20 /* Company Signature 1 Length */ -#define SIG2_LEN 14 /* Company Signature 2 Length */ -#define BOARDID_LEN16 /* Length of BoardId */ -#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ -#define CHIPID_LEN 6 /* Chip Id Length */ -#define IMAGE_LEN 10 /* Length of Length Field */ -#define ADDRESS_LEN12 /* Length of Address field */ -#define DUALFLAG_LEN 2 /* Dual Image flag Length */ -#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ -#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ -#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ -#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ -#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ -#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */ - -#define NUM_PIRELLI2 -#define IMAGETAG_CRC_START 0x - -#define PIRELLI_BOARDS { \ - "AGPF-S0", \ - "DWV-S0", \ -} - -/* - * The broadcom firmware assumes the rootfs starts the image, - * therefore uses the rootfs start (flash_image_address) - * to determine where to flash the image. Since we have the kernel first - * we have to give it the kernel address, but the crc uses the length - * associated with this address (root_length), which is added to the kernel - * length (kernel_length) to determine the length of image to flash and thus - * needs to be rootfs + deadcode (jffs2 EOF marker) -*/ - -struct bcm_tag { - /* 0-3: Version of the image tag */ - char tag_version[TAGVER_LEN]; - /* 4-23: Company Line 1 */ - char sig_1[SIG1_LEN]; - /* 24-37: Company Line 2 */ - char sig_2[SIG2_LEN]; - /* 38-43: Chip this image is for */ - char chip_id[CHIPID_LEN]; - /* 44-59: Board name */ - char board_id[BOARDID_LEN]; - /* 60-61: Map endianness -- 1 BE 0 LE */ - char big_endian[ENDIANFLAG_LEN]; - /* 62-71: Total length of image */ - char total_length[IMAGE_LEN]; - /* 72-83: Address in memory of CFE */ - char cfe__address[ADDRESS_LEN]; - /* 84-93: Size of CFE */ - char cfe_length[IMAGE_LEN]; - /* 94-105: Address in memory of image start -* (kernel for OpenWRT, rootfs for stock firmware) -*/ - char flash_image_start[ADDRESS_LEN]; - /* 106-115: Size of rootfs */ - char root_length[IMAGE_LEN]; - /* 116-127: Address in memory of kernel */ - char kernel_address[ADDRESS_LEN]; - /* 128-137: Size of kernel */ - char kernel_length[IMAGE_LEN]; - /* 138-139: Unused at the moment */ - char dual_image[DUALFLAG_LEN]; - /* 140-141: Unused at the moment */ - char inactive_flag[INACTIVEFLAG_LEN]; - /* 142-161: RSA Signature (not used; some vendors may use this) */ - char rsa_signature[RSASIG_LEN]; - /* 162-191: Compilation and related information (not used in OpenWrt) */ - char information1[TAGINFO1_LEN]; - /* 192-195: Version flash layout */ - char flash_layout_ver[FLASHLAYOUTVER_LEN]; - /* 196-199: kernel+rootfs CRC32 */ - __u32 fskernel_crc; - /* 200-215: Unused except on Alice Gate where is is information */ - char information2[TAGINFO2_LEN]; - /* 216-219: CRC32 of
[PATCH linux-next v4 02/11] MIPS: bcm63xx: nvram: Use nvram structure definition from header file
Use the common definition of the nvram structure from the header file include/linux/bcm963xx_nvram.h instead of maintaining a separate copy. Read the version 5 size of nvram data from memory and then call the new checksum verification function from the header file. Signed-off-by: Simon Arlott --- v4: Use checksum verification function from header file. v3: No changes (reworded commit message). v2: Use external struct bcm963xx_nvram definition for bcm963268part. arch/mips/bcm63xx/nvram.c | 35 +++ 1 file changed, 3 insertions(+), 32 deletions(-) diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 4b50d40..05757ae 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) "bcm63xx_nvram: " fmt +#include #include #include #include @@ -18,23 +19,6 @@ #include -/* - * nvram structure - */ -struct bcm963xx_nvram { - u32 version; - u8 reserved1[256]; - u8 name[16]; - u32 main_tp_number; - u32 psi_size; - u32 mac_addr_count; - u8 mac_addr_base[ETH_ALEN]; - u8 reserved2[2]; - u32 checksum_old; - u8 reserved3[720]; - u32 checksum_high; -}; - #define BCM63XX_DEFAULT_PSI_SIZE 64 static struct bcm963xx_nvram nvram; @@ -42,27 +26,14 @@ static int mac_addr_used; void __init bcm63xx_nvram_init(void *addr) { - unsigned int check_len; u32 crc, expected_crc; u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; /* extract nvram data */ - memcpy(&nvram, addr, sizeof(nvram)); + memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE); /* check checksum before using data */ - if (nvram.version <= 4) { - check_len = offsetof(struct bcm963xx_nvram, reserved3); - expected_crc = nvram.checksum_old; - nvram.checksum_old = 0; - } else { - check_len = sizeof(nvram); - expected_crc = nvram.checksum_high; - nvram.checksum_high = 0; - } - - crc = crc32_le(~0, (u8 *)&nvram, check_len); - - if (crc != expected_crc) + if (bcm963xx_nvram_checksum(&nvram, &expected_crc, &crc)) pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", expected_crc, crc); -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 01/11] MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
Broadcom BCM963xx boards have multiple nvram variants across different SoCs with additional checksum fields added whenever the size of the nvram was extended. Add this structure as a header file so that multiple drivers can use it. Signed-off-by: Simon Arlott --- v4: Move out of uapi. Add nand offset/size functions/macros. Add checksum calculation function. v3: Fix includes/type names, add comments explaining the nvram struct. v2: Use external struct bcm963xx_nvram definition for bcm963268part. MAINTAINERS| 1 + include/linux/bcm963xx_nvram.h | 112 + 2 files changed, 113 insertions(+) create mode 100644 include/linux/bcm963xx_nvram.h diff --git a/MAINTAINERS b/MAINTAINERS index 31fc0bf..ac7de1a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2391,6 +2391,7 @@ F:arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* +F: include/linux/bcm963xx_nvram.h BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan diff --git a/include/linux/bcm963xx_nvram.h b/include/linux/bcm963xx_nvram.h new file mode 100644 index 000..290c231 --- /dev/null +++ b/include/linux/bcm963xx_nvram.h @@ -0,0 +1,112 @@ +#ifndef __LINUX_BCM963XX_NVRAM_H__ +#define __LINUX_BCM963XX_NVRAM_H__ + +#include +#include +#include +#include + +/* + * Broadcom BCM963xx SoC board nvram data structure. + * + * The nvram structure varies in size depending on the SoC board version. Use + * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information + * you need instead of sizeof(struct bcm963xx_nvram) as this may change. + */ + +#define BCM963XX_NVRAM_V4_SIZE 300 +#define BCM963XX_NVRAM_V5_SIZE (1 * SZ_1K) + +#define BCM963XX_DEFAULT_PSI_SIZE 64 + +enum bcm963xx_nvram_nand_part { + BCM963XX_NVRAM_NAND_PART_BOOT = 0, + BCM963XX_NVRAM_NAND_PART_ROOTFS_1, + BCM963XX_NVRAM_NAND_PART_ROOTFS_2, + BCM963XX_NVRAM_NAND_PART_DATA, + BCM963XX_NVRAM_NAND_PART_BBT, + + __BCM963XX_NVRAM_NAND_NR_PARTS +}; + +struct bcm963xx_nvram { + u32 version; + charbootline[256]; + charname[16]; + u32 main_tp_number; + u32 psi_size; + u32 mac_addr_count; + u8 mac_addr_base[ETH_ALEN]; + u8 __reserved1[2]; + u32 checksum_v4; + + u8 __reserved2[292]; + u32 nand_part_offset[__BCM963XX_NVRAM_NAND_NR_PARTS]; + u32 nand_part_size[__BCM963XX_NVRAM_NAND_NR_PARTS]; + u8 __reserved3[388]; + u32 checksum_v5; +}; + +#define BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, part) \ + bcm963xx_nvram_nand_part_offset(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) + +static inline u64 __pure bcm963xx_nvram_nand_part_offset( + const struct bcm963xx_nvram *nvram, + enum bcm963xx_nvram_nand_part part) +{ + return nvram->nand_part_offset[part] * SZ_1K; +} + +#define BCM963XX_NVRAM_NAND_PART_SIZE(nvram, part) \ + bcm963xx_nvram_nand_part_size(nvram, BCM963XX_NVRAM_NAND_PART_ ##part) + +static inline u64 __pure bcm963xx_nvram_nand_part_size( + const struct bcm963xx_nvram *nvram, + enum bcm963xx_nvram_nand_part part) +{ + return nvram->nand_part_size[part] * SZ_1K; +} + +/* + * bcm963xx_nvram_checksum - Verify nvram checksum + * + * @nvram: pointer to full size nvram data structure + * @expected_out: optional pointer to store expected checksum value + * @actual_out: optional pointer to store actual checksum value + * + * Return: 0 if the checksum is valid, otherwise -EINVAL + */ +static int __maybe_unused bcm963xx_nvram_checksum( + const struct bcm963xx_nvram *nvram, + u32 *expected_out, u32 *actual_out) +{ + u32 expected, actual; + size_t len; + + if (nvram->version <= 4) { + expected = nvram->checksum_v4; + len = BCM963XX_NVRAM_V4_SIZE - sizeof(u32); + } else { + expected = nvram->checksum_v5; + len = BCM963XX_NVRAM_V5_SIZE - sizeof(u32); + } + + /* +* Calculate the CRC32 value for the nvram with a checksum value +* of 0 without modifying or copying the nvram by combining: +* - The CRC32 of the nvram without the checksum value +* - The CRC32 of a zero checksum value (which is also 0) +*/ + actual = crc32_le_combine( + crc32_le(~0, (u8 *)nvram, len), 0, sizeof(u32)); + + if (expected_out) + *expected_out = expected; + + if (actual_out) + *actual_out = actual; + + return expected == actual ? 0 : -EINVAL; +}; + +#endif /* __LINUX_BCM963XX_NVRAM_H__ */ -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http
Re: [PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning support
On 13/12/15 22:42, Simon Arlott wrote: > The BCM963xx NAND flash boards have a different handling of the > partition layout from the NOR flash boards. For NAND there are offsets > for the partitions in nvram. Both types of boards use the same CFE > bootloader, nvram format and image tag in their rootfs partitions. > > This patch series: > 1-4: Creates separate header files for bcm963xx_nvram and bcm_tag structures > 5:Updates the bcm_tag field image_sequence > 6:Removes the dependency on mach-bcm63xx from the bcm63xxpart parser > 7:Removes unused mach-bcm63xx nvram function > 8-10: Cleanup and move NOR flash layout to a separate function > 11: Add NAND flash layout support These patches are also available on github against next-20151211: https://github.com/lp0/linux/commits/20151213-bcm63xxpart-v4 (Yes I am aware that the summary line and description of the patches are not suitable for merging.) -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next v4 00/11] mtd: bcm63xxpart: Add NAND partitioning support
The BCM963xx NAND flash boards have a different handling of the partition layout from the NOR flash boards. For NAND there are offsets for the partitions in nvram. Both types of boards use the same CFE bootloader, nvram format and image tag in their rootfs partitions. This patch series: 1-4: Creates separate header files for bcm963xx_nvram and bcm_tag structures 5:Updates the bcm_tag field image_sequence 6:Removes the dependency on mach-bcm63xx from the bcm63xxpart parser 7:Removes unused mach-bcm63xx nvram function 8-10: Cleanup and move NOR flash layout to a separate function 11: Add NAND flash layout support Patches 1-2 tested on BCM63XX with a BCM963168 (NAND) board. Patches 3-11 compile tested on BCM63XX. Patches 6-11 tested on BMIPS with a BCM963168 (NAND) board. --- v4: Move struct bcm_tag to include/linux/. Modify bcm63xx parser to read nvram from NOR flash and handle the NAND flash layout in the same parser. v3: Fix includes/type names, add comments explaining the nvram struct. Use COMPILE_TEST. Ensure that strings read from flash are null terminated and validate bcm_tag integer values (this also moves reporting of rootfs sequence numbers to later on). v2: Use external struct bcm963xx_nvram definition for bcm963268part. Removed support for the nand partition number field, it's not a standard Broadcom field (was added by MitraStar Technology Corp.). -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH linux-next (v3) 3/3] mtd: part: Add BCM962368 CFE partitioning support
On 11/12/15 23:12, Jonas Gorski wrote: > On Fri, Dec 11, 2015 at 11:02 PM, Simon Arlott wrote: >> +#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 >> +#define BCM963XX_CFE_VERSION_OFFSET0x570 >> +#define BCM963XX_NVRAM_OFFSET 0x580 > > You should decide whether you want to call it BCM63XX (the SoC) or > BCM963XX (the Board using the SoC). Also probably better served in > bcm963xx_nvram.h I'm going to name the CFE locations, nvram and anything that is a property of the flash layout BCM963XX_*, as a theoretical board using BCM63XX with no flash wouldn't use these. The parser is still called bcm63xxpart so that's currently an anomaly. I'm working on making it support both NOR and NAND flash layouts. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH linux-next (v3) 1/3] MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
On 11/12/15 23:29, Jonas Gorski wrote: > On Fri, Dec 11, 2015 at 11:24 PM, Simon Arlott wrote: >> On 11/12/15 22:02, Jonas Gorski wrote: >>> On Fri, Dec 11, 2015 at 10:54 PM, Simon Arlott wrote: >>>> Broadcom BCM963xx boards have multiple nvram variants across different >>>> SoCs with additional checksum fields added whenever the size of the >>>> nvram was extended. >>>> >>>> Add this structure as a header file so that multiple drivers and userspace >>>> can use it. >>>> >>>> Signed-off-by: Simon Arlott >>>> --- >>>> v3: Fix includes/type names, add comments explaining the nvram struct. >>>> >>>> v2: Use external struct bcm963xx_nvram definition for bcm963268part. ... >>>> diff --git a/include/uapi/linux/bcm963xx_nvram.h >>>> b/include/uapi/linux/bcm963xx_nvram.h >>>> new file mode 100644 >>>> index 000..2dcb307 >>>> --- /dev/null >>>> +++ b/include/uapi/linux/bcm963xx_nvram.h >>> >>> Why uapi? The nvram layout isn't really enforced to be that way, and >>> at least Huawei uses a modified one on some devices (in case you >>> wondered why bcm63xx doesn't fail a crc32-"broken" one), so IMHO it >>> should be kept for in-kernel use only. >> >> Because Florian suggested include/uapi/linux/bcm963xx_nvram.h; I could >> move it to include/linux/ instead if this is preferred. ... >>>> + * Do not use the __reserved fields, especially not as an offset for CRC >>>> + * calculations (use BCM963XX_NVRAM_*_SIZE instead). These may be removed >>>> or >>>> + * repositioned. > > Because I just saw that: Nobody will read that. ;p I'll move this to include/linux/bcm963xx_nvram.h and omit the linux-api mailing list when I next send the patch series. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH linux-next (v3) 1/3] MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
On 11/12/15 22:02, Jonas Gorski wrote: > Hi, > > On Fri, Dec 11, 2015 at 10:54 PM, Simon Arlott wrote: >> Broadcom BCM963xx boards have multiple nvram variants across different >> SoCs with additional checksum fields added whenever the size of the >> nvram was extended. >> >> Add this structure as a header file so that multiple drivers and userspace >> can use it. >> >> Signed-off-by: Simon Arlott >> --- >> v3: Fix includes/type names, add comments explaining the nvram struct. >> >> v2: Use external struct bcm963xx_nvram definition for bcm963268part. >> >> MAINTAINERS | 1 + >> include/uapi/linux/bcm963xx_nvram.h | 53 >> + >> 2 files changed, 54 insertions(+) >> create mode 100644 include/uapi/linux/bcm963xx_nvram.h >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 6b6d4e2e..abf18b4 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -2393,6 +2393,7 @@ F:drivers/irqchip/irq-bcm63* >> F: drivers/irqchip/irq-bcm7* >> F: drivers/irqchip/irq-brcmstb* >> F: include/linux/bcm63xx_wdt.h >> +F: include/uapi/linux/bcm963xx_nvram.h >> >> BROADCOM TG3 GIGABIT ETHERNET DRIVER >> M: Prashant Sreedharan >> diff --git a/include/uapi/linux/bcm963xx_nvram.h >> b/include/uapi/linux/bcm963xx_nvram.h >> new file mode 100644 >> index 000..2dcb307 >> --- /dev/null >> +++ b/include/uapi/linux/bcm963xx_nvram.h > > Why uapi? The nvram layout isn't really enforced to be that way, and > at least Huawei uses a modified one on some devices (in case you > wondered why bcm63xx doesn't fail a crc32-"broken" one), so IMHO it > should be kept for in-kernel use only. Because Florian suggested include/uapi/linux/bcm963xx_nvram.h; I could move it to include/linux/ instead if this is preferred. >> @@ -0,0 +1,53 @@ >> +#ifndef _UAPI__LINUX_BCM963XX_NVRAM_H__ >> +#define _UAPI__LINUX_BCM963XX_NVRAM_H__ >> + >> +#include >> +#include >> + >> +/* >> + * Broadcom BCM963xx SoC board nvram data structure. >> + * >> + * The nvram structure varies in size depending on the SoC board version. >> Use >> + * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information >> + * you need instead of sizeof(struct bcm963xx_nvram) as this may change. >> + * >> + * The "version" field value maps directly to the size and checksum names, >> e.g. >> + * version 4 uses "checksum_v4" and the data is BCM963XX_NVRAM_V4_SIZE >> bytes. >> + * >> + * Do not use the __reserved fields, especially not as an offset for CRC >> + * calculations (use BCM963XX_NVRAM_*_SIZE instead). These may be removed or >> + * repositioned. >> + */ >> + >> +#define BCM963XX_NVRAM_V4_SIZE 300 >> +#define BCM963XX_NVRAM_V5_SIZE 1024 >> +#define BCM963XX_NVRAM_V6_SIZE BCM963XX_NVRAM_V5_SIZE >> +#define BCM963XX_NVRAM_V7_SIZE 3072 >> + >> +#define BCM963XX_NVRAM_NR_PARTS5 >> + >> +struct bcm963xx_nvram { >> + __u32 version; >> + charbootline[256]; >> + charname[16]; >> + __u32 main_tp_number; >> + __u32 psi_size; >> + __u32 mac_addr_count; >> + __u8mac_addr_base[ETH_ALEN]; >> + __u8__reserved1[2]; >> + __u32 checksum_v4; >> + >> + __u8__reserved2[292]; >> + __u32 nand_part_offset[BCM963XX_NVRAM_NR_PARTS]; >> + __u32 nand_part_size[BCM963XX_NVRAM_NR_PARTS]; >> + __u8__reserved3[388]; >> + union { >> + __u32 checksum_v5; >> + __u32 checksum_v6; >> + }; > > what's the point of this union? Both are the same size and have the > same function. For convenience when deciding which size of nvram to use. The mach-bcm63xx code uses the V5 definitions because it supports checksums at the v4 and v5 sizes. The bcm963xxpart code uses the V6 definitions because that's what my board has and I can't tell if the nand_part values are valid in version 5 or if they were only added in version 6. >> + >> + __u8__reserved4[2044]; >> + __u32 checksum_v7; >> +} __packed; > > Why is it __packed? there are no unaligned members, so it should work > fine without this (and it did for bcm63xx). I could remove it, but as soon as someone adds an unaligned member but forgets to add __packed it's going to break. There are unaligned members in some of the __reserved areas, like this one: #define NVRAM_GPON_SERIAL_NUMBER_LEN13 #define NVRAM_GPON_PASSWORD_LEN 11 char gponSerialNumber[NVRAM_GPON_SERIAL_NUMBER_LEN]; char gponPassword[NVRAM_GPON_PASSWORD_LEN]; -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v3) 3/3] mtd: part: Add BCM962368 CFE partitioning support
Add partitioning support for BCM963268 boards with CFE bootloaders. The following partitions are defined: "boot": CFE and nvram data "rootfs": Currently selected rootfs "data": Configuration data "rootfs1_update": Container for the whole flash area used for the first rootfs to allow it to be updated. "rootfs2_update": Container for the whole flash area used for the second rootfs to allow it to be updated. "rootfs_other": The other (not currently selected) rootfs Example: [1.904302] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1 [1.911000] nand: Macronix NAND 128MiB 3,3V 8-bit [1.915855] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [1.923797] bcm6368_nand 1200.nand: detected 128MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, Hamming ECC [1.936994] Bad block table found at page 65472, version 0x01 [1.944121] Bad block table found at page 65408, version 0x01 [1.951166] nand_read_bbt: bad block at 0x0748 [1.969377] bcm963268part: rootfs1: CFE boot tag found at 0x2 with version 6, board type 963168VX [1.980690] bcm963268part: rootfs2: CFE boot tag found at 0x400 with version 6, board type 963168VX [1.990801] bcm963268part: CFE bootline selected latest image rootfs1 (rootfs1_seq=2, rootfs2_seq=1) [2.022080] 6 bcm963268part partitions found on MTD device brcmnand.0 [2.042659] Creating 6 MTD partitions on "brcmnand.0": [2.048025] 0x-0x0002 : "boot" [2.062134] 0x0004-0x0112 : "rootfs" [2.077632] 0x07b0-0x07f0 : "data" [2.091363] 0x0002-0x03ac : "rootfs1_update" [2.106228] 0x0400-0x07ac : "rootfs2_update" [2.121093] 0x0402-0x0506 : "rootfs_other" The nvram contains the offset and size of the boot, rootfs1, rootfs2 and data partitions. The presence of CFE and nvram is verified by reading from the boot partition which is assumed to be at offset 0 and the process aborts if the nvram read indicates that this is not the case. There is bcm_tag information at the start of each rootfs that is used to determine which rootfs is newer and what its real offset/size is. The CFE bootline is used to select a rootfs. Signed-off-by: Simon Arlott --- v3: Use COMPILE_TEST. Ensure that strings read from flash are null terminated and validate bcm_tag integer values (this also moves reporting of rootfs sequence numbers to later on). v2: Use external struct bcm963xx_nvram definition for bcm963268part. Removed support for the nand partition number field, it's not a standard Broadcom field (was added by MitraStar Technology Corp.). drivers/mtd/Kconfig | 21 +++ drivers/mtd/Makefile| 1 + drivers/mtd/bcm963268part.c | 350 3 files changed, 372 insertions(+) create mode 100644 drivers/mtd/bcm963268part.c diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 42cc953..8209730 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -148,6 +148,27 @@ config MTD_BCM63XX_PARTS This provides partions parsing for BCM63xx devices with CFE bootloaders. +config MTD_BCM963268_PARTS + tristate "BCM963268 CFE partitioning support" + depends on BMIPS_GENERIC || COMPILE_TEST + select CRC32 + help + This provides partitions parsing for BCM963268 boards with CFE + bootloaders. The following partitions are defined: + "boot": CFE and nvram data + "rootfs": Currently selected rootfs + "data": Configuration data + "rootfs1_update": Container for the whole flash area used + for the first rootfs to allow it to be + updated. + "rootfs2_update": Container for the whole flash area used + for the second rootfs to allow it to be + updated. + "rootfs_other": The other (not currently selected) rootfs + + A decision is made regarding which of the two rootfs is to be + used based on the nvram data. + config MTD_BCM47XX_PARTS tristate "BCM47XX partitioning support" depends on BCM47XX || ARCH_BCM_5301X diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 99bb9a1..f0f4140 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS)+= afs.o obj-$(CONFIG_MTD_AR7_PARTS)+= ar7part.o obj-$(CONFIG_MTD_BC
[PATCH linux-next (v3) 2/3] MIPS: bcm63xx: nvram: Use nvram structure definition from header file
Use the common definition of the nvram structure from the header file include/uapi/linux/bcm963xx_nvram.h instead of maintaining a separate copy. Read the version 5 size of nvram data from memory and then support the version 4 and version 5 variants of nvram data checksums. Signed-off-by: Simon Arlott --- Compile tested only (there is no support for brcmnand on mach-bcm63xx). v3: No changes (reworded commit message). v2: Use external struct bcm963xx_nvram definition for bcm963268part. arch/mips/bcm63xx/nvram.c | 32 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 4b50d40..36e74f9 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -16,25 +16,9 @@ #include #include +#include #include -/* - * nvram structure - */ -struct bcm963xx_nvram { - u32 version; - u8 reserved1[256]; - u8 name[16]; - u32 main_tp_number; - u32 psi_size; - u32 mac_addr_count; - u8 mac_addr_base[ETH_ALEN]; - u8 reserved2[2]; - u32 checksum_old; - u8 reserved3[720]; - u32 checksum_high; -}; - #define BCM63XX_DEFAULT_PSI_SIZE 64 static struct bcm963xx_nvram nvram; @@ -47,17 +31,17 @@ void __init bcm63xx_nvram_init(void *addr) u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; /* extract nvram data */ - memcpy(&nvram, addr, sizeof(nvram)); + memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE); /* check checksum before using data */ if (nvram.version <= 4) { - check_len = offsetof(struct bcm963xx_nvram, reserved3); - expected_crc = nvram.checksum_old; - nvram.checksum_old = 0; + check_len = BCM963XX_NVRAM_V4_SIZE; + expected_crc = nvram.checksum_v4; + nvram.checksum_v4 = 0; } else { - check_len = sizeof(nvram); - expected_crc = nvram.checksum_high; - nvram.checksum_high = 0; + check_len = BCM963XX_NVRAM_V5_SIZE; + expected_crc = nvram.checksum_v5; + nvram.checksum_v5 = 0; } crc = crc32_le(~0, (u8 *)&nvram, check_len); -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v3) 1/3] MIPS: bcm963xx: Add Broadcom BCM963xx board nvram data structure
Broadcom BCM963xx boards have multiple nvram variants across different SoCs with additional checksum fields added whenever the size of the nvram was extended. Add this structure as a header file so that multiple drivers and userspace can use it. Signed-off-by: Simon Arlott --- v3: Fix includes/type names, add comments explaining the nvram struct. v2: Use external struct bcm963xx_nvram definition for bcm963268part. MAINTAINERS | 1 + include/uapi/linux/bcm963xx_nvram.h | 53 + 2 files changed, 54 insertions(+) create mode 100644 include/uapi/linux/bcm963xx_nvram.h diff --git a/MAINTAINERS b/MAINTAINERS index 6b6d4e2e..abf18b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2393,6 +2393,7 @@ F:drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: include/linux/bcm63xx_wdt.h +F: include/uapi/linux/bcm963xx_nvram.h BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan diff --git a/include/uapi/linux/bcm963xx_nvram.h b/include/uapi/linux/bcm963xx_nvram.h new file mode 100644 index 000..2dcb307 --- /dev/null +++ b/include/uapi/linux/bcm963xx_nvram.h @@ -0,0 +1,53 @@ +#ifndef _UAPI__LINUX_BCM963XX_NVRAM_H__ +#define _UAPI__LINUX_BCM963XX_NVRAM_H__ + +#include +#include + +/* + * Broadcom BCM963xx SoC board nvram data structure. + * + * The nvram structure varies in size depending on the SoC board version. Use + * the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information + * you need instead of sizeof(struct bcm963xx_nvram) as this may change. + * + * The "version" field value maps directly to the size and checksum names, e.g. + * version 4 uses "checksum_v4" and the data is BCM963XX_NVRAM_V4_SIZE bytes. + * + * Do not use the __reserved fields, especially not as an offset for CRC + * calculations (use BCM963XX_NVRAM_*_SIZE instead). These may be removed or + * repositioned. + */ + +#define BCM963XX_NVRAM_V4_SIZE 300 +#define BCM963XX_NVRAM_V5_SIZE 1024 +#define BCM963XX_NVRAM_V6_SIZE BCM963XX_NVRAM_V5_SIZE +#define BCM963XX_NVRAM_V7_SIZE 3072 + +#define BCM963XX_NVRAM_NR_PARTS5 + +struct bcm963xx_nvram { + __u32 version; + charbootline[256]; + charname[16]; + __u32 main_tp_number; + __u32 psi_size; + __u32 mac_addr_count; + __u8mac_addr_base[ETH_ALEN]; + __u8__reserved1[2]; + __u32 checksum_v4; + + __u8__reserved2[292]; + __u32 nand_part_offset[BCM963XX_NVRAM_NR_PARTS]; + __u32 nand_part_size[BCM963XX_NVRAM_NR_PARTS]; + __u8__reserved3[388]; + union { + __u32 checksum_v5; + __u32 checksum_v6; + }; + + __u8__reserved4[2044]; + __u32 checksum_v7; +} __packed; + +#endif /* _UAPI__LINUX_BCM963XX_NVRAM_H__ */ -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH linux-next 1/2] power: Add brcm,bcm6358-power-controller device tree binding
On 11/12/15 02:58, Rob Herring wrote: > On Wed, Dec 09, 2015 at 10:29:35PM +0000, Simon Arlott wrote: >> The BCM6358 contains power domains controlled with a register. Power >> domains are indexed by bits in the register. Power domain bits can be >> interleaved with other status bits and clocks in the same register. >> >> Newer SoCs with dedicated power domain registers are active low. >> >> Signed-off-by: Simon Arlott >> --- >> .../power/brcm,bcm6358-power-controller.txt| 53 >> ++ >> 1 file changed, 53 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt >> >> diff --git >> a/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt >> b/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt >> new file mode 100644 >> index 000..556c323 >> --- /dev/null >> +++ >> b/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt >> @@ -0,0 +1,53 @@ >> +Broadcom BCM6358 Power domain controller >> + >> +This binding uses the power domain bindings: >> +Documentation/devicetree/bindings/power/power_domain.txt >> + >> +The BCM6358 contains power domains controlled with a register. Power >> +domains are indexed by bits in the register. Power domain bits can be >> +interleaved with other status bits and clocks in the same register. >> + >> +Newer SoCs with dedicated power domain registers are active low. >> + >> +Required properties: >> +- compatible: Should be "brcm,bcm-power-controller", >> "brcm,bcm6358-power-controller" >> +- #power-domain-cells: Should be <1>. >> +- regmap: The register map phandle >> +- offset: Offset in the register map for the power domain >> register (in bytes) >> +- power-domain-indices: The bits in the register used for power domains. > > You should drop this and make the cell values be the register offsets. I need to register every power domain in order to get the kernel to turn off those that are unused. Even if I could enumerate all device tree devices that reference the power-controller node, not all of them have bindings to allow them to be specified in the device tree file. I can't register all 32 bits because that won't work on the BCM6358 that only has 1 power domain bit in the register and several clock bits. On the BCM63268 there are power domain bits that have no device that I don't want the kernel to disable (like the memory controller). How should I determine which bits to register a power domain for? misc_iddq_ctrl: power-controller@1000184c { compatible = "brcm,bcm6358-power-controller"; regmap = <&misc>; offset = <0x4c>; mask = <0x1043fff>; #power-domain-cells = <1>; }; or misc_iddq_ctrl: power-controller@1000184c { compatible = "brcm,bcm6358-power-controller"; regmap = <&misc>; offset = <0x4c>; #address-cells = <1>; #size-cells = <0>; sar: power-controller@0 { reg = <0>; #power-domain-cells = <0>; }; ipsec: power-controller@1 { reg = <1>; #power-domain-cells = <0>; }; ... }; or something else? >> +- power-domain-names: Should be a list of strings of power domain names >> +indexed by the power domain indices. > > This isn't really needed anyway. If I remove this then I'll have to use the same node name for each struct generic_pm_domain "name" field that I register, although these names don't appear to be exported anywhere. >> + >> +Optional properties: >> +- active-low: Specify that the bits are active low. > > This should be implied by the compatible property. Ok, I'll create "brcm,bcm6358-power-controller" that's active high and "brcm,bcm6328-power-controller" that's active low. This appear to be the earliest chips that introduced or changed "iddq" register bits. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v2) 3/3] mtd: part: Add BCM962368 CFE partitioning support
Add partitioning support for BCM963268 boards with CFE bootloaders. The following partitions are defined: "boot": CFE and nvram data "rootfs": Currently selected rootfs "data": Configuration data "rootfs1_update": Container for the whole flash area used for the first rootfs to allow it to be updated. "rootfs2_update": Container for the whole flash area used for the second rootfs to allow it to be updated. "rootfs_other": The other (not currently selected) rootfs Example: [1.904302] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1 [1.911000] nand: Macronix NAND 128MiB 3,3V 8-bit [1.915855] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [1.923797] bcm6368_nand 1200.nand: detected 128MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, Hamming ECC [1.936994] Bad block table found at page 65472, version 0x01 [1.944121] Bad block table found at page 65408, version 0x01 [1.951166] nand_read_bbt: bad block at 0x0748 [1.990043] bcm963268part: rootfs1: CFE boot tag found at 0x2 with version 6, board type 963168VX and sequence number 2 [2.003060] bcm963268part: rootfs2: CFE boot tag found at 0x400 with version 6, board type 963168VX and sequence number 1 [2.015159] bcm963268part: CFE bootline selected latest image rootfs1 [2.022080] 6 bcm963268part partitions found on MTD device brcmnand.0 [2.042659] Creating 6 MTD partitions on "brcmnand.0": [2.048025] 0x-0x0002 : "boot" [2.062134] 0x0004-0x0112 : "rootfs" [2.077632] 0x07b0-0x07f0 : "data" [2.091363] 0x0002-0x03ac : "rootfs1_update" [2.106228] 0x0400-0x07ac : "rootfs2_update" [2.121093] 0x0402-0x0506 : "rootfs_other" The nvram contains the offset and size of the boot, rootfs1, rootfs2 and data partitions. The presence of CFE and nvram is verified by reading from the boot partition which is assumed to be at offset 0 and the process aborts if the nvram read indicates that this is not the case. There is bcm_tag information at the start of each rootfs that is used to determine which rootfs is newer and what its real offset/size is. The CFE bootline is used to select a rootfs. Signed-off-by: Simon Arlott --- v2: Use external struct bcm963xx_nvram definition for bcm963268part. Removed support for the nand partition number field, it's not a standard Broadcom field (was added by MitraStar Technology Corp.). drivers/mtd/Kconfig | 21 +++ drivers/mtd/Makefile| 1 + drivers/mtd/bcm963268part.c | 326 3 files changed, 348 insertions(+) create mode 100644 drivers/mtd/bcm963268part.c diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 42cc953..63cb2db 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -148,6 +148,27 @@ config MTD_BCM63XX_PARTS This provides partions parsing for BCM63xx devices with CFE bootloaders. +config MTD_BCM963268_PARTS + tristate "BCM963268 CFE partitioning support" + depends on BMIPS_GENERIC + select CRC32 + help + This provides partitions parsing for BCM963268 boards with CFE + bootloaders. The following partitions are defined: + "boot": CFE and nvram data + "rootfs": Currently selected rootfs + "data": Configuration data + "rootfs1_update": Container for the whole flash area used + for the first rootfs to allow it to be + updated. + "rootfs2_update": Container for the whole flash area used + for the second rootfs to allow it to be + updated. + "rootfs_other": The other (not currently selected) rootfs + + A decision is made regarding which of the two rootfs is to be + used based on the nvram data. + config MTD_BCM47XX_PARTS tristate "BCM47XX partitioning support" depends on BCM47XX || ARCH_BCM_5301X diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 99bb9a1..f0f4140 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS)+= afs.o obj-$(CONFIG_MTD_AR7_PARTS)+= ar7part.o obj-$(CONFIG_MTD_BCM63XX_PARTS)+= bcm63xxpart.o +obj-$(CONFIG_MTD_BCM963268_PARTS) += bcm963268part.o obj-$(CONFIG_MTD_BCM47XX_PARTS)+= bcm47xxpart.o # 'Users' - code which presents funct
[PATCH linux-next (v2) 2/3] MIPS: bcm63xx: Use common nvram structure definition
Use an external common definition of the nvram structure. Signed-off-by: Simon Arlott --- Compile tested only (there is no support for brcmnand on mach-bcm63xx). v2: Use external struct bcm963xx_nvram definition for bcm963268part. arch/mips/bcm63xx/nvram.c | 32 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 4b50d40..36e74f9 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -16,25 +16,9 @@ #include #include +#include #include -/* - * nvram structure - */ -struct bcm963xx_nvram { - u32 version; - u8 reserved1[256]; - u8 name[16]; - u32 main_tp_number; - u32 psi_size; - u32 mac_addr_count; - u8 mac_addr_base[ETH_ALEN]; - u8 reserved2[2]; - u32 checksum_old; - u8 reserved3[720]; - u32 checksum_high; -}; - #define BCM63XX_DEFAULT_PSI_SIZE 64 static struct bcm963xx_nvram nvram; @@ -47,17 +31,17 @@ void __init bcm63xx_nvram_init(void *addr) u8 hcs_mac_addr[ETH_ALEN] = { 0x00, 0x10, 0x18, 0xff, 0xff, 0xff }; /* extract nvram data */ - memcpy(&nvram, addr, sizeof(nvram)); + memcpy(&nvram, addr, BCM963XX_NVRAM_V5_SIZE); /* check checksum before using data */ if (nvram.version <= 4) { - check_len = offsetof(struct bcm963xx_nvram, reserved3); - expected_crc = nvram.checksum_old; - nvram.checksum_old = 0; + check_len = BCM963XX_NVRAM_V4_SIZE; + expected_crc = nvram.checksum_v4; + nvram.checksum_v4 = 0; } else { - check_len = sizeof(nvram); - expected_crc = nvram.checksum_high; - nvram.checksum_high = 0; + check_len = BCM963XX_NVRAM_V5_SIZE; + expected_crc = nvram.checksum_v5; + nvram.checksum_v5 = 0; } crc = crc32_le(~0, (u8 *)&nvram, check_len); -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v2) 1/3] MIPS: bcm963xx: Add nvram structure
The BCM963xx has multiple nvram variants across different SoCs with additional checksum fields added whenever the size of the nvram was extended. Signed-off-by: Simon Arlott --- v2: Use external struct bcm963xx_nvram definition for bcm963268part. MAINTAINERS | 1 + include/uapi/linux/bcm963xx_nvram.h | 39 + 2 files changed, 40 insertions(+) create mode 100644 include/uapi/linux/bcm963xx_nvram.h diff --git a/MAINTAINERS b/MAINTAINERS index 1354720..5d2272c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2396,6 +2396,7 @@ F:drivers/irqchip/irq-brcmstb* F: drivers/power/bcm6358* F: drivers/reset/bcm/reset-bcm6345* F: include/linux/bcm63xx_wdt.h +F: include/uapi/linux/bcm963xx_nvram.h BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan diff --git a/include/uapi/linux/bcm963xx_nvram.h b/include/uapi/linux/bcm963xx_nvram.h new file mode 100644 index 000..470a4b9 --- /dev/null +++ b/include/uapi/linux/bcm963xx_nvram.h @@ -0,0 +1,39 @@ +#ifndef _UAPI__LINUX_BCM963XX_NVRAM_H__ +#define _UAPI__LINUX_BCM963XX_NVRAM_H__ + +#include +#include +#include + +#define BCM963XX_NVRAM_V4_SIZE 300 +#define BCM963XX_NVRAM_V5_SIZE (1 * SZ_1K) +#define BCM963XX_NVRAM_V6_SIZE BCM963XX_NVRAM_V5_SIZE +#define BCM963XX_NVRAM_V7_SIZE (3 * SZ_1K) + +#define BCM963XX_NVRAM_NR_PARTS5 + +struct bcm963xx_nvram { + u32 version; + charbootline[256]; + charname[16]; + u32 main_tp_number; + u32 psi_size; + u32 mac_addr_count; + u8 mac_addr_base[ETH_ALEN]; + u8 __reserved1[2]; + u32 checksum_v4; + + u8 __reserved2[292]; + u32 nand_part_offset[BCM963XX_NVRAM_NR_PARTS]; + u32 nand_part_size[BCM963XX_NVRAM_NR_PARTS]; + u8 __reserved3[388]; + union { + u32 checksum_v5; + u32 checksum_v6; + }; + + u8 __reserved4[2044]; + u32 checksum_v7; +} __packed; + +#endif /* _UAPI__LINUX_BCM963XX_NVRAM_H__ */ -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v2) 2/2] clk: bcm6345: Add BCM6345 gated clock support
The BCM6345 contains clocks gated with a register. Clocks are indexed by bits in the register and are active high. Most MIPS-based BCM63xx SoCs have a clock gating set of registers, but some have clock gate bits interleaved with other status bits and configurable clocks in the same register. Enabled by default for BMIPS_GENERIC. Signed-off-by: Simon Arlott --- v2: Resend, no changes. v1: Renamed from BCM63xx to BCM6345. MAINTAINERS | 1 + drivers/clk/bcm/Kconfig | 9 ++ drivers/clk/bcm/Makefile | 1 + drivers/clk/bcm/clk-bcm6345.c | 191 ++ 4 files changed, 202 insertions(+) create mode 100644 drivers/clk/bcm/clk-bcm6345.c diff --git a/MAINTAINERS b/MAINTAINERS index 5ac17b0..9b54ddc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2389,6 +2389,7 @@ F:arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/clk/bcm/clk-bcm6345* F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index f287845..043353a 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig @@ -8,6 +8,15 @@ config CLK_BCM_63XX Enable common clock framework support for Broadcom BCM63xx DSL SoCs based on the ARM architecture +config CLK_BCM_6345 + bool "Broadcom BCM6345 clock support" + depends on BMIPS_GENERIC || COMPILE_TEST + depends on COMMON_CLK + default BMIPS_GENERIC + help + Enable common clock framework support for Broadcom BCM6345 DSL SoCs + based on the MIPS architecture + config CLK_BCM_KONA bool "Broadcom Kona CCU clock support" depends on ARCH_BCM_MOBILE || COMPILE_TEST diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 247c267..e2bac43 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o +obj-$(CONFIG_CLK_BCM_6345) += clk-bcm6345.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o diff --git a/drivers/clk/bcm/clk-bcm6345.c b/drivers/clk/bcm/clk-bcm6345.c new file mode 100644 index 000..88a1e7e --- /dev/null +++ b/drivers/clk/bcm/clk-bcm6345.c @@ -0,0 +1,191 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from clk-gate.c: + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: Basic clock which uses a bit in a regmap to gate and ungate the output + * + * Traits of this clock: + * prepare - clk_(un)prepare only ensures parent is (un)prepared + * enable - clk_enable and clk_disable are functional & control gating + * rate - inherits rate from parent. No clk_set_rate support + * parent - fixed parent. No clk_set_parent support + */ + +struct clk_bcm6345 { + struct clk_hw hw; + struct regmap *map; + u32 offset; + u32 mask; +}; + +#define to_clk_bcm6345(_hw) container_of(_hw, struct clk_bcm6345, hw) + +static int clk_bcm6345_enable(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + + return regmap_write_bits(gate->map, gate->offset, + gate->mask, gate->mask); +} + +static void clk_bcm6345_disable(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + + regmap_write_bits(gate->map, gate->offset, + gate->mask, 0); +} + +static int clk_bcm6345_is_enabled(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + unsigned int val; + int ret; + + ret = regmap_read(gate->map, gate->offset, &val); + if (ret) + return ret; + + val &= gate->mask; + + return val ? 1 : 0; +} + +const struct clk_ops clk_bcm6345_ops = { + .enable = clk_bcm6345_enable, + .disable = clk_bcm6345_disable, + .is_enabled = clk_bcm6345_is_enabled, +}; + +static struct clk * __init of_bcm6345_clk_register(const char *parent_name, + const char *clk_name, struct regm
[PATCH linux-next (v2) 1/2] clk: Add brcm,bcm6345-gate-clk device tree binding
Add device tree binding for the BCM6345's gated clocks. The BCM6345 contains clocks gated with a register. Clocks are indexed by bits in the register and are active high. Most MIPS-based BCM63xx SoCs have a clock gating set of registers, but some have clock gate bits interleaved with other status bits and configurable clocks in the same register. Signed-off-by: Simon Arlott --- v2: Added clock-indices, clock-output-names (from clock-bindings.txt), these are required properties. v1: Renamed from BCM63xx to BCM6345. .../bindings/clock/brcm,bcm6345-gate-clk.txt | 62 ++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt b/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt new file mode 100644 index 000..a6e264c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt @@ -0,0 +1,62 @@ +Broadcom BCM6345 clocks + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +The BCM6345 contains clocks gated with a register. Clocks are indexed +by bits in the register and are active high. Most MIPS-based BCM63xx +SoCs have a clock gating set of registers, but some have clock gate bits +interleaved with other status bits and configurable clocks in the same +register. + +Required properties: +- compatible: Should be "brcm,bcm-gate-clk", "brcm,bcm6345-gate-clk" +- #clock-cells: Should be <1>. +- regmap: The register map phandle +- offset: Offset in the register map for the clock register (in bytes) +- clocks: The external oscillator clock phandle +- clock-indices: The bits in the register used for gated clocks. +- clock-output-names: Should be a list of strings of clock output signal + names indexed by the clock indices. + +Example: + +periph_clk: periph_clk { + compatible = "brcm,bcm63168-gate-clk", "brcm,bcm6345-gate-clk"; + regmap = <&periph_cntl>; + offset = <0x4>; + + #clock-cells = <1>; + clock-indices = + <1>, <2>,<3>, <4>, <5>, + <6>, <7>,<8>, <9>, <10>, + <11>, <12>, <13>, <14>,<15>, + <16>, <17>, <18>, <19>,<20>, + <27>, <31>; + clock-output-names = + "vdsl_qproc", "vdsl_afe", "vdsl","mips", "wlan_ocp", + "dect", "fap0", "fap1","sar", "robosw", + "pcm","usbd", "usbh","ipsec", "spi", + "hsspi", "pcie", "phymips", "gmac", "nand", + "tbus", "robosw250"; +}; + +timer_clk: timer_clk { + compatible = "brcm,bcm63168-gate-clk", "brcm,bcm6345-gate-clk"; + regmap = <&timer_cntl>; + offset = <0x4>; + + #clock-cells = <1>; + clock-indices = <17>, <18>; + clock-output-names = "uto_extin", "usb_ref"; +}; + +ehci0: usb@10002500 { + compatible = "brcm,bcm63168-ehci", "brcm,bcm6345-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + interrupt-parent = <&periph_intc>; + interrupts = <10>; + clocks = <&periph_clk 13>, <&timer_clk 18>; + phys = <&usbh>; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next (v3) 2/2] reset: bcm6345: Add support for the BCM6345 soft-reset controller
The BCM6345 contains a soft-reset controller activated by setting a bit (that must previously have been cleared). Signed-off-by: Simon Arlott --- v3: Resend based on linux-next, no changes. v2: Renamed to bcm6345, removed "mask" property (and the regmap register size is always assumed to be 32 bits). Moved from drivers/reset/ to drivers/reset/bcm/. MAINTAINERS | 1 + drivers/reset/Kconfig | 1 + drivers/reset/Makefile| 17 +++--- drivers/reset/bcm/Kconfig | 10 drivers/reset/bcm/Makefile| 1 + drivers/reset/bcm/reset-bcm6345.c | 109 ++ 6 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 drivers/reset/bcm/Kconfig create mode 100644 drivers/reset/bcm/Makefile create mode 100644 drivers/reset/bcm/reset-bcm6345.c diff --git a/MAINTAINERS b/MAINTAINERS index 9b54ddc..b81b238 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2393,6 +2393,7 @@ F:drivers/clk/bcm/clk-bcm6345* F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* +F: drivers/reset/bcm/reset-bcm6345* F: include/linux/bcm63xx_wdt.h BROADCOM TG3 GIGABIT ETHERNET DRIVER diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0615f50..ee73f5f 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -12,4 +12,5 @@ menuconfig RESET_CONTROLLER If unsure, say no. +source "drivers/reset/bcm/Kconfig" source "drivers/reset/sti/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 85d5904..a34f469 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -1,8 +1,9 @@ -obj-$(CONFIG_RESET_CONTROLLER) += core.o -obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o -obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o -obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o -obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o -obj-$(CONFIG_ARCH_STI) += sti/ -obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o -obj-$(CONFIG_ATH79) += reset-ath79.o +obj-$(CONFIG_RESET_CONTROLLER) += core.o +obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o +obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_STI) += sti/ +obj-$(CONFIG_ARCH_ZYNQ)+= reset-zynq.o +obj-$(CONFIG_ATH79)+= reset-ath79.o +obj-y += bcm/ diff --git a/drivers/reset/bcm/Kconfig b/drivers/reset/bcm/Kconfig new file mode 100644 index 000..85931c9 --- /dev/null +++ b/drivers/reset/bcm/Kconfig @@ -0,0 +1,10 @@ +if RESET_CONTROLLER + +config RESET_BCM6345 + bool "BCM6345 Reset Controller" + depends on BMIPS_GENERIC + default BMIPS_GENERIC + help + Support resetting of devices on BCM6345 boards. + +endif diff --git a/drivers/reset/bcm/Makefile b/drivers/reset/bcm/Makefile new file mode 100644 index 000..3d004bd --- /dev/null +++ b/drivers/reset/bcm/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_RESET_BCM6345)+= reset-bcm6345.o diff --git a/drivers/reset/bcm/reset-bcm6345.c b/drivers/reset/bcm/reset-bcm6345.c new file mode 100644 index 000..a95433d --- /dev/null +++ b/drivers/reset/bcm/reset-bcm6345.c @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Simon Arlott + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * Derived from reset-berlin.c: + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * Sebastian Hesselbarth + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_bcm6345_reset_priv(p) \ + container_of((p), struct bcm6345_reset_priv, rcdev) + +struct bcm6345_reset_priv { + struct regmap *map; + u32 offset; + struct reset_controller_dev rcdev; + struct mutex mutex; +}; + +static int bcm6345_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct bcm6345_reset_priv *priv = to_bcm6345_reset_priv(rcdev); + + mutex_lock(&priv->mutex); + regmap_write_bits(priv->map, priv->offset, BIT(id), 0); + usleep_range(1, 2); + regmap_write_bits(priv->map, priv->offset, BIT(id), BIT(id)); + usleep_range(1, 2); + mutex_unlock(&priv->mutex); + + return 0; +} + +static struct reset_control_ops bcm6345_reset_ops = { + .reset = bcm6345_reset_reset, +}; + +static int __init bcm6345_reset_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct bcm6345_reset_priv *priv; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL)
[PATCH linux-next (v3) 1/2] reset: Add brcm,bcm6345-reset device tree binding
Add device tree binding for the BCM6345 soft reset controller. The BCM6345 contains a soft-reset controller activated by setting a bit (that must previously have been cleared). Signed-off-by: Simon Arlott --- v3: Resend. Example has changed because usbh now has two compatible strings and uses a power domain instead of a regulator. v2: Renamed to bcm6345, removed "mask" property. Acked-by: Rob Herring .../bindings/reset/brcm,bcm6345-reset.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt b/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt new file mode 100644 index 000..0313040 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt @@ -0,0 +1,33 @@ +Broadcom BCM6345 reset controller + +The BCM6345 contains a basic soft reset controller in the perf register +set which resets components using a bit in a register. + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "brcm,bcm-reset", "brcm,bcm6345-reset" +- regmap: The register map phandle +- offset: Offset in the register map for the reset register (in bytes) +- #reset-cells:Must be set to 1 + +Example: + +periph_soft_rst: reset-controller { + compatible = "brcm,bcm63168-reset", "brcm,bcm6345-reset"; + regmap = <&periph_cntl>; + offset = <0x10>; + + #reset-cells = <1>; +}; + +usbh: usbphy@10002700 { + compatible = "brcm,bcm63168-usbh", "brcm,bcm6328-usbh"; + reg = <0x10002700 0x38>; + clocks = <&periph_clk 13>, <&timer_clk 18>; + resets = <&periph_soft_rst 6>; + power-domains = <&misc_iddq_ctrl 4>; + #phy-cells = <0>; +}; + -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH linux-next] mtd: part: Add BCM962368 CFE partitioning support
On 10/12/15 17:41, Florian Fainelli wrote: > Le 09/12/2015 13:55, Simon Arlott a écrit : >> drivers/mtd/Kconfig | 21 +++ >> drivers/mtd/Makefile| 1 + >> drivers/mtd/bcm963268part.c | 373 >> >> 3 files changed, 395 insertions(+) >> create mode 100644 drivers/mtd/bcm963268part.c > > What motivated created a separate partition parser rather then using the > extended the existing one? I started off doing that but had to split it up because how it handles the nvram and bcm_tag to construct the partition layout is significantly different. The nvram isn't even read from flash in bcm63xxpart, and the psi size value isn't used by bcm963268. > I would imagine that, at some point, the partition parser could know > what kind of flash it needs to parse: SPI/P-NOR or NAND, and based on > that, do an appropriate definition? With the device tree changes Brian's introducing it can be specified in there, otherwise a common parser would need to read from the miscStrapBus register which would be difficult for a partition parser as it's not a device and has no memory resources. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next 2/2] power: bcm6358-power: Add BCM6358 power domain controller support
The BCM6358 contains power domains controlled with a register. Power domains are indexed by bits in the register. Power domain bits can be interleaved with other status bits and clocks in the same register. Newer SoCs with dedicated power domain registers are active low. Signed-off-by: Simon Arlott --- MAINTAINERS | 1 + drivers/power/Kconfig | 11 +++ drivers/power/Makefile| 1 + drivers/power/bcm6358-power.c | 198 ++ 4 files changed, 211 insertions(+) create mode 100644 drivers/power/bcm6358-power.c diff --git a/MAINTAINERS b/MAINTAINERS index 0370aba..5546a53 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2391,6 +2391,7 @@ F:drivers/clk/bcm/clk-bcm6345* F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* +F: drivers/power/bcm6358* F: drivers/reset/bcm/reset-bcm6345* F: include/linux/bcm63xx_wdt.h diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 1ddd13c..3d6f842 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -506,3 +506,14 @@ endif # POWER_SUPPLY source "drivers/power/reset/Kconfig" source "drivers/power/avs/Kconfig" + +config BCM6358_POWER + bool "BCM6358 power domain support" + depends on BMIPS_GENERIC && PM && OF + select PM_GENERIC_DOMAINS + select PM_GENERIC_DOMAINS_OF + default BMIPS_GENERIC + help + Say Y here to enable support for power domains on the BCM6358. + Required to ensure that power is enabled for SoC peripheral + devices, and that power is disabled to unused devices. diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 0e4eab5..0b72dd2 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o obj-$(CONFIG_PDA_POWER)+= pda_power.o obj-$(CONFIG_APM_POWER)+= apm_power.o obj-$(CONFIG_AXP20X_POWER) += axp20x_usb_power.o +obj-$(CONFIG_BCM6358_POWER)+= bcm6358-power.o obj-$(CONFIG_MAX8925_POWER)+= max8925_power.o obj-$(CONFIG_WM831X_BACKUP)+= wm831x_backup.o obj-$(CONFIG_WM831X_POWER) += wm831x_power.o diff --git a/drivers/power/bcm6358-power.c b/drivers/power/bcm6358-power.c new file mode 100644 index 000..f4654d7 --- /dev/null +++ b/drivers/power/bcm6358-power.c @@ -0,0 +1,198 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BITS 32 + +struct bcm6358_power; + +struct bcm6358_power_dev { + struct generic_pm_domain genpd; + struct bcm6358_power *power; + u32 bit; +}; + +struct bcm6358_power { + struct regmap *map; + u32 offset; + bool active_low; + + struct bcm6358_power_dev dev[BITS]; + struct genpd_onecell_data genpd_data; + struct generic_pm_domain *genpd[BITS]; +}; + +static int bcm6358_power_get_state(struct bcm6358_power_dev *pmd, + bool *is_on) +{ + struct bcm6358_power *power = pmd->power; + unsigned int val; + int ret; + + ret = regmap_read(power->map, power->offset, &val); + if (ret) { + *is_on = false; + return ret; + } + + if (power->active_low) + *is_on = !(val & pmd->bit); + else + *is_on = (val & pmd->bit); + return 0; +} + +static int bcm6358_power_set_state(struct bcm6358_power_dev *pmd, + bool on) +{ + struct bcm6358_power *power = pmd->power; + u32 val; + + if (power->active_low) + val = on ? 0 : pmd->bit; + else + val = on ? pmd->bit : 0; + + return regmap_update_bits(power->map, power->offset, pmd->bit, val); +} + +static int bcm6358_power_power_on(struct generic_pm_domain *genpd) +{ + struct bcm6358_power_dev *pmd = container_of(genpd, + struct bcm6358_power_dev, genpd); + + return bcm6358_power_set_state(pmd, true); +} + +static int bcm6358_power_power_off(struct generic_pm_domain *genpd) +{ + struct bcm6358_power_dev *pmd = container_of(genpd, + struct bcm6358_power_dev, genpd); + + return bcm6358_power_set_state(pmd, false); +} + +static int __init bcm6358_power_probe(struct platfo
[PATCH linux-next 1/2] power: Add brcm,bcm6358-power-controller device tree binding
The BCM6358 contains power domains controlled with a register. Power domains are indexed by bits in the register. Power domain bits can be interleaved with other status bits and clocks in the same register. Newer SoCs with dedicated power domain registers are active low. Signed-off-by: Simon Arlott --- .../power/brcm,bcm6358-power-controller.txt| 53 ++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt diff --git a/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt b/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt new file mode 100644 index 000..556c323 --- /dev/null +++ b/Documentation/devicetree/bindings/power/brcm,bcm6358-power-controller.txt @@ -0,0 +1,53 @@ +Broadcom BCM6358 Power domain controller + +This binding uses the power domain bindings: +Documentation/devicetree/bindings/power/power_domain.txt + +The BCM6358 contains power domains controlled with a register. Power +domains are indexed by bits in the register. Power domain bits can be +interleaved with other status bits and clocks in the same register. + +Newer SoCs with dedicated power domain registers are active low. + +Required properties: +- compatible: Should be "brcm,bcm-power-controller", "brcm,bcm6358-power-controller" +- #power-domain-cells: Should be <1>. +- regmap: The register map phandle +- offset: Offset in the register map for the power domain register (in bytes) +- power-domain-indices: The bits in the register used for power domains. +- power-domain-names: Should be a list of strings of power domain names +indexed by the power domain indices. + +Optional properties: +- active-low: Specify that the bits are active low. + +Example: + +misc_iddq_ctrl: power-controller { + compatible = "brcm,bcm63168-power-controller", "brcm,bcm6358-power-controller"; + regmap = <&misc>; + offset = <0x4c>; + + #power-domain-cells = <1>; + power-domain-indices = + <0>, <1>, <2>,<3>, <4>, + <5>, <6>, <7>,<8>, <9>, + <10>,<11>, <12>, <13>,<17>, + <18>; + power-domain-names = + "sar", "ipsec", "mips", "dect", "usbh", + "usbd", "robosw", "pcm", "periph","vdsl_phy", + "vdsl_mips", "fap","pcie", "wlan_pads", "gphy", + "gmac"; + active-low; +}; + +periph_iddq: power-controller { + compatible = "brcm,bcm6368-power-controller", "brcm,bcm6358-power-controller"; + regmap = <&periph_cntl>; + offset = <0x4>; + + #power-domain-cells = <1>; + power-domain-indices = <19>; + power-domain-names = "usbh"; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next] mtd: part: Add BCM962368 CFE partitioning support
Add partitioning support for BCM963268 boards with CFE bootloaders. The following partitions are defined: "boot": CFE and nvram data "rootfs": Currently selected rootfs "data": Configuration data "rootfs1_update": Container for the whole flash area used for the first rootfs to allow it to be updated. "rootfs2_update": Container for the whole flash area used for the second rootfs to allow it to be updated. "rootfs_other": The other (not currently selected) rootfs Example: [1.904302] nand: device found, Manufacturer ID: 0xc2, Chip ID: 0xf1 [1.911000] nand: Macronix NAND 128MiB 3,3V 8-bit [1.915855] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64 [1.923797] bcm6368_nand 1200.nand: detected 128MiB total, 128KiB blocks, 2KiB pages, 16B OOB, 8-bit, Hamming ECC [1.936994] Bad block table found at page 65472, version 0x01 [1.944121] Bad block table found at page 65408, version 0x01 [1.951166] nand_read_bbt: bad block at 0x0748 [1.990043] bcm963268part: rootfs1: CFE boot tag found at 0x2 with version 6, board type 963168VX and sequence number 2 [2.003060] bcm963268part: rootfs2: CFE boot tag found at 0x400 with version 6, board type 963168VX and sequence number 1 [2.015159] bcm963268part: CFE bootline selected latest image rootfs1 [2.022080] 6 bcm963268part partitions found on MTD device brcmnand.0 [2.042659] Creating 6 MTD partitions on "brcmnand.0": [2.048025] 0x-0x0002 : "boot" [2.062134] 0x0004-0x0112 : "rootfs" [2.077632] 0x07b0-0x07f0 : "data" [2.091363] 0x0002-0x03ac : "rootfs1_update" [2.106228] 0x0400-0x07ac : "rootfs2_update" [2.121093] 0x0402-0x0506 : "rootfs_other" The nvram contains the offset and size of the boot, rootfs1, rootfs2 and data partitions. The presence of CFE and nvram is verified by reading from the boot partition which is assumed to be at offset 0 and the process aborts if the nvram read indicates that this is not the case. There is bcm_tag information at the start of each rootfs that is used to determine which rootfs is newer and what its real offset/size is. The CFE bootline or nvram partition number is used to select a rootfs. Signed-off-by: Simon Arlott --- I'm aware that this is not compatible with the mtd partition/device tree reorganisation patches and will rework the patch when this is committed. Should I try to put the "struct bcm963268_nvram" in a common header file for all 63xx SoCs? It's hard to know if there is only one purpose for each byte in the nvram across all SoCs or whether it would be a complex type involving unions for different SoCs. The partitioning needs to match what exists already for this board so that it's practical to swap between an flash image released by the manufacturer/distributor of the hardware, and a custom image based on the latest vanilla kernel. drivers/mtd/Kconfig | 21 +++ drivers/mtd/Makefile| 1 + drivers/mtd/bcm963268part.c | 373 3 files changed, 395 insertions(+) create mode 100644 drivers/mtd/bcm963268part.c diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 42cc953..63cb2db 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -148,6 +148,27 @@ config MTD_BCM63XX_PARTS This provides partions parsing for BCM63xx devices with CFE bootloaders. +config MTD_BCM963268_PARTS + tristate "BCM963268 CFE partitioning support" + depends on BMIPS_GENERIC + select CRC32 + help + This provides partitions parsing for BCM963268 boards with CFE + bootloaders. The following partitions are defined: + "boot": CFE and nvram data + "rootfs": Currently selected rootfs + "data": Configuration data + "rootfs1_update": Container for the whole flash area used + for the first rootfs to allow it to be + updated. + "rootfs2_update": Container for the whole flash area used + for the second rootfs to allow it to be + updated. + "rootfs_other": The other (not currently selected) rootfs + + A decision is made regarding which of the two rootfs is to be + used based on the nvram data. + config MTD_BCM47XX_PARTS tristate "BCM47XX partitioning support" depends on BCM47XX || ARCH_BCM_5301X diff --git a/drive
[PATCH linux-next (v2) 2/3] mtd: brcmnand: Request and enable the clock if present
Attempt to enable a clock named "nand" as some SoCs have a clock for the controller that needs to be enabled. Signed-off-by: Simon Arlott --- Resend, no changes. drivers/mtd/nand/brcmnand/brcmnand.c | 64 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 190a99a..dca8162 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -122,6 +123,9 @@ struct brcmnand_controller { /* Some SoCs provide custom interrupt status register(s) */ struct brcmnand_soc *soc; + /* Some SoCs have a gateable clock for the controller */ + struct clk *clk; + int cmd_pending; booldma_pending; struct completion done; @@ -2127,10 +2131,24 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (IS_ERR(ctrl->nand_base)) return PTR_ERR(ctrl->nand_base); + /* Enable clock before using NAND registers */ + ctrl->clk = devm_clk_get(dev, "nand"); + if (!IS_ERR(ctrl->clk)) { + ret = clk_prepare_enable(ctrl->clk); + if (ret) + return ret; + } else { + ret = PTR_ERR(ctrl->clk); + if (ret == -EPROBE_DEFER) + return ret; + + ctrl->clk = NULL; + } + /* Initialize NAND revision */ ret = brcmnand_revision_init(ctrl); if (ret) - return ret; + goto err; /* * Most chips have this cache at a fixed offset within 'nand' block. @@ -2139,8 +2157,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); if (res) { ctrl->nand_fc = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->nand_fc)) - return PTR_ERR(ctrl->nand_fc); + if (IS_ERR(ctrl->nand_fc)) { + ret = PTR_ERR(ctrl->nand_fc); + goto err; + } } else { ctrl->nand_fc = ctrl->nand_base + ctrl->reg_offsets[BRCMNAND_FC_BASE]; @@ -2150,8 +2170,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); if (res) { ctrl->flash_dma_base = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->flash_dma_base)) - return PTR_ERR(ctrl->flash_dma_base); + if (IS_ERR(ctrl->flash_dma_base)) { + ret = PTR_ERR(ctrl->flash_dma_base); + goto err; + } flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); @@ -2160,13 +2182,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->dma_desc = dmam_alloc_coherent(dev, sizeof(*ctrl->dma_desc), &ctrl->dma_pa, GFP_KERNEL); - if (!ctrl->dma_desc) - return -ENOMEM; + if (!ctrl->dma_desc) { + ret = -ENOMEM; + goto err; + } ctrl->dma_irq = platform_get_irq(pdev, 1); if ((int)ctrl->dma_irq < 0) { dev_err(dev, "missing FLASH_DMA IRQ\n"); - return -ENODEV; + ret = -ENODEV; + goto err; } ret = devm_request_irq(dev, ctrl->dma_irq, @@ -2175,7 +2200,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) { dev_err(dev, "can't allocate IRQ %d: error %d\n", ctrl->dma_irq, ret); - return ret; + goto err; } dev_info(dev, "enabling FLASH_DMA\n"); @@ -2199,7 +2224,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->irq = platform_get_irq(pdev, 0); if ((int)ctrl->irq < 0) { dev_err(dev, "no IRQ defined\n"); - return -ENOD
[PATCH linux-next (v2) 3/3] mtd: brcmnand: Add support for the BCM6368
The BCM6368 has a NAND interrupt register with combined status and enable registers. As the BCM6328, BCM6362 and BCM6368 all use v2.1 controllers, the first variant that will work with this driver is the BCM63268 using a v4.0 controller. Set up the device by disabling and acking all interrupts, then handle the CTRL_READY interrupt. Signed-off-by: Simon Arlott --- Changed "nand-intr-base" reg name to "nand-int-base". drivers/mtd/nand/brcmnand/Makefile | 1 + drivers/mtd/nand/brcmnand/bcm6368_nand.c | 145 +++ 2 files changed, 146 insertions(+) create mode 100644 drivers/mtd/nand/brcmnand/bcm6368_nand.c diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/brcmnand/Makefile index 3b1fbfd..b28ffb59 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/brcmnand/Makefile @@ -2,5 +2,6 @@ # more specific iproc_nand.o, for instance obj-$(CONFIG_MTD_NAND_BRCMNAND)+= iproc_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm63138_nand.o +obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm6368_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmstb_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmnand.o diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c new file mode 100644 index 000..7f5359b --- /dev/null +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from bcm63138_nand.c: + * Copyright © 2015 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: + * Copyright 2000-2010 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: + * Copyright 2000-2010 Broadcom Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "brcmnand.h" + +struct bcm6368_nand_soc { + struct brcmnand_soc soc; + void __iomem *base; +}; + +#define BCM6368_NAND_INT 0x00 +#define BCM6368_NAND_STATUS_SHIFT 0 +#define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT) +#define BCM6368_NAND_ENABLE_SHIFT 16 +#define BCM6368_NAND_ENABLE_MASK (0x << BCM6368_NAND_ENABLE_SHIFT) +#define BCM6368_NAND_BASE_ADDR00x04 +#define BCM6368_NAND_BASE_ADDR10x0c + +enum { + BCM6368_NP_READ = BIT(0), + BCM6368_BLOCK_ERASE = BIT(1), + BCM6368_COPY_BACK = BIT(2), + BCM6368_PAGE_PGM= BIT(3), + BCM6368_CTRL_READY = BIT(4), + BCM6368_DEV_RBPIN = BIT(5), + BCM6368_ECC_ERR_UNC = BIT(6), + BCM6368_ECC_ERR_CORR= BIT(7), +}; + +static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { + /* Ack interrupt */ + val &= ~BCM6368_NAND_STATUS_MASK; + val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; + brcmnand_writel(val, mmio); + return true; + } + + return false; +} + +static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + /* Don't ack any interrupts */ + val &= ~BCM6368_NAND_STATUS_MASK; + + if (en) + val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; + else + val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); + + brcmnand_writel(val, mmio); +} + +static int bcm6368_nand_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm6368_nand_soc *priv; + struct brcmnand_soc *soc; + struct resource *res; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + soc = &priv->soc; + + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "
[PATCH linux-next (v2) 1/3] mtd: brcmnand: Add brcm,bcm6368-nand device tree binding
Add device tree binding for NAND on the BCM6368. The BCM6368 has a NAND interrupt register with combined status and enable registers. It also requires a clock, so add an optional clock to the common brcmnand binding. Signed-off-by: Simon Arlott --- Changed "nand-intr-base" reg name to "nand-int-base". .../devicetree/bindings/mtd/brcm,brcmnand.txt | 32 ++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 4ff7128..ebfa6fc 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt @@ -45,6 +45,8 @@ Required properties: - #size-cells : <0> Optional properties: +- clock : reference to the clock for the NAND controller +- clock-names : "nand" (required for the above clock) - brcm,nand-has-wp : Some versions of this IP include a write-protect (WP) control bit. It is always available on >= v7.0. Use this property to describe the rare @@ -72,6 +74,12 @@ we define additional 'compatible' properties and associated register resources w and enable registers - reg-names: (required) "nand-int-base" + * "brcm,nand-bcm6368" + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm6368" + - reg: (required) the 'NAND_INTR_BASE' register range, with combined status + and enable registers, and boot address registers + - reg-names: (required) "nand-int-base" + * "brcm,nand-iproc" - reg: (required) the "IDM" register range, for interrupt enable and APB bus access endianness configuration, and the "EXT" register range, @@ -148,3 +156,27 @@ nand@f0442800 { }; }; }; + +nand@1200 { + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", "brcm,brcmnand"; + reg = <0x1200 0x180>, + <0x1600 0x200>, + <0x10b0 0x10>; + reg-names = "nand", "nand-cache", "nand-intr-base"; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + clocks = <&periph_clk 20>; + clock-names = "nand"; + + #address-cells = <1>; + #size-cells = <0>; + + nand0: nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <1>; + nand-ecc-step-size = <512>; + }; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next 2/2] MIPS: bmips: Add bcm6345-l1 interrupt controller
Add the BCM6345 interrupt controller based on the SMP-capable BCM7038 and the BCM3380 but with packed interrupt registers. Add the BCM6345 interrupt controller to a list with the existing BCM7038 so that interrupts on CPU1 are not ignored. Update the maintainers file list for BMIPS to include this driver. Signed-off-by: Simon Arlott --- Rebased against linux-next-20151209, no other changes. MAINTAINERS | 1 + arch/mips/Kconfig| 1 + arch/mips/bmips/irq.c| 10 +- drivers/irqchip/Kconfig | 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-bcm6345-l1.c | 364 +++ 6 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 drivers/irqchip/irq-bcm6345-l1.c diff --git a/MAINTAINERS b/MAINTAINERS index 82f296a..9c49d4e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2387,6 +2387,7 @@ F:arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fbf3f66..9caf55a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -151,6 +151,7 @@ config BMIPS_GENERIC select CSRC_R4K select SYNC_R4K select COMMON_CLK + select BCM6345_L1_IRQ select BCM7038_L1_IRQ select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ diff --git a/arch/mips/bmips/irq.c b/arch/mips/bmips/irq.c index e7fc6f934..7efefcf 100644 --- a/arch/mips/bmips/irq.c +++ b/arch/mips/bmips/irq.c @@ -15,6 +15,12 @@ #include #include +static const struct of_device_id smp_intc_dt_match[] = { + { .compatible = "brcm,bcm7038-l1-intc" }, + { .compatible = "brcm,bcm6345-l1-intc" }, + {} +}; + unsigned int get_c0_compare_int(void) { return CP0_LEGACY_COMPARE_IRQ; @@ -24,8 +30,8 @@ void __init arch_init_irq(void) { struct device_node *dn; - /* Only the STB (bcm7038) controller supports SMP IRQ affinity */ - dn = of_find_compatible_node(NULL, NULL, "brcm,bcm7038-l1-intc"); + /* Only these controllers support SMP IRQ affinity */ + dn = of_find_matching_node(NULL, smp_intc_dt_match); if (dn) of_node_put(dn); else diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 4d7294e..d307bb3 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -65,6 +65,11 @@ config I8259 bool select IRQ_DOMAIN +config BCM6345_L1_IRQ + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + config BCM7038_L1_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 177f78f..ded59cf 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -43,6 +43,7 @@ obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX)+= irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_SOC_VF610)+= irq-vf610-mscm-ir.o +obj-$(CONFIG_BCM6345_L1_IRQ) += irq-bcm6345-l1.o obj-$(CONFIG_BCM7038_L1_IRQ) += irq-bcm7038-l1.o obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c new file mode 100644 index 000..b844c89 --- /dev/null +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -0,0 +1,364 @@ +/* + * Broadcom BCM6345 style Level 1 interrupt controller driver + * + * Copyright (C) 2014 Broadcom Corporation + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is based on the BCM7038 (which supports SMP) but with a single + * enable register instead of separate mask/set/clear registers. + * + * The BCM3380 has a similar mask/status register layout, but each pair + * of words is at separate locations (and SMP is not supported). + * + * ENABLE/STATUS words are packed next to each other for each CPU: + * + * BCM6368: + * 0x1000_0020: CPU0_W0_ENABLE + * 0x1000_0024: CPU0_W1_ENABLE + * 0x1000_0028: CPU0_W0_STATUS IRQs 31-63 + * 0x1000_002c: CPU0_W1_STATUS IRQs 0-31 + * 0x1000_0030: CPU1_W0_ENABLE + * 0x1000_0034: CPU1_W1_ENABLE + * 0x1000_0038: CPU1_W0_STATUS IRQs 31-63 + * 0x1000_003c: CPU1_W1_STATUS IRQs 0-31 + * + * BCM63168: + * 0x1000_0020: CPU0_W0_ENABLE + * 0x1000_0024: CPU0_W1_ENABLE + * 0x1000_0028: CPU0_W2_ENABLE + * 0x1000_002c: CPU0_W3_ENABLE + * 0x1000_0030: CPU0_W0_STATUS IRQs 96-127 + * 0x1000_0
[PATCH linux-next 1/2] irqchip: Add brcm,bcm6345-l1-intc device tree binding
Add device tree binding for the BCM6345 interrupt controller. This controller is similar to the SMP-capable BCM7038 and the BCM3380 but with packed interrupt registers. Signed-off-by: Simon Arlott --- Corrected example device name to be "interrupt-controller". .../interrupt-controller/brcm,bcm6345-l1-intc.txt | 57 ++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt diff --git a/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt new file mode 100644 index 000..4040905 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/brcm,bcm6345-l1-intc.txt @@ -0,0 +1,57 @@ +Broadcom BCM6345-style Level 1 interrupt controller + +This block is a first level interrupt controller that is typically connected +directly to one of the HW INT lines on each CPU. + +Key elements of the hardware design include: + +- 32, 64 or 128 incoming level IRQ lines + +- Most onchip peripherals are wired directly to an L1 input + +- A separate instance of the register set for each CPU, allowing individual + peripheral IRQs to be routed to any CPU + +- Contains one or more enable/status word pairs per CPU + +- No atomic set/clear operations + +- No polarity/level/edge settings + +- No FIFO or priority encoder logic; software is expected to read all + 2-4 status words to determine which IRQs are pending + +Required properties: + +- compatible: should be "brcm,bcm-l1-intc", "brcm,bcm6345-l1-intc" +- reg: specifies the base physical address and size of the registers; + the number of supported IRQs is inferred from the size argument +- interrupt-controller: identifies the node as an interrupt controller +- #interrupt-cells: specifies the number of cells needed to encode an interrupt + source, should be 1. +- interrupt-parent: specifies the phandle to the parent interrupt controller(s) + this one is cascaded from +- interrupts: specifies the interrupt line(s) in the interrupt-parent controller + node; valid values depend on the type of parent interrupt controller + +If multiple reg ranges and interrupt-parent entries are present on an SMP +system, the driver will allow IRQ SMP affinity to be set up through the +/proc/irq/ interface. In the simplest possible configuration, only one +reg range and one interrupt-parent is needed. + +The driver operates in native CPU endian by default, there is no support for +specifying an alternative endianness. + +Example: + +periph_intc: interrupt-controller@1000 { +compatible = "brcm,bcm63168-l1-intc", "brcm,bcm6345-l1-intc"; +reg = <0x1020 0x20>, + <0x1040 0x20>; + +interrupt-controller; +#interrupt-cells = <1>; + +interrupt-parent = <&cpu_intc>; +interrupts = <2>, <3>; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] clk: Add brcm,bcm63xx-gate-clk device tree binding
On Fri, December 4, 2015 21:04, Simon Arlott wrote: > On Fri, December 4, 2015 14:30, Rob Herring wrote: >> On Mon, Nov 30, 2015 at 08:52:55PM +0000, Simon Arlott wrote: >>> +periph_clk: periph_clk { >>> + compatible = "brcm,bcm63168-gate-clk", "brcm,bcm63xx-gate-clk"; >>> + regmap = <&periph_cntl>; >> >> What else is in periph_cntrl? Could this all just be part of that node? > > uint32RevID; /* (00) word 0 */ > uint32blkEnables;/* (04) word 1 */ <-- gated clocks > uint32pll_control; /* (08) word 2 */ <-- system reset > controller bit > uint32deviceTimeoutEn; /* (0c) word 3 */ <-- unknown > uint32softResetB;/* (10) word 4 */ <-- device reset > controller bits > uint32diagControl;/* (14) word 5 */ <-- unknown > uint32ExtIrqCfg; /* (18) word 6*/ <-- external interrupt > controller > uint32unused1;/* (1c) word 7 */ <-- (external > interrupt controller?) > IrqControl_t IrqControl[3];/* (20) (40) (60) */ <-- normal > interrupt controller On the BCM6368 [1], blkEnables also conatains a power domain bit: uint32blkEnables;/* (04) word 1 */ #define USBH_IDDQ_EN (1 << 19) #define IPSEC_CLK_EN (1 << 18) #define NAND_CLK_EN (1 << 17) #define DISABLE_GLESS(1 << 16) #define USBH_CLK_EN (1 << 15) #define PCM_CLK_EN (1 << 14) #define UTOPIA_CLK_EN(1 << 13) #define ROBOSW_CLK_EN(1 << 12) #define SAR_CLK_EN (1 << 11) #define USBD_CLK_EN (1 << 10) #define SPI_CLK_EN (1 << 9) #define SWPKT_SAR_CLK_EN (1 << 8) #define SWPKT_USB_CLK_EN (1 << 7) #define PHYMIPS_CLK_EN (1 << 6) #define VDSL_CLK_EN (1 << 5) #define VDSL_BONDING_EN (1 << 4) #define VDSL_AFE_EN (1 << 3) #define VDSL_QPROC_EN(1 << 2) In order to be able to map these to devices for the BCM63xx SoCs I'm going to define the power controller binding with "power-domain-indices" and "power-domain-names" to mirror the clock binding. The separate clk and generic_pm_domain devices will then handle set/clear of the relevant bits using the regmap. [1] https://code.google.com/p/gfiber-gflt100/source/browse/shared/opensource/include/bcm963xx/6368_map_part.h?r=b292e8c271addbda62104bece90e3c8018714194 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/3] mtd: brcmnand: Add brcm,bcm6368-nand device tree binding
On Fri, December 4, 2015 16:04, Jonas Gorski wrote: > On Thu, Dec 3, 2015 at 12:41 AM, Simon Arlott wrote: >> + * "brcm,nand-bcm6368" >> + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm6368" >> + - reg: (required) the 'NAND_INTR_BASE' register range, with combined >> status >> + and enable registers, and boot address registers >> + - reg-names: (required) "nand-intr-base" > > Can't we use the same name as bcm63138, i.e. nand-int-base? Brian, Before I change this, is there anything else in the patch series that needs to be changed? (I'll keep the comment referring to "NAND_INTR_BASE" the same because that's the name in the original #define for this hardware.) -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH (v2) 1/2] reset: Add brcm,bcm6345-reset device tree binding
On Thu, December 3, 2015 08:39, Philipp Zabel wrote: > Am Mittwoch, den 02.12.2015, 21:03 + schrieb Simon Arlott: >> +periph_soft_rst: reset-controller { >> +compatible = "brcm,bcm63168-reset", "brcm,bcm6345-reset"; >> +regmap = <&periph_cntl>; >> +offset = <0x10>; >> + >> +#reset-cells = <1>; >> +}; > > I would have written it something like this: > > periph_cntl: ... { > compatible = "syscon", "simple-mfd"; > #address-cells = <1>; > #size-cells = <1>; > > periph_soft_rst: reset-controller { > compatible = "brcm,bcm6345-reset"; > reg = <0x10 0x4>; > #reset-cells = <1>; > }; > }; > > for a device that is only controlled through a syscon. Rob, do you want me to change this or is my version ok? > The driver itself looks good to me. > > best regards > Philipp > > -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] clk: Add brcm,bcm63xx-gate-clk device tree binding
On Fri, December 4, 2015 14:30, Rob Herring wrote: > On Mon, Nov 30, 2015 at 08:52:55PM +0000, Simon Arlott wrote: >> +periph_clk: periph_clk { >> +compatible = "brcm,bcm63168-gate-clk", "brcm,bcm63xx-gate-clk"; >> +regmap = <&periph_cntl>; > > What else is in periph_cntrl? Could this all just be part of that node? uint32RevID; /* (00) word 0 */ uint32blkEnables;/* (04) word 1 */ <-- gated clocks uint32pll_control; /* (08) word 2 */ <-- system reset controller bit uint32deviceTimeoutEn; /* (0c) word 3 */ <-- unknown uint32softResetB;/* (10) word 4 */ <-- device reset controller bits uint32diagControl;/* (14) word 5 */ <-- unknown uint32ExtIrqCfg; /* (18) word 6*/ <-- external interrupt controller uint32unused1;/* (1c) word 7 */ <-- (external interrupt controller?) IrqControl_t IrqControl[3];/* (20) (40) (60) */ <-- normal interrupt controller So it has these clocks, two types of reset controller, and the interrupt controllers, but I've left the interrupt controllers registers out of the syscon device. For the registers in the "timer" peripheral at the end of the timer/watchdog registers: uint32EnSwPLL; <-- unknown uint32ClkRstCtl; #define POR_RESET_STATUS(1 << 31) <-- unknown #define HW_RESET_STATUS (1 << 30) <-- unknown #define SW_RESET_STATUS (1 << 29) <-- unknown #define USB_REF_CLKEN (1 << 18) <-- gated clock #define UTO_EXTIN_CLKEN (1 << 17) <-- gated clock #define UTO_CLK50_SEL (1 << 16) <-- looks like a clock frequency selection bit #define FAP2_PLL_CLKEN (1 << 15) <-- gated clock #define FAP2_PLL_FREQ_SHIFT 12<-- bits for controlling the frequency #define FAP1_PLL_CLKEN (1 << 11) <-- gated clock #define FAP1_PLL_FREQ_SHIFT 8 <-- bits for controlling the frequency #define WAKEON_DSL (1 << 7) <-- wake on network bit #define WAKEON_EPHY (1 << 6) <-- wake on network bit #define DSL_ENERGY_DETECT_ENABLE(1 << 4) <-- energy saving control for network #define GPHY_1_ENERGY_DETECT_ENABLE (1 << 3) <-- energy saving control for network #define EPHY_3_ENERGY_DETECT_ENABLE (1 << 2) <-- energy saving control for network #define EPHY_2_ENERGY_DETECT_ENABLE (1 << 1) <-- energy saving control for network #define EPHY_1_ENERGY_DETECT_ENABLE (1 << 0) <-- energy saving control for network I need the usb_ref clock for USB, and I want to be able to disable uto_extin, fap1 and fap2 as they're unused by anything in the device tree. The full list of registers is here: https://github.com/lp0/bcm963xx_4.12L.06B_consumer/blob/master/shared/opensource/include/bcm963xx/63268_map_part.h -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On Fri, December 4, 2015 11:00, Mark Brown wrote: > On Thu, Dec 03, 2015 at 11:51:16PM +0000, Simon Arlott wrote: >> On 03/12/15 23:45, Mark Brown wrote: > >> > Are you *sure* these are regulators and not power domains? These names >> > look a lot like they could be power domains. > >> No, I'm not sure. Some of them are may actually be regulators (the "PHY" >> ones) while others are almost definitely power domains (like the "FAP" >> Forwarding Assist Processor). > > OK, so the power domains should be being represented and managed as such > rather than using regulators - it's a better fit (doing things like > support atomic context) and it also sidesteps this. For the things that > you say are clearly regulators should we have more information about > those? I'd prefer to handle them all as power domains since it fits better. Even if some of them are regulators there's no extra control or status interface and they're used like power domains to disable unused functionality. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On 03/12/15 23:45, Mark Brown wrote: > On Thu, Dec 03, 2015 at 11:38:28PM +0000, Simon Arlott wrote: > >> #define MISC_IDDQ_CTRL_GMAC (1<<18) >> #define MISC_IDDQ_CTRL_WLAN_PADS(1<<13) >> #define MISC_IDDQ_CTRL_PCIE (1<<12) >> #define MISC_IDDQ_CTRL_FAP (1<<11) >> #define MISC_IDDQ_CTRL_VDSL_MIPS(1<<10) >> #define MISC_IDDQ_CTRL_VDSL_PHY (1<<9) >> #define MISC_IDDQ_CTRL_PERIPH (1<<8) >> #define MISC_IDDQ_CTRL_PCM (1<<7) >> #define MISC_IDDQ_CTRL_ROBOSW (1<<6) >> #define MISC_IDDQ_CTRL_USBD (1<<5) >> #define MISC_IDDQ_CTRL_USBH (1<<4) >> #define MISC_IDDQ_CTRL_DECT (1<<3) >> #define MISC_IDDQ_CTRL_MIPS (1<<2) >> #define MISC_IDDQ_CTRL_IPSEC(1<<1) >> #define MISC_IDDQ_CTRL_SAR (1<<0) > > Are you *sure* these are regulators and not power domains? These names > look a lot like they could be power domains. No, I'm not sure. Some of them are may actually be regulators (the "PHY" ones) while others are almost definitely power domains (like the "FAP" Forwarding Assist Processor). -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On 03/12/15 15:05, Mark Brown wrote: > On Thu, Dec 03, 2015 at 08:14:33AM +0000, Simon Arlott wrote: >> On 03/12/15 00:06, Mark Brown wrote: > >> > this it should know at least something about how to control the device >> > from the compatible string. If you're making a generic driver it should >> > not make reference to specific devices. > >> Will you accept a generic driver for a simple enable regulator device on >> a regmap? What should its compatible string be? > > Perhaps. I really don't like putting the entire driver into DT, it's > not a pattern I want to encourage. I don't like putting the list of which bit is which regulator name into a driver because it means that new hardware that adds a regulator or moves them around requires a change to the driver. Documentation/devicetree/usage-model.txt: 2.1 High Level View --- [...] Using it allows board and device support to become data driven; to make setup decisions based on data passed into the kernel instead of on per-machine hard coded selections. I agree that an entire driver shouldn't be put in the DT (especially given that you then need the DT to debug any issue), but this isn't much of a driver when it involves flipping a single bit. The key thing would be to avoid it growing into something too complex (e.g. set register X to 42 to enable and set register Y to 90 to disable, would not belong in DT). Should I be looking at trying to use generic_pm_domain instead of a regulator? Those don't appear to require a name so a phandle with an argument for the bit would work. >> > There could be one if it would help, but we do normally manage to do >> > this without - look at how other regulator drivers work. > >> Several of them have a fixed list of supported regulator names in the > > Yes, that's the way this is handled. I see two variants of the hardware bits (three if you consider that the GMAC isn't on every SoC): #define MISC_IDDQ_CTRL_GMAC (1<<18) #define MISC_IDDQ_CTRL_WLAN_PADS(1<<13) #define MISC_IDDQ_CTRL_PCIE (1<<12) #define MISC_IDDQ_CTRL_FAP (1<<11) #define MISC_IDDQ_CTRL_VDSL_MIPS(1<<10) #define MISC_IDDQ_CTRL_VDSL_PHY (1<<9) #define MISC_IDDQ_CTRL_PERIPH (1<<8) #define MISC_IDDQ_CTRL_PCM (1<<7) #define MISC_IDDQ_CTRL_ROBOSW (1<<6) #define MISC_IDDQ_CTRL_USBD (1<<5) #define MISC_IDDQ_CTRL_USBH (1<<4) #define MISC_IDDQ_CTRL_DECT (1<<3) #define MISC_IDDQ_CTRL_MIPS (1<<2) #define MISC_IDDQ_CTRL_IPSEC(1<<1) #define MISC_IDDQ_CTRL_SAR (1<<0) #define MISC_IDDQ_CTRL_EPHY (1<<9) #define MISC_IDDQ_CTRL_ROBOSW (1<<8) #define MISC_IDDQ_CTRL_PCIE (1<<7) #define MISC_IDDQ_CTRL_USBH (1<<6) #define MISC_IDDQ_CTRL_USBD (1<<5) #define MISC_IDDQ_CTRL_PCM (1<<4) #define MISC_IDDQ_CTRL_SAR (1<<3) #define MISC_IDDQ_CTRL_ADSL2_AFE(1<<2) #define MISC_IDDQ_CTRL_ADSL2_PHY(1<<1) #define MISC_IDDQ_CTRL_ADSL2_MIPS (1<<0) I could put these lists of bits in a driver (associated with the names) but I'd strongly prefer to put the list of bits in the DT. If they are in the driver, then there is nothing to stop someone from deciding to force it to fit a different new piece of hardware by deliberately using the wrong names in the DT just because they match the bits they want to use, and they think they can't wait for a new list of bits to be added to the kernel. e.g. someone adds an LTE chip and reuses the obsolete DECT regulator: misc_iddq_ctrl@42 { compatible = "...-regulator"; reg = <0x42>; regulators { lte_power: dect { regulator-name = "LTE"; }; }; }; Associating the bits with the names in the DT avoids this problem at the expense of having a very generic driver. A lot of the existing regulator drivers have mostly numbered regulator pins which could have been connected to anything on a hardware variant. >> driver. The regulator names for this device are meaningless to the >> driver because all of the regulators look the same. They don't have a >> known or controllable voltage and can only be turned on or off. > > Nonsense. The names are useful to identify which supply is being > referred to. Having voltage control is irrelevant to identifying > regulators. Ok, but from the driver's point of view there's nothing different about any of the regulators on this hardware. I could have numbered them "BIT0" to "BIT31" in the driver and used a meaningful alias in DT. >> Any table mapping regulator names to bits in the register would be
[PATCH linux-next 3/3] mtd: brcmnand: Add support for the BCM6368
The BCM6368 has a NAND interrupt register with combined status and enable registers. As the BCM6328, BCM6362 and BCM6368 all use v2.1 controllers, the first variant that will work with this driver is the BCM63268 using a v4.0 controller. Set up the device by disabling and acking all interrupts, then handle the CTRL_READY interrupt. Signed-off-by: Simon Arlott --- drivers/mtd/nand/brcmnand/Makefile | 1 + drivers/mtd/nand/brcmnand/bcm6368_nand.c | 145 +++ 2 files changed, 146 insertions(+) create mode 100644 drivers/mtd/nand/brcmnand/bcm6368_nand.c diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/brcmnand/Makefile index 3b1fbfd..b28ffb59 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/brcmnand/Makefile @@ -2,5 +2,6 @@ # more specific iproc_nand.o, for instance obj-$(CONFIG_MTD_NAND_BRCMNAND)+= iproc_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm63138_nand.o +obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm6368_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmstb_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmnand.o diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c new file mode 100644 index 000..c347ea5 --- /dev/null +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from bcm63138_nand.c: + * Copyright © 2015 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: + * Copyright 2000-2010 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: + * Copyright 2000-2010 Broadcom Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "brcmnand.h" + +struct bcm6368_nand_soc { + struct brcmnand_soc soc; + void __iomem *base; +}; + +#define BCM6368_NAND_INT 0x00 +#define BCM6368_NAND_STATUS_SHIFT 0 +#define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT) +#define BCM6368_NAND_ENABLE_SHIFT 16 +#define BCM6368_NAND_ENABLE_MASK (0x << BCM6368_NAND_ENABLE_SHIFT) +#define BCM6368_NAND_BASE_ADDR00x04 +#define BCM6368_NAND_BASE_ADDR10x0c + +enum { + BCM6368_NP_READ = BIT(0), + BCM6368_BLOCK_ERASE = BIT(1), + BCM6368_COPY_BACK = BIT(2), + BCM6368_PAGE_PGM= BIT(3), + BCM6368_CTRL_READY = BIT(4), + BCM6368_DEV_RBPIN = BIT(5), + BCM6368_ECC_ERR_UNC = BIT(6), + BCM6368_ECC_ERR_CORR= BIT(7), +}; + +static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { + /* Ack interrupt */ + val &= ~BCM6368_NAND_STATUS_MASK; + val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; + brcmnand_writel(val, mmio); + return true; + } + + return false; +} + +static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + /* Don't ack any interrupts */ + val &= ~BCM6368_NAND_STATUS_MASK; + + if (en) + val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; + else + val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); + + brcmnand_writel(val, mmio); +} + +static int bcm6368_nand_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm6368_nand_soc *priv; + struct brcmnand_soc *soc; + struct resource *res; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + soc = &priv->soc; + + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "nand-intr-base"); + if (!res) + retu
[PATCH linux-next 2/3] mtd: brcmnand: Request and enable the clock if present
Attempt to enable a clock named "nand" as some SoCs have a clock for the controller that needs to be enabled. Signed-off-by: Simon Arlott --- Removed ctrl->clk not NULL check. drivers/mtd/nand/brcmnand/brcmnand.c | 64 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 35d78f7..cf0374e 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -122,6 +123,9 @@ struct brcmnand_controller { /* Some SoCs provide custom interrupt status register(s) */ struct brcmnand_soc *soc; + /* Some SoCs have a gateable clock for the controller */ + struct clk *clk; + int cmd_pending; booldma_pending; struct completion done; @@ -2127,10 +2131,24 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (IS_ERR(ctrl->nand_base)) return PTR_ERR(ctrl->nand_base); + /* Enable clock before using NAND registers */ + ctrl->clk = devm_clk_get(dev, "nand"); + if (!IS_ERR(ctrl->clk)) { + ret = clk_prepare_enable(ctrl->clk); + if (ret) + return ret; + } else { + ret = PTR_ERR(ctrl->clk); + if (ret == -EPROBE_DEFER) + return ret; + + ctrl->clk = NULL; + } + /* Initialize NAND revision */ ret = brcmnand_revision_init(ctrl); if (ret) - return ret; + goto err; /* * Most chips have this cache at a fixed offset within 'nand' block. @@ -2139,8 +2157,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); if (res) { ctrl->nand_fc = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->nand_fc)) - return PTR_ERR(ctrl->nand_fc); + if (IS_ERR(ctrl->nand_fc)) { + ret = PTR_ERR(ctrl->nand_fc); + goto err; + } } else { ctrl->nand_fc = ctrl->nand_base + ctrl->reg_offsets[BRCMNAND_FC_BASE]; @@ -2150,8 +2170,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); if (res) { ctrl->flash_dma_base = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->flash_dma_base)) - return PTR_ERR(ctrl->flash_dma_base); + if (IS_ERR(ctrl->flash_dma_base)) { + ret = PTR_ERR(ctrl->flash_dma_base); + goto err; + } flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); @@ -2160,13 +2182,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->dma_desc = dmam_alloc_coherent(dev, sizeof(*ctrl->dma_desc), &ctrl->dma_pa, GFP_KERNEL); - if (!ctrl->dma_desc) - return -ENOMEM; + if (!ctrl->dma_desc) { + ret = -ENOMEM; + goto err; + } ctrl->dma_irq = platform_get_irq(pdev, 1); if ((int)ctrl->dma_irq < 0) { dev_err(dev, "missing FLASH_DMA IRQ\n"); - return -ENODEV; + ret = -ENODEV; + goto err; } ret = devm_request_irq(dev, ctrl->dma_irq, @@ -2175,7 +2200,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) { dev_err(dev, "can't allocate IRQ %d: error %d\n", ctrl->dma_irq, ret); - return ret; + goto err; } dev_info(dev, "enabling FLASH_DMA\n"); @@ -2199,7 +2224,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->irq = platform_get_irq(pdev, 0); if ((int)ctrl->irq < 0) { dev_err(dev, "no IRQ defined\n"); - return -E
[PATCH linux-next 1/3] mtd: brcmnand: Add brcm,bcm6368-nand device tree binding
Add device tree binding for NAND on the BCM6368. The BCM6368 has a NAND interrupt register with combined status and enable registers. It also requires a clock, so add an optional clock to the common brcmnand binding. Signed-off-by: Simon Arlott --- .../devicetree/bindings/mtd/brcm,brcmnand.txt | 32 ++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 4ff7128..16d7835 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt @@ -45,6 +45,8 @@ Required properties: - #size-cells : <0> Optional properties: +- clock : reference to the clock for the NAND controller +- clock-names : "nand" (required for the above clock) - brcm,nand-has-wp : Some versions of this IP include a write-protect (WP) control bit. It is always available on >= v7.0. Use this property to describe the rare @@ -72,6 +74,12 @@ we define additional 'compatible' properties and associated register resources w and enable registers - reg-names: (required) "nand-int-base" + * "brcm,nand-bcm6368" + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm6368" + - reg: (required) the 'NAND_INTR_BASE' register range, with combined status + and enable registers, and boot address registers + - reg-names: (required) "nand-intr-base" + * "brcm,nand-iproc" - reg: (required) the "IDM" register range, for interrupt enable and APB bus access endianness configuration, and the "EXT" register range, @@ -148,3 +156,27 @@ nand@f0442800 { }; }; }; + +nand@1200 { + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", "brcm,brcmnand"; + reg = <0x1200 0x180>, + <0x1600 0x200>, + <0x10b0 0x10>; + reg-names = "nand", "nand-cache", "nand-intr-base"; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + clocks = <&periph_clk 20>; + clock-names = "nand"; + + #address-cells = <1>; + #size-cells = <0>; + + nand0: nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <1>; + nand-ecc-step-size = <512>; + }; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH linux-next 2/2] clk: bcm6345: Add BCM6345 gated clock support
The BCM6345 contains clocks gated with a register. Clocks are indexed by bits in the register and are active high. Clock gate bits are interleaved with other status bits and configurable clocks in the same register. Enabled by default for BMIPS_GENERIC. Signed-off-by: Simon Arlott --- Renamed to BCM6345. MAINTAINERS | 1 + drivers/clk/bcm/Kconfig | 9 ++ drivers/clk/bcm/Makefile | 1 + drivers/clk/bcm/clk-bcm6345.c | 191 ++ 4 files changed, 202 insertions(+) create mode 100644 drivers/clk/bcm/clk-bcm6345.c diff --git a/MAINTAINERS b/MAINTAINERS index 577e5ea..9a61f48 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2381,6 +2381,7 @@ F:arch/mips/bmips/* F: arch/mips/include/asm/mach-bmips/* F: arch/mips/kernel/*bmips* F: arch/mips/boot/dts/brcm/bcm*.dts* +F: drivers/clk/bcm/clk-bcm6345* F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* diff --git a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig index f287845..043353a 100644 --- a/drivers/clk/bcm/Kconfig +++ b/drivers/clk/bcm/Kconfig @@ -8,6 +8,15 @@ config CLK_BCM_63XX Enable common clock framework support for Broadcom BCM63xx DSL SoCs based on the ARM architecture +config CLK_BCM_6345 + bool "Broadcom BCM6345 clock support" + depends on BMIPS_GENERIC || COMPILE_TEST + depends on COMMON_CLK + default BMIPS_GENERIC + help + Enable common clock framework support for Broadcom BCM6345 DSL SoCs + based on the MIPS architecture + config CLK_BCM_KONA bool "Broadcom Kona CCU clock support" depends on ARCH_BCM_MOBILE || COMPILE_TEST diff --git a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile index 247c267..e2bac43 100644 --- a/drivers/clk/bcm/Makefile +++ b/drivers/clk/bcm/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_CLK_BCM_63XX) += clk-bcm63xx.o +obj-$(CONFIG_CLK_BCM_6345) += clk-bcm6345.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona.o obj-$(CONFIG_CLK_BCM_KONA) += clk-kona-setup.o obj-$(CONFIG_CLK_BCM_KONA) += clk-bcm281xx.o diff --git a/drivers/clk/bcm/clk-bcm6345.c b/drivers/clk/bcm/clk-bcm6345.c new file mode 100644 index 000..88a1e7e --- /dev/null +++ b/drivers/clk/bcm/clk-bcm6345.c @@ -0,0 +1,191 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from clk-gate.c: + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: Basic clock which uses a bit in a regmap to gate and ungate the output + * + * Traits of this clock: + * prepare - clk_(un)prepare only ensures parent is (un)prepared + * enable - clk_enable and clk_disable are functional & control gating + * rate - inherits rate from parent. No clk_set_rate support + * parent - fixed parent. No clk_set_parent support + */ + +struct clk_bcm6345 { + struct clk_hw hw; + struct regmap *map; + u32 offset; + u32 mask; +}; + +#define to_clk_bcm6345(_hw) container_of(_hw, struct clk_bcm6345, hw) + +static int clk_bcm6345_enable(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + + return regmap_write_bits(gate->map, gate->offset, + gate->mask, gate->mask); +} + +static void clk_bcm6345_disable(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + + regmap_write_bits(gate->map, gate->offset, + gate->mask, 0); +} + +static int clk_bcm6345_is_enabled(struct clk_hw *hw) +{ + struct clk_bcm6345 *gate = to_clk_bcm6345(hw); + unsigned int val; + int ret; + + ret = regmap_read(gate->map, gate->offset, &val); + if (ret) + return ret; + + val &= gate->mask; + + return val ? 1 : 0; +} + +const struct clk_ops clk_bcm6345_ops = { + .enable = clk_bcm6345_enable, + .disable = clk_bcm6345_disable, + .is_enabled = clk_bcm6345_is_enabled, +}; + +static struct clk * __init of_bcm6345_clk_register(const char *parent_name, + const char *clk_name, struct regmap *map, u32 offset, u32 mask) +{ + struct clk_bcm6345 *gate; + struct clk_init_data init; + struc
[PATCH linux-next 1/2] clk: Add brcm,bcm6345-gate-clk device tree binding
Add device tree binding for the BCM6345's gated clocks. The BCM6345 contains clocks gated with a register. Clocks are indexed by bits in the register and are active high. Clock gate bits are interleaved with other status bits and configurable clocks in the same register. Signed-off-by: Simon Arlott --- Renamed to BCM6345. .../bindings/clock/brcm,bcm6345-gate-clk.txt | 58 ++ 1 file changed, 58 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt diff --git a/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt b/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt new file mode 100644 index 000..5801264 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/brcm,bcm6345-gate-clk.txt @@ -0,0 +1,58 @@ +Broadcom BCM6345 clocks + +This binding uses the common clock binding: + Documentation/devicetree/bindings/clock/clock-bindings.txt + +The BCM6345 contains clocks gated with a register. Clocks are indexed +by bits in the register and are active high. Clock gate bits are +interleaved with other status bits and configurable clocks in the same +register. + +Required properties: +- compatible: Should be "brcm,bcm-gate-clk", "brcm,bcm6345-gate-clk" +- #clock-cells:Should be <1>. +- regmap: The register map phandle +- offset: Offset in the register map for the clock register (in bytes) +- clocks: The external oscillator clock phandle + +Example: + +periph_clk: periph_clk { + compatible = "brcm,bcm63168-gate-clk", "brcm,bcm6345-gate-clk"; + regmap = <&periph_cntl>; + offset = <0x4>; + + #clock-cells = <1>; + clock-indices = + <1>, <2>,<3>, <4>, <5>, + <6>, <7>,<8>, <9>, <10>, + <11>, <12>, <13>, <14>,<15>, + <16>, <17>, <18>, <19>,<20>, + <27>, <31>; + clock-output-names = + "vdsl_qproc", "vdsl_afe", "vdsl","mips", "wlan_ocp", + "dect", "fap0", "fap1","sar", "robosw", + "pcm","usbd", "usbh","ipsec", "spi", + "hsspi", "pcie", "phymips", "gmac", "nand", + "tbus", "robosw250"; +}; + +timer_clk: timer_clk { + compatible = "brcm,bcm63168-gate-clk", "brcm,bcm6345-gate-clk"; + regmap = <&timer_cntl>; + offset = <0x4>; + + #clock-cells = <1>; + clock-indices = <17>, <18>; + clock-output-names = "uto_extin", "usb_ref"; +}; + +ehci0: usb@10002500 { + compatible = "brcm,bcm63168-ehci", "brcm,bcm6345-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + interrupt-parent = <&periph_intc>; + interrupts = <10>; + clocks = <&periph_clk 13>, <&timer_clk 18>; + phys = <&usbh>; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On 03/12/15 00:06, Mark Brown wrote: > On Wed, Dec 02, 2015 at 08:26:36PM +0000, Simon Arlott wrote: >> On 02/12/15 12:53, Mark Brown wrote: > >> > This is the sort of thing you can pick up from the SoC compatible >> > strings. As things stand there is zero content in this driver that >> > relates to this SoC. > >> There's always going to be very little content in the driver that >> relates to this SoC, given that a single bit flip enables/disables >> power. > >> All other device tree drivers allow a register address to be specified >> for the device, how is an offset in the regmap any different? > > It's not that it's an offset in regmap, it's that you're trying to make > a device driver with literally *no* content that is specific to the > actual device. If you're making a driver for a specific device like The device that only has a single register, I don't want to make it specific to the device by hard coding a register address in the driver that changes when the same device is used on different SoCs. > this it should know at least something about how to control the device > from the compatible string. If you're making a generic driver it should > not make reference to specific devices. Will you accept a generic driver for a simple enable regulator device on a regmap? What should its compatible string be? > In general I would prefer to have a driver with a SoC specific > compatible string and the data tables in the kernel, that way we keep > the device trees stable and our ABI more robust. > >> >> The mask is used as there's one bit per regulator in the register, but >> >> there's more than one way to express this in the DT: > >> > I wouldn't expect to see it in the device tree at all for a device >> > specific driver. > >> If there isn't an individual entry in DT for each regulator, how is it >> supposed to work? There's no #regulator-cells property. > > There could be one if it would help, but we do normally manage to do > this without - look at how other regulator drivers work. Several of them have a fixed list of supported regulator names in the driver. The regulator names for this device are meaningless to the driver because all of the regulators look the same. They don't have a known or controllable voltage and can only be turned on or off. Any table mapping regulator names to bits in the register would be different for each SoC making the list of regulator names in the device tree redundant. If they're not listed in the device tree then I can't use them as a phandle for other devices. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] mtd: brcmnand: Add support for the BCM6368
The BCM6368 has a NAND interrupt register with combined status and enable registers. As the BCM6328, BCM6362 and BCM6368 all use v2.1 controllers, the first variant that will work with this driver is the BCM63268 using a v4.0 controller. Set up the device by disabling and acking all interrupts, then handle the CTRL_READY interrupt. Signed-off-by: Simon Arlott --- Renamed from BCM63268, moved clock to brcmnand. drivers/mtd/nand/brcmnand/Makefile | 1 + drivers/mtd/nand/brcmnand/bcm6368_nand.c | 145 +++ 2 files changed, 146 insertions(+) create mode 100644 drivers/mtd/nand/brcmnand/bcm6368_nand.c diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/brcmnand/Makefile index 3b1fbfd..b28ffb59 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/brcmnand/Makefile @@ -2,5 +2,6 @@ # more specific iproc_nand.o, for instance obj-$(CONFIG_MTD_NAND_BRCMNAND)+= iproc_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm63138_nand.o +obj-$(CONFIG_MTD_NAND_BRCMNAND)+= bcm6368_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmstb_nand.o obj-$(CONFIG_MTD_NAND_BRCMNAND)+= brcmnand.o diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c new file mode 100644 index 000..c347ea5 --- /dev/null +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Derived from bcm63138_nand.c: + * Copyright © 2015 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: + * Copyright 2000-2010 Broadcom Corporation + * + * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: + * Copyright 2000-2010 Broadcom Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "brcmnand.h" + +struct bcm6368_nand_soc { + struct brcmnand_soc soc; + void __iomem *base; +}; + +#define BCM6368_NAND_INT 0x00 +#define BCM6368_NAND_STATUS_SHIFT 0 +#define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT) +#define BCM6368_NAND_ENABLE_SHIFT 16 +#define BCM6368_NAND_ENABLE_MASK (0x << BCM6368_NAND_ENABLE_SHIFT) +#define BCM6368_NAND_BASE_ADDR00x04 +#define BCM6368_NAND_BASE_ADDR10x0c + +enum { + BCM6368_NP_READ = BIT(0), + BCM6368_BLOCK_ERASE = BIT(1), + BCM6368_COPY_BACK = BIT(2), + BCM6368_PAGE_PGM= BIT(3), + BCM6368_CTRL_READY = BIT(4), + BCM6368_DEV_RBPIN = BIT(5), + BCM6368_ECC_ERR_UNC = BIT(6), + BCM6368_ECC_ERR_CORR= BIT(7), +}; + +static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { + /* Ack interrupt */ + val &= ~BCM6368_NAND_STATUS_MASK; + val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; + brcmnand_writel(val, mmio); + return true; + } + + return false; +} + +static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) +{ + struct bcm6368_nand_soc *priv = + container_of(soc, struct bcm6368_nand_soc, soc); + void __iomem *mmio = priv->base + BCM6368_NAND_INT; + u32 val = brcmnand_readl(mmio); + + /* Don't ack any interrupts */ + val &= ~BCM6368_NAND_STATUS_MASK; + + if (en) + val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; + else + val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); + + brcmnand_writel(val, mmio); +} + +static int bcm6368_nand_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct bcm6368_nand_soc *priv; + struct brcmnand_soc *soc; + struct resource *res; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + soc = &priv->soc; + + res = platform_get_resource_byname(pdev, + IORESOURCE_MEM, "nand-intr-base"); +
[PATCH 2/3] mtd: brcmnand: Request and enable the clock if present
Attempt to enable a clock named "nand" as some SoCs have a clock for the controller that needs to be enabled. Signed-off-by: Simon Arlott --- drivers/mtd/nand/brcmnand/brcmnand.c | 69 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 2c8f67f..0a9cccf 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -122,6 +123,9 @@ struct brcmnand_controller { /* Some SoCs provide custom interrupt status register(s) */ struct brcmnand_soc *soc; + /* Some SoCs have a gateable clock for the controller */ + struct clk *clk; + int cmd_pending; booldma_pending; struct completion done; @@ -2136,10 +2140,24 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (IS_ERR(ctrl->nand_base)) return PTR_ERR(ctrl->nand_base); + /* Enable clock before using NAND registers */ + ctrl->clk = devm_clk_get(dev, "nand"); + if (!IS_ERR(ctrl->clk)) { + ret = clk_prepare_enable(ctrl->clk); + if (ret) + return ret; + } else { + ret = PTR_ERR(ctrl->clk); + if (ret == -EPROBE_DEFER) + return ret; + + ctrl->clk = NULL; + } + /* Initialize NAND revision */ ret = brcmnand_revision_init(ctrl); if (ret) - return ret; + goto err; /* * Most chips have this cache at a fixed offset within 'nand' block. @@ -2148,8 +2166,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); if (res) { ctrl->nand_fc = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->nand_fc)) - return PTR_ERR(ctrl->nand_fc); + if (IS_ERR(ctrl->nand_fc)) { + ret = PTR_ERR(ctrl->nand_fc); + goto err; + } } else { ctrl->nand_fc = ctrl->nand_base + ctrl->reg_offsets[BRCMNAND_FC_BASE]; @@ -2159,8 +2179,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); if (res) { ctrl->flash_dma_base = devm_ioremap_resource(dev, res); - if (IS_ERR(ctrl->flash_dma_base)) - return PTR_ERR(ctrl->flash_dma_base); + if (IS_ERR(ctrl->flash_dma_base)) { + ret = PTR_ERR(ctrl->flash_dma_base); + goto err; + } flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); @@ -2169,13 +2191,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->dma_desc = dmam_alloc_coherent(dev, sizeof(*ctrl->dma_desc), &ctrl->dma_pa, GFP_KERNEL); - if (!ctrl->dma_desc) - return -ENOMEM; + if (!ctrl->dma_desc) { + ret = -ENOMEM; + goto err; + } ctrl->dma_irq = platform_get_irq(pdev, 1); if ((int)ctrl->dma_irq < 0) { dev_err(dev, "missing FLASH_DMA IRQ\n"); - return -ENODEV; + ret = -ENODEV; + goto err; } ret = devm_request_irq(dev, ctrl->dma_irq, @@ -2184,7 +2209,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) if (ret < 0) { dev_err(dev, "can't allocate IRQ %d: error %d\n", ctrl->dma_irq, ret); - return ret; + goto err; } dev_info(dev, "enabling FLASH_DMA\n"); @@ -2208,7 +2233,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) ctrl->irq = platform_get_irq(pdev, 0); if ((int)ctrl->irq < 0) { dev_err(dev, "no IRQ defined\n"); - return -ENODEV; + ret = -ENODEV; +
[PATCH 1/3] mtd: brcmnand: Add brcm,bcm6368-nand device tree binding
Add device tree binding for NAND on the BCM6368. The BCM6368 has a NAND interrupt register with combined status and enable registers. It also requires a clock, so add an optional clock to the common brcmnand binding. Signed-off-by: Simon Arlott --- Renamed from BCM63268, made clock a generic property. .../devicetree/bindings/mtd/brcm,brcmnand.txt | 32 ++ 1 file changed, 32 insertions(+) diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 4ff7128..16d7835 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt @@ -45,6 +45,8 @@ Required properties: - #size-cells : <0> Optional properties: +- clock : reference to the clock for the NAND controller +- clock-names : "nand" (required for the above clock) - brcm,nand-has-wp : Some versions of this IP include a write-protect (WP) control bit. It is always available on >= v7.0. Use this property to describe the rare @@ -72,6 +74,12 @@ we define additional 'compatible' properties and associated register resources w and enable registers - reg-names: (required) "nand-int-base" + * "brcm,nand-bcm6368" + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm6368" + - reg: (required) the 'NAND_INTR_BASE' register range, with combined status + and enable registers, and boot address registers + - reg-names: (required) "nand-intr-base" + * "brcm,nand-iproc" - reg: (required) the "IDM" register range, for interrupt enable and APB bus access endianness configuration, and the "EXT" register range, @@ -148,3 +156,27 @@ nand@f0442800 { }; }; }; + +nand@1200 { + compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", + "brcm,brcmnand-v4.0", "brcm,brcmnand"; + reg = <0x1200 0x180>, + <0x1600 0x200>, + <0x10b0 0x10>; + reg-names = "nand", "nand-cache", "nand-intr-base"; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + clocks = <&periph_clk 20>; + clock-names = "nand"; + + #address-cells = <1>; + #size-cells = <0>; + + nand0: nandcs@0 { + compatible = "brcm,nandcs"; + reg = <0>; + nand-on-flash-bbt; + nand-ecc-strength = <1>; + nand-ecc-step-size = <512>; + }; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] mtd: brcmnand: Workaround false ECC uncorrectable errors
On 02/12/15 21:08, Jonas Gorski wrote: > On Wed, Dec 2, 2015 at 9:54 PM, Brian Norris > wrote: >> >> BTW, I think Kamal had code to handle protecting bitflips in erased >> pages code in the Broadcom STB Linux BSP. Perhaps he can port that to >> upstream with nand_check_erased_ecc_chunk()? IIUC, that would probably >> handle your case too, Simon, although it wouldn't be optimal for an >> all-0xff check (i.e., bitflip_threshold == 0). >> >> If that's really an issue (i.e., we have an implementation + data), I'm >> sure we could add optimization to nand_check_erased_ecc_chunk() to >> support the bitflip_threshold == 0 case. > > Maybe I'm missing something, but wasn't the point of introducing > nand_check_erased_ecc_chunk that bitflips in erased pages should be > treated as bitflips corrected by the ecc, and therefore fixed up > before passing the data further on? So having a theshold of 0 would be > wrong / no protection at all, and could be quite destructive on MLC > nand, where bitflips in erased pages are rather common. Without this patch I can't access erased pages at all. I don't know if the controller will still return an uncorrectable error if the page is erased but has 1 or more bit flips. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH (v2) 2/2] reset: bcm6345: Add support for the BCM6345 soft-reset controller
The BCM6345 contains a soft-reset controller activated by setting a bit (that must previously have cleared). Signed-off-by: Simon Arlott --- MAINTAINERS | 1 + drivers/reset/Kconfig | 1 + drivers/reset/Makefile| 17 +++--- drivers/reset/bcm/Kconfig | 10 drivers/reset/bcm/Makefile| 1 + drivers/reset/bcm/reset-bcm6345.c | 109 ++ 6 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 drivers/reset/bcm/Kconfig create mode 100644 drivers/reset/bcm/Makefile create mode 100644 drivers/reset/bcm/reset-bcm6345.c diff --git a/MAINTAINERS b/MAINTAINERS index 07613dd..a20cecf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2378,6 +2378,7 @@ F:drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: drivers/regulator/bcm63* +F: drivers/reset/bcm/reset-bcm6345* F: include/linux/bcm63xx_wdt.h BROADCOM TG3 GIGABIT ETHERNET DRIVER diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0615f50..ee73f5f 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -12,4 +12,5 @@ menuconfig RESET_CONTROLLER If unsure, say no. +source "drivers/reset/bcm/Kconfig" source "drivers/reset/sti/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 85d5904..a34f469 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -1,8 +1,9 @@ -obj-$(CONFIG_RESET_CONTROLLER) += core.o -obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o -obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o -obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o -obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o -obj-$(CONFIG_ARCH_STI) += sti/ -obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o -obj-$(CONFIG_ATH79) += reset-ath79.o +obj-$(CONFIG_RESET_CONTROLLER) += core.o +obj-$(CONFIG_ARCH_LPC18XX) += reset-lpc18xx.o +obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o +obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o +obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o +obj-$(CONFIG_ARCH_STI) += sti/ +obj-$(CONFIG_ARCH_ZYNQ)+= reset-zynq.o +obj-$(CONFIG_ATH79)+= reset-ath79.o +obj-y += bcm/ diff --git a/drivers/reset/bcm/Kconfig b/drivers/reset/bcm/Kconfig new file mode 100644 index 000..85931c9 --- /dev/null +++ b/drivers/reset/bcm/Kconfig @@ -0,0 +1,10 @@ +if RESET_CONTROLLER + +config RESET_BCM6345 + bool "BCM6345 Reset Controller" + depends on BMIPS_GENERIC + default BMIPS_GENERIC + help + Support resetting of devices on BCM6345 boards. + +endif diff --git a/drivers/reset/bcm/Makefile b/drivers/reset/bcm/Makefile new file mode 100644 index 000..3d004bd --- /dev/null +++ b/drivers/reset/bcm/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_RESET_BCM6345)+= reset-bcm6345.o diff --git a/drivers/reset/bcm/reset-bcm6345.c b/drivers/reset/bcm/reset-bcm6345.c new file mode 100644 index 000..a95433d --- /dev/null +++ b/drivers/reset/bcm/reset-bcm6345.c @@ -0,0 +1,109 @@ +/* + * Copyright 2015 Simon Arlott + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * Derived from reset-berlin.c: + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * Sebastian Hesselbarth + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_bcm6345_reset_priv(p) \ + container_of((p), struct bcm6345_reset_priv, rcdev) + +struct bcm6345_reset_priv { + struct regmap *map; + u32 offset; + struct reset_controller_dev rcdev; + struct mutex mutex; +}; + +static int bcm6345_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct bcm6345_reset_priv *priv = to_bcm6345_reset_priv(rcdev); + + mutex_lock(&priv->mutex); + regmap_write_bits(priv->map, priv->offset, BIT(id), 0); + usleep_range(1, 2); + regmap_write_bits(priv->map, priv->offset, BIT(id), BIT(id)); + usleep_range(1, 2); + mutex_unlock(&priv->mutex); + + return 0; +} + +static struct reset_control_ops bcm6345_reset_ops = { + .reset = bcm6345_reset_reset, +}; + +static int __init bcm6345_reset_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct bcm6345_reset_priv *priv; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->mutex); + + priv->map = syscon_regmap_lookup_by_phandle(np, "regmap"); + if (IS_ERR(priv->map)) + return PTR_ERR(
[PATCH (v2) 1/2] reset: Add brcm,bcm6345-reset device tree binding
Add device tree binding for the BCM6345 soft reset controller. The BCM6345 contains a soft-reset controller activated by setting a bit (that must previously have cleared). Signed-off-by: Simon Arlott --- Renamed to bcm6345, removed "mask" property. .../bindings/reset/brcm,bcm6345-reset.txt | 33 ++ 1 file changed, 33 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt b/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt new file mode 100644 index 000..bb9ca6e --- /dev/null +++ b/Documentation/devicetree/bindings/reset/brcm,bcm6345-reset.txt @@ -0,0 +1,33 @@ +Broadcom BCM6345 reset controller + +The BCM6345 contains a basic soft reset controller in the perf register +set which resets components using a bit in a register. + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "brcm,bcm-reset", "brcm,bcm6345-reset" +- regmap: The register map phandle +- offset: Offset in the register map for the reset register (in bytes) +- #reset-cells:Must be set to 1 + +Example: + +periph_soft_rst: reset-controller { + compatible = "brcm,bcm63168-reset", "brcm,bcm6345-reset"; + regmap = <&periph_cntl>; + offset = <0x10>; + + #reset-cells = <1>; +}; + +usbh: usbphy@10002700 { + compatible = "brcm,bcm63168-usbh"; + reg = <0x10002700 0x38>; + clocks = <&periph_clk 13>, <&timer_clk 18>; + resets = <&periph_soft_rst 6>; + power-supply = <&power_usbh>; + #phy-cells = <0>; +}; + -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/2] reset: bcm63xx: Add support for the BCM63xx soft-reset controller
On 02/12/15 18:03, Florian Fainelli wrote: > 2015-11-30 12:58 GMT-08:00 Simon Arlott : >> The BCM63xx contains a soft-reset controller activated by setting >> a bit (that must previously have cleared). >> >> Signed-off-by: Simon Arlott >> --- >> MAINTAINERS | 1 + >> drivers/reset/Kconfig | 9 +++ >> drivers/reset/Makefile| 1 + >> drivers/reset/reset-bcm63xx.c | 134 >> ++ >> 4 files changed, 145 insertions(+) >> create mode 100644 drivers/reset/reset-bcm63xx.c > > > Could you create a bcm directory and then add your reset-bcm63xx.c > file there? I have a pending submission for the BCM63138 reset > controller which is not at all using the same structure and will share > nothing with your driver. > Ok, I'll call it reset-bcm6345.c to avoid confusion. > >> +static int bcm63xx_reset_xlate(struct reset_controller_dev *rcdev, >> + const struct of_phandle_args *reset_spec) >> +{ >> + struct bcm63xx_reset_priv *priv = to_bcm63xx_reset_priv(rcdev); >> + >> + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) >> + return -EINVAL; >> + >> + if (reset_spec->args[0] >= rcdev->nr_resets) >> + return -EINVAL; > > Should not these two things be moved to the core reset controller code > based on the #reset-cells value? > This has already been removed from the next version of the patch. > >> + if (of_property_read_u32(np, "offset", &priv->offset)) >> + return -EINVAL; >> + >> + /* valid reset bits */ >> + if (of_property_read_u32(np, "mask", &priv->mask)) >> + priv->mask = 0x; >> + >> + priv->rcdev.owner = THIS_MODULE; >> + priv->rcdev.ops = &bcm63xx_reset_ops; >> + priv->rcdev.nr_resets = 32; > > Should not that come from Device Tree, or be computed based on the > mask property, like hweight_long() or something along these lines? The "mask" property has been removed. It will assume 32 resets and rely on the rest of the DT to only refer to valid bits. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH (v6) 1/2] mtd: brcmnand: Add brcm,bcm63268-nand device tree binding
On 02/12/15 20:21, Brian Norris wrote: > Hi Simon, > > On Wed, Dec 02, 2015 at 08:12:32PM +0000, Simon Arlott wrote: >> On 02/12/15 20:00, Brian Norris wrote: >> > On Wed, Dec 02, 2015 at 07:41:07PM +, Simon Arlott wrote: >> >> I've created a bcm963268part driver so there won't need to be any >> >> partitions in DT for bcm63268. >> > >> > Just curious, do you plan to submit this driver? We're working on >> >> Yes, it's just the most recent one I've been working on. I still have >> USBH and IUDMA to submit >> >> > matching up partition parsers to flash devices via device tree >> > of_match_table's, so you could do something like this: >> > >> >nand0: nandcs@0 { >> >compatible = "brcm,nandcs"; >> >... >> > >> >partitions { >> >compatible = "brcm,bcm963268-partitions"; >> >... >> >}; >> >}; >> >> I modified brcmnand to look for a machine matching "brcm,bcm963268", but > > Like this? > > http://patchwork.ozlabs.org/patch/473180/ > > I'd like to avoid that (hence the "Rejected" status). I exported default_mtd_part_types, copied it, and then added to it: + for (i = 0; i < nr_types; i++) + part_types[i] = default_mtd_part_types[i]; + + /* Add partition type based on machine */ + if (of_machine_is_compatible("brcm,bcm963268")) + part_types[i++] = "bcm963268part"; + else + part_types[i++] = NULL; + + part_types[i++] = NULL; >> that way is ok with me. Presumably "ofpart" defers to another matching >> partition parser? > > Yes, "ofpart" is for specifying the entire partition table in the device > tree as subnodes of either the flash node or of the flash's "partitions" > subnode. It's not the most flexible, but it does work generically. > >> Is there a patch for that method of parser detection available? > > I have something working here, but I haven't had time to finish cleaning > it up and submitting it. There's an older patch that works similarly, > though it has some deficiencies: > > http://patchwork.ozlabs.org/patch/475988/ > > The main difference between that and my (yet-to-be-submitted) proposal > is that I'd like parsers to opt in by adding a proper of_match_table > with non-Linux-specific DT bindings, and then we can drop the > "linux,..." naming and make it a reasonably generic property. I'll submit my parser without any means of using it, let me know if you want me to work on a patch for a match table. > Regards, > Brian > -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On 02/12/15 12:53, Mark Brown wrote: > On Wed, Dec 02, 2015 at 12:45:50PM -0000, Simon Arlott wrote: >> On Tue, December 1, 2015 22:16, Mark Brown wrote: > >> > Why are these in the DT, I would expect that if this is a driver for a >> > specific SoC all these properties would be known as a result of that. > >> This is a driver for multiple SoCs with the same regulator control in >> different places on different SoCs, so the location of it within the misc >> register needs to be provided in the DT: > >> BCM6362: >> #define MISC_BASE 0xb0001800 /* Miscellaneous Registers */ >> uint32 miscIddqCtrl; /* 0x48 */ > > This is the sort of thing you can pick up from the SoC compatible > strings. As things stand there is zero content in this driver that > relates to this SoC. There's always going to be very little content in the driver that relates to this SoC, given that a single bit flip enables/disables power. All other device tree drivers allow a register address to be specified for the device, how is an offset in the regmap any different? >> The mask is used as there's one bit per regulator in the register, but >> there's more than one way to express this in the DT: > > I wouldn't expect to see it in the device tree at all for a device > specific driver. If there isn't an individual entry in DT for each regulator, how is it supposed to work? There's no #regulator-cells property. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] mtd: brcmnand: Workaround false ECC uncorrectable errors
On 01/12/15 10:41, Jonas Gorski wrote: > On Sat, Nov 28, 2015 at 8:23 PM, Simon Arlott wrote: >> + >> + /* Go to start of buffer */ >> + buf -= FC_WORDS; >> + >> + /* Erased if all data bytes are 0xFF */ >> + buf_erased = memchr_inv(buf, 0xFF, FC_WORDS) == NULL; >> + >> + if (!buf_erased) >> + goto out_free; > > We now have a function exactly for that use case in 4.4, > nand_check_erased_buf [1], consider using that. This also has the > benefit of treating bit flips as correctable as long as the ECC scheme > is strong enough. I have no idea whether or not it's appropriate to specify bitflips_threshold > 0 so it'd just be a more complex way to do a memchr_inv() search for 0xFF. The code also has to check for the hamming code bytes being all 0x00, because according to the comments [2], the controller also has difficulty with the non-erased all-0xFFs scenario too. [2] https://github.com/lp0/bcm963xx_4.12L.06B_consumer/blob/dd8fcb13046f738c311507dc2fcfd3e5d57a88e0/kernel/linux/drivers/mtd/brcmnand/brcmnand_base.c#L2459 > > Jonas > > [1] > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/mtd/nand/nand_base.c#n1110 > -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH (v6) 1/2] mtd: brcmnand: Add brcm,bcm63268-nand device tree binding
On 02/12/15 20:00, Brian Norris wrote: > Hi, > > On Wed, Dec 02, 2015 at 07:41:07PM +0000, Simon Arlott wrote: >> >> + nand0: nandcs@0 { >> >> + compatible = "brcm,nandcs"; >> >> + >> >> + #address-cells = <0>; >> >> + #size-cells = <0>; > >> I think they're also implicit so you can just remove those two lines. > > From ePAPR: "The #address-cells and #size-cells properties are not > inherited from ancestors in the device tree. They shall be explicitly > defined." > > But we don't want to define them. I'd drop them, at least from the > example, as they're not relevant. Ok. >> I've created a bcm963268part driver so there won't need to be any >> partitions in DT for bcm63268. > > Just curious, do you plan to submit this driver? We're working on Yes, it's just the most recent one I've been working on. I still have USBH and IUDMA to submit > matching up partition parsers to flash devices via device tree > of_match_table's, so you could do something like this: > > nand0: nandcs@0 { > compatible = "brcm,nandcs"; > ... > > partitions { > compatible = "brcm,bcm963268-partitions"; > ... > }; > }; I modified brcmnand to look for a machine matching "brcm,bcm963268", but that way is ok with me. Presumably "ofpart" defers to another matching partition parser? Is there a patch for that method of parser detection available? -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH (v6) 1/2] mtd: brcmnand: Add brcm,bcm63268-nand device tree binding
On 02/12/15 19:38, Florian Fainelli wrote: > 2015-12-02 11:05 GMT-08:00 Brian Norris : >> + Broadcom list + Kamal >> >> On Tue, Nov 24, 2015 at 08:19:37PM -, Simon Arlott wrote: >>> Add device tree binding for NAND on the BCM63268. >>> >>> The BCM63268 has a NAND interrupt register with combined status and enable >>> registers. >>> >>> Signed-off-by: Simon Arlott >>> --- >>> .../devicetree/bindings/mtd/brcm,brcmnand.txt | 35 >>> ++ >>> 1 file changed, 35 insertions(+) >>> >>> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >>> b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >>> index 4ff7128..f2a71c8 100644 >>> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >>> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >>> @@ -72,6 +72,14 @@ we define additional 'compatible' properties and >>> associated register resources w >>> and enable registers >>> - reg-names: (required) "nand-int-base" >>> >>> + * "brcm,nand-bcm63268" >>> + - compatible: should contain "brcm,nand-bcm", >>> "brcm,nand-bcm63268" >> >> Looks like you're aiming to support bcm63168? Is bcm63268 the first >> chip to include this style of register then? The numbering seems >> backwards, but that may just be reality. > > 6362 (NAND rev 2.1, ann. Sep 8, 2009), 6368 (v0.1?!?, ann. Jan 7, > 2009) and 6328 (v2.1, can't find release date) are earlier chips that > have an identical combined interrupt enable + status register and a > NAND controller within the same 32-bits word, so these would qualify > as a better compatible string for this specific addition integration > stub here. I would gowith 6368 here then? > I could change it to 6368 but there's no documented NAND_INTR_BASE for it. Only the 63268 and 6818 have a #define for NAND_INTR_BASE. -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH (v7) 2/2] mtd: brcmnand: Add support for the BCM63268
On 02/12/15 19:18, Brian Norris wrote: > + Broadcom list + Kamal > > Hi Simon, > > On Wed, Nov 25, 2015 at 07:49:13PM +0000, Simon Arlott wrote: >> The BCM63268 has a NAND interrupt register with combined status and enable >> registers. It also has a clock for the NAND controller that needs to be >> enabled. >> >> Set up the device by enabling the clock, disabling and acking all >> interrupts, then handle the CTRL_READY interrupt. >> >> Add a brcmnand_get_socdata() function so that bcm63268_nand can obtain its >> data and disable the clock when the device is removed. >> >> Signed-off-by: Simon Arlott >> --- >> Added EXPORT_SYMBOL_GPL(brcmnand_get_socdata) >> >> (As the brcmnand module must be loaded first its compatible string will >> apply to any existing devices before the soc-specific module can be >> loaded.) > > What's this comment supposed to mean? The brcmnand module will not > directly probe any devices. It doesn't register any driver structs by > itself. I didn't notice that it didn't actually probe devices. In that case the documentation should not require "brcm,brcmnand" for soc-specific variants because the hardware's not really compatible with it. > (BTW given that, it probably doesn't need its MODULE_DEVICE_TABLE.) > >> drivers/mtd/nand/brcmnand/Makefile| 1 + >> drivers/mtd/nand/brcmnand/bcm63268_nand.c | 179 >> ++ >> drivers/mtd/nand/brcmnand/brcmnand.c | 8 ++ >> drivers/mtd/nand/brcmnand/brcmnand.h | 1 + >> 4 files changed, 189 insertions(+) >> create mode 100644 drivers/mtd/nand/brcmnand/bcm63268_nand.c >> >> diff --git a/drivers/mtd/nand/brcmnand/Makefile >> b/drivers/mtd/nand/brcmnand/Makefile >> index 3b1fbfd..b83a9ae 100644 >> --- a/drivers/mtd/nand/brcmnand/Makefile >> +++ b/drivers/mtd/nand/brcmnand/Makefile >> @@ -2,5 +2,6 @@ >> # more specific iproc_nand.o, for instance >> obj-$(CONFIG_MTD_NAND_BRCMNAND) += iproc_nand.o >> obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63138_nand.o >> +obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63268_nand.o >> obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o >> obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o >> diff --git a/drivers/mtd/nand/brcmnand/bcm63268_nand.c >> b/drivers/mtd/nand/brcmnand/bcm63268_nand.c >> new file mode 100644 >> index 000..70ad907 >> --- /dev/null >> +++ b/drivers/mtd/nand/brcmnand/bcm63268_nand.c >> @@ -0,0 +1,179 @@ >> +/* >> + * Copyright 2015 Simon Arlott >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * Derived from bcm63138_nand.c: >> + * Copyright © 2015 Broadcom Corporation >> + * >> + * Derived from >> bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: >> + * Copyright 2000-2010 Broadcom Corporation >> + * >> + * Derived from >> bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: >> + * Copyright 2000-2010 Broadcom Corporation >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "brcmnand.h" >> + >> +struct bcm63268_nand_soc { >> +struct brcmnand_soc soc; >> +void __iomem *base; >> +struct clk *clk; >> +}; >> + >> +#define BCM63268_NAND_INT 0x00 >> +#define BCM63268_NAND_STATUS_SHIFT 0 >> +#define BCM63268_NAND_STATUS_MASK (0xfff << BCM63268_NAND_STATUS_SHIFT) >> +#define BCM63268_NAND_ENABLE_SHIFT 16 >> +#define BCM63268_NAND_ENABLE_MASK (0x << BCM63268_NAND_ENABLE_SHIFT) >> +#define BCM63268_NAND_BASE_ADDR00x04 >> +#define BCM63268_NAND_BASE_ADDR10x0c >> + >> +enum { >> +BCM63268_NP_READ= BIT(0), >> +BCM63268_BLOCK_ERASE= BIT(1), >> +BCM63268_COPY_BACK = BIT(2), >> +BCM63268_PAGE_PGM = BIT(3), >> +BCM63268_CTRL_READY = BIT(4), >> +
Re: [PATCH (v6) 1/2] mtd: brcmnand: Add brcm,bcm63268-nand device tree binding
On 02/12/15 19:05, Brian Norris wrote: > + Broadcom list + Kamal > > On Tue, Nov 24, 2015 at 08:19:37PM -0000, Simon Arlott wrote: >> Add device tree binding for NAND on the BCM63268. >> >> The BCM63268 has a NAND interrupt register with combined status and enable >> registers. >> >> Signed-off-by: Simon Arlott >> --- >> .../devicetree/bindings/mtd/brcm,brcmnand.txt | 35 >> ++ >> 1 file changed, 35 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >> b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >> index 4ff7128..f2a71c8 100644 >> --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >> +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt >> @@ -72,6 +72,14 @@ we define additional 'compatible' properties and >> associated register resources w >> and enable registers >> - reg-names: (required) "nand-int-base" >> >> + * "brcm,nand-bcm63268" >> + - compatible: should contain "brcm,nand-bcm", "brcm,nand-bcm63268" > > Looks like you're aiming to support bcm63168? Is bcm63268 the first > chip to include this style of register then? The numbering seems > backwards, but that may just be reality. Yes, I have a BCM963168VX (BCM63168) but all the Broadcom code refers to this SoC as BCM63268. This is the only one with these registers in the source code of similar MIPS that I have. https://github.com/lp0/bcm963xx_4.12L.06B_consumer/blob/master/bcmdrivers/opensource/char/board/bcm963xx/impl1/board.c#L6595 int kerSysGetChipId() { ... /* Force BCM63168, BCM63169, and BCM63269 to be BCM63268) */ if( ( (r & 0xe) == 0x63168 ) || ( (r & 0xe) == 0x63268 )) r = 0x63268; >> + - reg: (required) the 'NAND_INTR_BASE' register range, with combined >> status >> + and enable registers, and boot address registers >> + - reg-names: (required) "nand-intr-base" >> + - clock: (required) reference to the clock for the NAND controller >> + - clock-names: (required) "nand" >> + >> * "brcm,nand-iproc" >> - reg: (required) the "IDM" register range, for interrupt enable and >> APB >> bus access endianness configuration, and the "EXT" register range, >> @@ -148,3 +156,30 @@ nand@f0442800 { >> }; >> }; >> }; >> + >> +nand@1200 { >> +compatible = "brcm,nand-bcm63168", "brcm,nand-bcm63268", >> +"brcm,brcmnand-v4.0", "brcm,brcmnand"; >> +reg = <0x1200 0x180>, >> + <0x1600 0x200>, >> + <0x10b0 0x10>; >> +reg-names = "nand", "nand-cache", "nand-intr-base"; >> +interrupt-parent = <&periph_intc>; >> +interrupts = <50>; >> +clocks = <&periph_clk 20>; >> +clock-names = "nand"; >> + >> +#address-cells = <1>; >> +#size-cells = <0>; >> + >> +nand0: nandcs@0 { >> +compatible = "brcm,nandcs"; >> +reg = <0>; >> +nand-on-flash-bbt; >> +nand-ecc-strength = <1>; >> +nand-ecc-step-size = <512>; >> + >> +#address-cells = <0>; >> +#size-cells = <0>; > > What are these {address,size}-cells for? If you need them for > partitioning, then those are wrong -- they shouldn't be zero. Maybe just > drop them? (I can cut them out when applying, if that's the only change > to make.) This is the correct way to do partitioning, there would be a "partitions" block with no address/size that contains the partitions as child nodes. [Documentation/devicetree/bindings/mtd/partition.txt] I think they're also implicit so you can just remove those two lines. I've created a bcm963268part driver so there won't need to be any partitions in DT for bcm63268. >> +}; >> +}; > > Brian > -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/2] regulator: Add brcm,bcm63xx-regulator device tree binding
On Tue, December 1, 2015 22:16, Mark Brown wrote: > On Mon, Nov 30, 2015 at 08:30:07PM +0000, Simon Arlott wrote: > >> +- offset: register offset >> +- mask: register enable mask >> +- startup-delay-us: startup time in microseconds > > Why are these in the DT, I would expect that if this is a driver for a > specific SoC all these properties would be known as a result of that. This is a driver for multiple SoCs with the same regulator control in different places on different SoCs, so the location of it within the misc register needs to be provided in the DT: BCM6362: #define MISC_BASE 0xb0001800 /* Miscellaneous Registers */ uint32 miscIddqCtrl; /* 0x48 */ BCM63268/BCM63168: #define MISC_BASE 0xb0001800 /* Miscellaneous Registers */ uint32 miscIddqCtrl; /* 0x4c */ I'll remove the startup-delay-us property and put a default in the driver. The mask is used as there's one bit per regulator in the register, but there's more than one way to express this in the DT: It currently looks like this: regulators { compatible = "simple-bus"; #address-cells = <0>; #size-cells = <0>; sar { compatible = "brcm,bcm63168-regulator", "brcm,bcm6345-regulator"; regulator-name = "sar_power"; regmap = <&misc>; offset = <0x4c>; mask = <0x1>; startup-delay-us = <10>; }; ipsec { compatible = "brcm,bcm63168-regulator", "brcm,bcm6345-regulator"; regulator-name = "ipsec_power"; regmap = <&misc>; offset = <0x4c>; mask = <0x2>; startup-delay-us = <10>; }; ... }; ubus { compatible = "brcm,ubus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; misc: syscon@10001800 { compatible = "syscon"; reg = <0x10001800 0xd0>; }; }; Would this be more appropriate? regulators { compatible = "simple-bus"; #address-cells = <0>; #size-cells = <0>; misc_iddq_ctrl { compatible = "brcm,bcm63168-regulator", "brcm,bcm6345-regulator"; regmap = <&misc>; offset = <0x4c>; #address-cells = <1>; #size-cells = <0>; sar@0 { regulator-name = "sar_power"; }; ipsec@1 { regulator-name = "ipsec_power"; }; ... }; }; ubus { compatible = "brcm,ubus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; misc: syscon@10001800 { compatible = "syscon"; reg = <0x10001800 0xd0>; }; }; -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 11/11] watchdog: bcm63xx_wdt: Use brcm,bcm6345-wdt device tree binding
Add of_match_table for "brcm,bcm6345-wdt". Use a NULL clock name when not on mach-bcm63xx so that the device tree clock name does not have to be "periph". Allow the watchdog to be selected on BMIPS_GENERIC and select the BCM6345 timer interrupt handler. Signed-off-by: Simon Arlott --- drivers/watchdog/Kconfig | 3 ++- drivers/watchdog/bcm63xx_wdt.c | 14 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 6815b74..0c50add 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1272,8 +1272,9 @@ config OCTEON_WDT config BCM63XX_WDT tristate "Broadcom BCM63xx hardware watchdog" - depends on BCM63XX + depends on BCM63XX || BMIPS_GENERIC select WATCHDOG_CORE + select BCM6345_L2_TIMER_IRQ if BMIPS_GENERIC help Watchdog driver for the built in watchdog hardware in Broadcom BCM63xx SoC. diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index fa6c28b..4db4145 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,11 @@ #define PFX KBUILD_MODNAME -#define WDT_CLK_NAME "periph" +#ifdef CONFIG_BCM63XX +# define WDT_CLK_NAME "periph" +#else +# define WDT_CLK_NAME NULL +#endif struct bcm63xx_wdt_hw { struct watchdog_device wdd; @@ -286,12 +291,19 @@ static void bcm63xx_wdt_shutdown(struct platform_device *pdev) bcm63xx_wdt_stop(&hw->wdd); } +static const struct of_device_id bcm63xx_wdt_dt_ids[] = { + { .compatible = "brcm,bcm6345-wdt" }, + {} +}; +MODULE_DEVICE_TABLE(of, bcm63xx_wdt_dt_ids); + static struct platform_driver bcm63xx_wdt_driver = { .probe = bcm63xx_wdt_probe, .remove = bcm63xx_wdt_remove, .shutdown = bcm63xx_wdt_shutdown, .driver = { .name = "bcm63xx-wdt", + .of_match_table = bcm63xx_wdt_dt_ids, } }; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 10/11] watchdog: bcm63xx_wdt: Use bcm63xx_timer interrupt directly
There is only one user of bcm63xx_timer and that is the watchdog. To allow the watchdog driver to be used on machine types other than mach-bcm63xx, it needs to use an interrupt instead of a custom register function. Modify bcm63xx_timer to only disable the timers (so that they don't interfere with the watchdog if an interrupt occurs) and remove its exported functions. Use the timer interrupt directly in bcm63xx_wdt. Signed-off-by: Simon Arlott --- arch/mips/bcm63xx/dev-wdt.c| 7 + arch/mips/bcm63xx/timer.c | 181 + arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h | 11 -- drivers/watchdog/bcm63xx_wdt.c | 41 +++-- 4 files changed, 36 insertions(+), 204 deletions(-) delete mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c index 2a2346a..a7a5497 100644 --- a/arch/mips/bcm63xx/dev-wdt.c +++ b/arch/mips/bcm63xx/dev-wdt.c @@ -17,6 +17,11 @@ static struct resource wdt_resources[] = { .end= -1, /* filled at runtime */ .flags = IORESOURCE_MEM, }, + { + .start = -1, /* filled at runtime */ + .end= -1, /* filled at runtime */ + .flags = IORESOURCE_IRQ, + }, }; static struct platform_device bcm63xx_wdt_device = { @@ -32,6 +37,8 @@ int __init bcm63xx_wdt_register(void) wdt_resources[0].end = wdt_resources[0].start; wdt_resources[0].end += RSET_WDT_SIZE - 1; + wdt_resources[1].start = bcm63xx_get_irq_number(IRQ_TIMER); + return platform_device_register(&bcm63xx_wdt_device); } arch_initcall(bcm63xx_wdt_register); diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c index 2110359..9c7b41a6 100644 --- a/arch/mips/bcm63xx/timer.c +++ b/arch/mips/bcm63xx/timer.c @@ -9,196 +9,23 @@ #include #include #include -#include -#include -#include #include #include -#include #include -static DEFINE_RAW_SPINLOCK(timer_reg_lock); -static DEFINE_RAW_SPINLOCK(timer_data_lock); -static struct clk *periph_clk; - -static struct timer_data { - void(*cb)(void *); - void*data; -} timer_data[BCM63XX_TIMER_COUNT]; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - u32 stat; - int i; - - raw_spin_lock(&timer_reg_lock); - stat = bcm_timer_readl(TIMER_IRQSTAT_REG); - bcm_timer_writel(stat, TIMER_IRQSTAT_REG); - raw_spin_unlock(&timer_reg_lock); - - for (i = 0; i < BCM63XX_TIMER_COUNT; i++) { - if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i))) - continue; - - raw_spin_lock(&timer_data_lock); - if (!timer_data[i].cb) { - raw_spin_unlock(&timer_data_lock); - continue; - } - - timer_data[i].cb(timer_data[i].data); - raw_spin_unlock(&timer_data_lock); - } - - return IRQ_HANDLED; -} - -int bcm63xx_timer_enable(int id) -{ - u32 reg; - unsigned long flags; - - if (id >= BCM63XX_TIMER_COUNT) - return -EINVAL; - - raw_spin_lock_irqsave(&timer_reg_lock, flags); - - reg = bcm_timer_readl(TIMER_CTLx_REG(id)); - reg |= TIMER_CTL_ENABLE_MASK; - bcm_timer_writel(reg, TIMER_CTLx_REG(id)); - - reg = bcm_timer_readl(TIMER_IRQSTAT_REG); - reg |= TIMER_IRQSTAT_TIMER_IR_EN(id); - bcm_timer_writel(reg, TIMER_IRQSTAT_REG); - - raw_spin_unlock_irqrestore(&timer_reg_lock, flags); - return 0; -} - -EXPORT_SYMBOL(bcm63xx_timer_enable); - -int bcm63xx_timer_disable(int id) +static int bcm63xx_timer_init(void) { u32 reg; - unsigned long flags; - - if (id >= BCM63XX_TIMER_COUNT) - return -EINVAL; - - raw_spin_lock_irqsave(&timer_reg_lock, flags); - - reg = bcm_timer_readl(TIMER_CTLx_REG(id)); - reg &= ~TIMER_CTL_ENABLE_MASK; - bcm_timer_writel(reg, TIMER_CTLx_REG(id)); - - reg = bcm_timer_readl(TIMER_IRQSTAT_REG); - reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id); - bcm_timer_writel(reg, TIMER_IRQSTAT_REG); - - raw_spin_unlock_irqrestore(&timer_reg_lock, flags); - return 0; -} - -EXPORT_SYMBOL(bcm63xx_timer_disable); - -int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data) -{ - unsigned long flags; - int ret; - - if (id >= BCM63XX_TIMER_COUNT || !callback) - return -EINVAL; - - ret = 0; - raw_spin_lock_irqsave(&timer_data_lock, flags); - if (timer_data[id].cb) { - ret = -EBUSY; - goto out; - } - - timer_data[id].cb = callback; - timer_data[id].data = data; - -out: - raw_spin_unlock_irq
[PATCH 09/11] watchdog: bcm63xx_wdt: Remove dependency on mach-bcm63xx functions/defines
The bcm_readl() and bcm_writel() functions are only defined for mach-bcm63xx, replace them with __raw_readl() and raw_writel(). The register defines required for the watchdog are in a mach-bcm63xx header file. Move them to include/linux/bcm63xx_wdt.h so that they are also available on other machine types. Signed-off-by: Simon Arlott --- MAINTAINERS | 1 + arch/mips/bcm63xx/prom.c | 1 + arch/mips/bcm63xx/setup.c | 1 + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 22 drivers/watchdog/bcm63xx_wdt.c| 25 +++ include/linux/bcm63xx_wdt.h | 22 6 files changed, 37 insertions(+), 35 deletions(-) create mode 100644 include/linux/bcm63xx_wdt.h diff --git a/MAINTAINERS b/MAINTAINERS index cd553a0..a381176 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2376,6 +2376,7 @@ F:arch/mips/boot/dts/brcm/bcm*.dts* F: drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* +F: include/linux/bcm63xx_wdt.h BROADCOM TG3 GIGABIT ETHERNET DRIVER M: Prashant Sreedharan diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c index 7019e29..d2800fb 100644 --- a/arch/mips/bcm63xx/prom.c +++ b/arch/mips/bcm63xx/prom.c @@ -6,6 +6,7 @@ * Copyright (C) 2008 Maxime Bizon */ +#include #include #include #include diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index 2be9caa..181402f 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -6,6 +6,7 @@ * Copyright (C) 2008 Maxime Bizon */ +#include #include #include #include diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index 5035f09..16a745b 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -441,28 +441,6 @@ /* - * _REG relative to RSET_WDT - */ - -/* Watchdog default count register */ -#define WDT_DEFVAL_REG 0x0 - -/* Watchdog control register */ -#define WDT_CTL_REG0x4 - -/* Watchdog control register constants */ -#define WDT_START_1(0xff00) -#define WDT_START_2(0x00ff) -#define WDT_STOP_1 (0xee00) -#define WDT_STOP_2 (0x00ee) - -/* Watchdog reset length register */ -#define WDT_RSTLEN_REG 0x8 - -/* Watchdog soft reset register (BCM6328 only) */ -#define WDT_SOFTRESET_REG 0xc - -/* * _REG relative to RSET_GPIO */ diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 2312dc2..f409523 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -13,6 +13,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -27,8 +28,6 @@ #include #include -#include -#include #include #include @@ -58,9 +57,9 @@ static int bcm63xx_wdt_start(struct watchdog_device *wdd) unsigned long flags; raw_spin_lock_irqsave(&hw->lock, flags); - bcm_writel(wdd->timeout * hw->clock_hz, hw->regs + WDT_DEFVAL_REG); - bcm_writel(WDT_START_1, hw->regs + WDT_CTL_REG); - bcm_writel(WDT_START_2, hw->regs + WDT_CTL_REG); + __raw_writel(wdd->timeout * hw->clock_hz, hw->regs + WDT_DEFVAL_REG); + __raw_writel(WDT_START_1, hw->regs + WDT_CTL_REG); + __raw_writel(WDT_START_2, hw->regs + WDT_CTL_REG); hw->running = true; raw_spin_unlock_irqrestore(&hw->lock, flags); return 0; @@ -72,8 +71,8 @@ static int bcm63xx_wdt_stop(struct watchdog_device *wdd) unsigned long flags; raw_spin_lock_irqsave(&hw->lock, flags); - bcm_writel(WDT_STOP_1, hw->regs + WDT_CTL_REG); - bcm_writel(WDT_STOP_2, hw->regs + WDT_CTL_REG); + __raw_writel(WDT_STOP_1, hw->regs + WDT_CTL_REG); + __raw_writel(WDT_STOP_2, hw->regs + WDT_CTL_REG); hw->running = false; raw_spin_unlock_irqrestore(&hw->lock, flags); return 0; @@ -108,10 +107,10 @@ static void bcm63xx_wdt_isr(void *data) raw_spin_lock_irqsave(&hw->lock, flags); if (!hw->running) { /* Stop the watchdog as it shouldn't be running */ - bcm_writel(WDT_STOP_1, hw->regs + WDT_CTL_REG); - bcm_writel(WDT_STOP_2, hw->regs + WDT_CTL_REG); + __raw_writel(WDT_STOP_1
[PATCH 08/11] watchdog: bcm63xx_wdt: Warn if the watchdog is currently running
Warn when the device is registered if the hardware watchdog is currently running and report the remaining time left. Signed-off-by: Simon Arlott --- drivers/watchdog/bcm63xx_wdt.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index ab4a794..2312dc2 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include #include #include @@ -159,6 +160,8 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) struct bcm63xx_wdt_hw *hw; struct watchdog_device *wdd; struct resource *r; + u32 timeleft1, timeleft2; + unsigned int timeleft; int ret; hw = devm_kzalloc(&pdev->dev, sizeof(*hw), GFP_KERNEL); @@ -199,7 +202,6 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) } raw_spin_lock_init(&hw->lock); - hw->running = false; wdd->parent = &pdev->dev; wdd->ops = &bcm63xx_wdt_ops; @@ -213,6 +215,23 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) watchdog_init_timeout(wdd, 0, &pdev->dev); watchdog_set_nowayout(wdd, nowayout); + /* Compare two reads of the time left value, 2 clock ticks apart */ + rmb(); + timeleft1 = __raw_readl(hw->regs + WDT_CTL_REG); + udelay(DIV_ROUND_UP(100, hw->clock_hz / 2)); + /* Ensure the register is read twice */ + rmb(); + timeleft2 = __raw_readl(hw->regs + WDT_CTL_REG); + + /* If the time left is changing, the watchdog is running */ + if (timeleft1 != timeleft2) { + hw->running = true; + timeleft = bcm63xx_wdt_get_timeleft(wdd); + } else { + hw->running = false; + timeleft = 0; + } + ret = watchdog_register_device(wdd); if (ret < 0) { dev_err(&pdev->dev, "failed to register watchdog device\n"); @@ -230,6 +249,8 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) dev_name(wdd->dev), hw->regs, wdd->timeout, wdd->max_timeout); + if (hw->running) + dev_alert(wdd->dev, "running, reboot in %us\n", timeleft); return 0; unregister_watchdog: -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 07/11] watchdog: bcm63xx_wdt: Add get_timeleft function
Return the remaining time from the hardware control register. Signed-off-by: Simon Arlott --- drivers/watchdog/bcm63xx_wdt.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 0a19731..ab4a794 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -78,6 +78,19 @@ static int bcm63xx_wdt_stop(struct watchdog_device *wdd) return 0; } +static unsigned int bcm63xx_wdt_get_timeleft(struct watchdog_device *wdd) +{ + struct bcm63xx_wdt_hw *hw = to_wdt_hw(wdd); + unsigned long flags; + u32 val; + + raw_spin_lock_irqsave(&hw->lock, flags); + val = __raw_readl(hw->regs + WDT_CTL_REG); + val /= hw->clock_hz; + raw_spin_unlock_irqrestore(&hw->lock, flags); + return val; +} + static int bcm63xx_wdt_set_timeout(struct watchdog_device *wdd, unsigned int timeout) { @@ -132,6 +145,7 @@ static struct watchdog_ops bcm63xx_wdt_ops = { .owner = THIS_MODULE, .start = bcm63xx_wdt_start, .stop = bcm63xx_wdt_stop, + .get_timeleft = bcm63xx_wdt_get_timeleft, .set_timeout = bcm63xx_wdt_set_timeout, }; @@ -256,6 +270,7 @@ module_platform_driver(bcm63xx_wdt_driver); MODULE_AUTHOR("Miguel Gaio "); MODULE_AUTHOR("Florian Fainelli "); +MODULE_AUTHOR("Simon Arlott"); MODULE_DESCRIPTION("Driver for the Broadcom BCM63xx SoC watchdog"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:bcm63xx-wdt"); -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 06/11] watchdog: bcm63xx_wdt: Obtain watchdog clock HZ from "periph" clk
Instead of using a fixed clock HZ in the driver, obtain it from the "periph" clk that the watchdog timer uses. Signed-off-by: Simon Arlott Reviewed-by: Florian Fainelli --- drivers/watchdog/bcm63xx_wdt.c | 36 +++- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 2257924..0a19731 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -13,6 +13,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -32,12 +33,14 @@ #define PFX KBUILD_MODNAME -#define WDT_HZ 5000/* Fclk */ +#define WDT_CLK_NAME "periph" struct bcm63xx_wdt_hw { struct watchdog_device wdd; raw_spinlock_t lock; void __iomem *regs; + struct clk *clk; + unsigned long clock_hz; bool running; }; @@ -54,7 +57,7 @@ static int bcm63xx_wdt_start(struct watchdog_device *wdd) unsigned long flags; raw_spin_lock_irqsave(&hw->lock, flags); - bcm_writel(wdd->timeout * WDT_HZ, hw->regs + WDT_DEFVAL_REG); + bcm_writel(wdd->timeout * hw->clock_hz, hw->regs + WDT_DEFVAL_REG); bcm_writel(WDT_START_1, hw->regs + WDT_CTL_REG); bcm_writel(WDT_START_2, hw->regs + WDT_CTL_REG); hw->running = true; @@ -118,7 +121,7 @@ static void bcm63xx_wdt_isr(void *data) die(PFX ": watchdog timer expired\n", get_irq_regs()); } - ms = timeleft / (WDT_HZ / 1000); + ms = timeleft / (hw->clock_hz / 1000); dev_alert(hw->wdd.dev, "warning timer fired, reboot in %ums\n", ms); } @@ -162,6 +165,25 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) return -ENXIO; } + hw->clk = devm_clk_get(&pdev->dev, WDT_CLK_NAME); + if (IS_ERR(hw->clk)) { + if (PTR_ERR(hw->clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "unable to request clock\n"); + return PTR_ERR(hw->clk); + } + + hw->clock_hz = clk_get_rate(hw->clk); + if (!hw->clock_hz) { + dev_err(&pdev->dev, "unable to fetch clock rate\n"); + return -EINVAL; + } + + ret = clk_prepare_enable(hw->clk); + if (ret) { + dev_err(&pdev->dev, "unable to enable clock\n"); + return ret; + } + raw_spin_lock_init(&hw->lock); hw->running = false; @@ -169,7 +191,7 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) wdd->ops = &bcm63xx_wdt_ops; wdd->info = &bcm63xx_wdt_info; wdd->min_timeout = 1; - wdd->max_timeout = 0x / WDT_HZ; + wdd->max_timeout = 0x / hw->clock_hz; wdd->timeout = min(30U, wdd->max_timeout); platform_set_drvdata(pdev, hw); @@ -180,7 +202,7 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) ret = watchdog_register_device(wdd); if (ret < 0) { dev_err(&pdev->dev, "failed to register watchdog device\n"); - return ret; + goto disable_clk; } ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, hw); @@ -198,6 +220,9 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev) unregister_watchdog: watchdog_unregister_device(wdd); + +disable_clk: + clk_disable_unprepare(hw->clk); return ret; } @@ -207,6 +232,7 @@ static int bcm63xx_wdt_remove(struct platform_device *pdev) bcm63xx_timer_unregister(TIMER_WDT_ID); watchdog_unregister_device(&hw->wdd); + clk_disable_unprepare(hw->clk); return 0; } -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/11] watchdog: bcm63xx_wdt: Use WATCHDOG_CORE
Convert bcm63xx_wdt to use WATCHDOG_CORE. The default and maximum time constants that are only used once have been moved to the initialisation of the struct watchdog_device. Signed-off-by: Simon Arlott --- drivers/watchdog/Kconfig | 1 + drivers/watchdog/bcm63xx_wdt.c | 259 + 2 files changed, 79 insertions(+), 181 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 7a8a6c6..6815b74 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1273,6 +1273,7 @@ config OCTEON_WDT config BCM63XX_WDT tristate "Broadcom BCM63xx hardware watchdog" depends on BCM63XX + select WATCHDOG_CORE help Watchdog driver for the built in watchdog hardware in Broadcom BCM63xx SoC. diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index 3f55cba..2257924 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -13,20 +13,15 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include #include -#include #include #include -#include #include #include #include #include -#include #include #include -#include #include #include @@ -38,53 +33,59 @@ #define PFX KBUILD_MODNAME #define WDT_HZ 5000/* Fclk */ -#define WDT_DEFAULT_TIME 30 /* seconds */ -#define WDT_MAX_TIME (0x / WDT_HZ) /* seconds */ struct bcm63xx_wdt_hw { + struct watchdog_device wdd; raw_spinlock_t lock; void __iomem *regs; - unsigned long inuse; bool running; }; -static struct bcm63xx_wdt_hw bcm63xx_wdt_device; -static int expect_close; +#define to_wdt_hw(x) container_of(x, struct bcm63xx_wdt_hw, wdd) -static int wdt_time = WDT_DEFAULT_TIME; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -/* HW functions */ -static void bcm63xx_wdt_hw_start(void) +static int bcm63xx_wdt_start(struct watchdog_device *wdd) { + struct bcm63xx_wdt_hw *hw = to_wdt_hw(wdd); unsigned long flags; - raw_spin_lock_irqsave(&bcm63xx_wdt_device.lock, flags); - bcm_writel(wdt_time * WDT_HZ, bcm63xx_wdt_device.regs + WDT_DEFVAL_REG); - bcm_writel(WDT_START_1, bcm63xx_wdt_device.regs + WDT_CTL_REG); - bcm_writel(WDT_START_2, bcm63xx_wdt_device.regs + WDT_CTL_REG); - bcm63xx_wdt_device.running = true; - raw_spin_unlock_irqrestore(&bcm63xx_wdt_device.lock, flags); + raw_spin_lock_irqsave(&hw->lock, flags); + bcm_writel(wdd->timeout * WDT_HZ, hw->regs + WDT_DEFVAL_REG); + bcm_writel(WDT_START_1, hw->regs + WDT_CTL_REG); + bcm_writel(WDT_START_2, hw->regs + WDT_CTL_REG); + hw->running = true; + raw_spin_unlock_irqrestore(&hw->lock, flags); + return 0; } -static void bcm63xx_wdt_hw_stop(void) +static int bcm63xx_wdt_stop(struct watchdog_device *wdd) { + struct bcm63xx_wdt_hw *hw = to_wdt_hw(wdd); unsigned long flags; - raw_spin_lock_irqsave(&bcm63xx_wdt_device.lock, flags); - bcm_writel(WDT_STOP_1, bcm63xx_wdt_device.regs + WDT_CTL_REG); - bcm_writel(WDT_STOP_2, bcm63xx_wdt_device.regs + WDT_CTL_REG); - bcm63xx_wdt_device.running = false; - raw_spin_unlock_irqrestore(&bcm63xx_wdt_device.lock, flags); + raw_spin_lock_irqsave(&hw->lock, flags); + bcm_writel(WDT_STOP_1, hw->regs + WDT_CTL_REG); + bcm_writel(WDT_STOP_2, hw->regs + WDT_CTL_REG); + hw->running = false; + raw_spin_unlock_irqrestore(&hw->lock, flags); + return 0; +} + +static int bcm63xx_wdt_set_timeout(struct watchdog_device *wdd, + unsigned int timeout) +{ + wdd->timeout = timeout; + return 0; } /* The watchdog interrupt occurs when half the timeout is remaining */ static void bcm63xx_wdt_isr(void *data) { - struct bcm63xx_wdt_hw *hw = &bcm63xx_wdt_device; + struct bcm63xx_wdt_hw *hw = data; unsigned long flags; raw_spin_lock_irqsave(&hw->lock, flags); @@ -118,147 +119,36 @@ static void bcm63xx_wdt_isr(void *data) } ms = timeleft / (WDT_HZ / 1000); - pr_alert("warning timer fired, reboot in %ums\n", ms); + dev_alert(hw->wdd.dev, + "warning timer fired, reboot in %ums\n", ms); } raw_spin_unlock_irqrestore(&hw->lock, flags); } -static int bcm63xx_wdt_settimeout(int new_time) -{ - if ((new_time <= 0) || (new_time > WDT_MAX_TIME)) - return -EINVAL; - - wdt_time = new_time; - - return 0; -} - -st
[PATCH 04/11] watchdog: bcm63xx_wdt: Handle hardware interrupt and remove software timer
There is a level triggered interrupt for the watchdog timer as part of the bcm63xx_timer device. The interrupt occurs when the hardware watchdog timer reaches 50% of the remaining time. It is not possible to mask the interrupt within the bcm63xx_timer device. To get around this limitation, handle the interrupt by restarting the watchdog with the current remaining time (which will be half the previous timeout) so that the interrupt occurs again at 1/4th, 1/8th, etc. of the original timeout value until the watchdog forces a reboot. The software timer was restarting the hardware watchdog with a 85 second timeout until the software timer expired, and then causing a panic() about 42.5 seconds later when the hardware interrupt occurred. The hardware watchdog would not reboot until a further 42.5 seconds had passed. Remove the software timer and rely on the hardware timer directly, reducing the maximum timeout from 256 seconds to 85 seconds (2^32 / WDT_HZ). Signed-off-by: Simon Arlott --- drivers/watchdog/bcm63xx_wdt.c | 125 - 1 file changed, 73 insertions(+), 52 deletions(-) diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c index ab26fd9..3f55cba 100644 --- a/drivers/watchdog/bcm63xx_wdt.c +++ b/drivers/watchdog/bcm63xx_wdt.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007, Miguel Gaio * Copyright (C) 2008, Florian Fainelli + * Copyright 2015 Simon Arlott * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,11 +21,10 @@ #include #include #include +#include #include #include #include -#include -#include #include #include #include @@ -37,16 +37,17 @@ #define PFX KBUILD_MODNAME -#define WDT_HZ 5000 /* Fclk */ -#define WDT_DEFAULT_TIME 30 /* seconds */ -#define WDT_MAX_TIME 256 /* seconds */ +#define WDT_HZ 5000/* Fclk */ +#define WDT_DEFAULT_TIME 30 /* seconds */ +#define WDT_MAX_TIME (0x / WDT_HZ) /* seconds */ -static struct { +struct bcm63xx_wdt_hw { + raw_spinlock_t lock; void __iomem *regs; - struct timer_list timer; unsigned long inuse; - atomic_t ticks; -} bcm63xx_wdt_device; + bool running; +}; +static struct bcm63xx_wdt_hw bcm63xx_wdt_device; static int expect_close; @@ -59,48 +60,67 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" /* HW functions */ static void bcm63xx_wdt_hw_start(void) { - bcm_writel(0xfffe, bcm63xx_wdt_device.regs + WDT_DEFVAL_REG); + unsigned long flags; + + raw_spin_lock_irqsave(&bcm63xx_wdt_device.lock, flags); + bcm_writel(wdt_time * WDT_HZ, bcm63xx_wdt_device.regs + WDT_DEFVAL_REG); bcm_writel(WDT_START_1, bcm63xx_wdt_device.regs + WDT_CTL_REG); bcm_writel(WDT_START_2, bcm63xx_wdt_device.regs + WDT_CTL_REG); + bcm63xx_wdt_device.running = true; + raw_spin_unlock_irqrestore(&bcm63xx_wdt_device.lock, flags); } static void bcm63xx_wdt_hw_stop(void) { + unsigned long flags; + + raw_spin_lock_irqsave(&bcm63xx_wdt_device.lock, flags); bcm_writel(WDT_STOP_1, bcm63xx_wdt_device.regs + WDT_CTL_REG); bcm_writel(WDT_STOP_2, bcm63xx_wdt_device.regs + WDT_CTL_REG); + bcm63xx_wdt_device.running = false; + raw_spin_unlock_irqrestore(&bcm63xx_wdt_device.lock, flags); } +/* The watchdog interrupt occurs when half the timeout is remaining */ static void bcm63xx_wdt_isr(void *data) { - struct pt_regs *regs = get_irq_regs(); - - die(PFX " fire", regs); -} - -static void bcm63xx_timer_tick(unsigned long unused) -{ - if (!atomic_dec_and_test(&bcm63xx_wdt_device.ticks)) { - bcm63xx_wdt_hw_start(); - mod_timer(&bcm63xx_wdt_device.timer, jiffies + HZ); - } else - pr_crit("watchdog will restart system\n"); -} - -static void bcm63xx_wdt_pet(void) -{ - atomic_set(&bcm63xx_wdt_device.ticks, wdt_time); -} - -static void bcm63xx_wdt_start(void) -{ - bcm63xx_wdt_pet(); - bcm63xx_timer_tick(0); -} + struct bcm63xx_wdt_hw *hw = &bcm63xx_wdt_device; + unsigned long flags; + + raw_spin_lock_irqsave(&hw->lock, flags); + if (!hw->running) { + /* Stop the watchdog as it shouldn't be running */ + bcm_writel(WDT_STOP_1, hw->regs + WDT_CTL_REG); + bcm_writel(WDT_STOP_2, hw->regs + WDT_CTL_REG); + } else { + u32 timeleft = bcm_readl(hw->regs + WDT_CTL_REG); + u32 ms; + + if (timeleft >= 2) { + /* The only way to clear this level triggered interrupt +* without disrupting the normal running of the
[PATCH 03/11] watchdog: Add brcm,bcm6345-wdt device tree binding
Add device tree binding for the BCM6345 watchdog. This uses the BCM6345 timer for its warning interrupt. Signed-off-by: Simon Arlott Acked-by: Rob Herring --- .../bindings/watchdog/brcm,bcm6345-wdt.txt | 35 ++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/watchdog/brcm,bcm6345-wdt.txt diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm6345-wdt.txt b/Documentation/devicetree/bindings/watchdog/brcm,bcm6345-wdt.txt new file mode 100644 index 000..9d852d4 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm6345-wdt.txt @@ -0,0 +1,35 @@ +BCM6345 Watchdog timer + +Required properties: + +- compatible: should be "brcm,bcm63-wdt", "brcm,bcm6345-wdt" +- reg: Specifies base physical address and size of the registers. +- clocks: Specify the clock used for timing + +Optional properties: + +- interrupt-parent: phandle to the interrupt controller +- interrupts: Specify the interrupt used for the watchdog timout warning +- timeout-sec: Contains the default watchdog timeout in seconds + +Example: + +watchdog { + compatible = "brcm,bcm63168-wdt", "brcm,bcm6345-wdt"; + reg = <0x109c 0x0c>; + clocks = <&periph_clk>; + + interrupt-parent = <&timer>; + interrupts = <3>; + timeout-sec = <30>; +}; + +watchdog { + compatible = "brcm,bcm6318-wdt", "brcm,bcm6345-wdt"; + reg = <0x1068 0x0c>; + clocks = <&periph_clk>; + + interrupt-parent = <&timer>; + interrupts = <3>; + timeout-sec = <30>; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 02/11] MIPS: bmips: Add bcm6345-l2-timer interrupt controller
Add the BCM6345/BCM6318 timer as an interrupt controller so that it can be used by the watchdog to warn that its timer will expire soon. Support for clocksource/clockevents is not implemented as the timer interrupt is not per CPU (except on the BCM6318) and the MIPS clock is better. This could be added later if required without changing the device tree binding. Signed-off-by: Simon Arlott --- drivers/irqchip/Kconfig| 5 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-bcm6345-l2-timer.c | 386 + 3 files changed, 392 insertions(+) create mode 100644 drivers/irqchip/irq-bcm6345-l2-timer.c diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index d307bb3..21c3d9b 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -70,6 +70,11 @@ config BCM6345_L1_IRQ select GENERIC_IRQ_CHIP select IRQ_DOMAIN +config BCM6345_L2_TIMER_IRQ + bool + select GENERIC_IRQ_CHIP + select IRQ_DOMAIN + config BCM7038_L1_IRQ bool select GENERIC_IRQ_CHIP diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index ded59cf..2687dea 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_SOC_VF610)+= irq-vf610-mscm-ir.o obj-$(CONFIG_BCM6345_L1_IRQ) += irq-bcm6345-l1.o +obj-$(CONFIG_BCM6345_L2_TIMER_IRQ) += irq-bcm6345-l2-timer.o obj-$(CONFIG_BCM7038_L1_IRQ) += irq-bcm7038-l1.o obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o diff --git a/drivers/irqchip/irq-bcm6345-l2-timer.c b/drivers/irqchip/irq-bcm6345-l2-timer.c new file mode 100644 index 000..f3acda7 --- /dev/null +++ b/drivers/irqchip/irq-bcm6345-l2-timer.c @@ -0,0 +1,386 @@ +/* + * Copyright 2015 Simon Arlott + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Based on arch/mips/bcm63xx/timer.c: + * Copyright (C) 2008 Maxime Bizon + * + * Registers for SoCs with 4 timers: BCM6345, BCM6328, BCM6362, BCM6816, + * BCM68220,BCM63168, BCM63268 + * 0x02: Interrupt enable (u8) + * 0x03: Interrupt status (u8) + * 0x04: Timer 0 control + * 0x08: Timer 1 control + * 0x0c: Timer 2 control + * 0x10: Timer 0 count + * 0x14: Timer 1 count + * 0x18: Timer 2 count + * 0x1c+: Watchdog registers + * + * Registers for SoCs with 5 timers: BCM6318 + * 0x00: Interrupt enable (u32) + * 0x04: Interrupt status (u32) + * 0x08: Timer 0 control + * 0x0c: Timer 1 control + * 0x10: Timer 2 control + * 0x14: Timer 3 control + * 0x18: Timer 0 count + * 0x1c: Timer 1 count + * 0x20: Timer 2 count + * 0x24: Timer 3 count + * 0x28+: Watchdog registers + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum timer_regs { + /* Interrupt enable register: +* 1 bit per timer (without the watchdog) +*/ + TIMER_INT_ENABLE = 0, + + /* Interrupt status register: +* 1 bit per timer (plus the watchdog) +* Read for status +* Write bit to ack +*/ + TIMER_INT_STATUS, + + /* Per-timer control register */ + TIMER_CONTROL, + + /* Per-timer count register */ + TIMER_COUNT, + + + /* Number of registers in enum */ + __TIMER_REGS_ENUM_SIZE +}; + +/* Watchdog interrupt is immediately after the timers */ +#define WATCHDOG_INT_BIT(x)(BIT((x)->variant.nr_timers)) + +#define CONTROL_COUNTDOWN_MASK (0x3fff) +#define CONTROL_RSTCNTCLR_MASK (1 << 30) +#define CONTROL_ENABLE_MASK(1 << 31) + +#define COUNT_MASK (0x3fff) + +struct bcm6345_timer *timer; + +struct bcm6345_timer_variant { + unsigned int nr_timers; + u32 (*int_read)(struct bcm6345_timer *timer, int reg); + void (*int_write)(struct bcm6345_timer *timer, int reg, u32 val); + long regs[__TIMER_REGS_ENUM_SIZE]; +}; + +struct bcm6345_timer { + raw_spinlock_t lock; + void __iomem *base; + unsigned int irq; + struct irq_domain *domain; + + struct bcm6345_timer_variant variant; + u
[PATCH 01/11] clocksource: Add brcm,bcm6345-timer/brcm,bcm6318-timer device tree binding
Add device tree bindings for the BCM6345/BCM6318 timers. This is required for the BCM6345 watchdog which needs to respond to one of the timer interrupts. Signed-off-by: Simon Arlott Acked-by: Rob Herring --- .../bindings/timer/brcm,bcm6318-timer.txt | 44 .../bindings/timer/brcm,bcm6345-timer.txt | 47 ++ 2 files changed, 91 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/brcm,bcm6318-timer.txt create mode 100644 Documentation/devicetree/bindings/timer/brcm,bcm6345-timer.txt diff --git a/Documentation/devicetree/bindings/timer/brcm,bcm6318-timer.txt b/Documentation/devicetree/bindings/timer/brcm,bcm6318-timer.txt new file mode 100644 index 000..cf4be7e --- /dev/null +++ b/Documentation/devicetree/bindings/timer/brcm,bcm6318-timer.txt @@ -0,0 +1,44 @@ +Broadcom BCM6318 Timer + +This block is a timer that is connected to multiple interrupts on the main +interrupt controller and functions as a programmable interrupt controller for +timer events. There is a main timer interrupt for all timers. + +- 4 independent timers with their own interrupt, and own maskable level + interrupt bit in the main timer interrupt + +- 1 watchdog timer with an unmaskable level interrupt bit in the main timer + interrupt + +- Contains one enable/status word pair + +- No atomic set/clear operations + +Required properties: + +- compatible: should be "brcm,bcm-timer", "brcm,bcm6318-timer" +- reg: specifies the base physical address and size of the registers, excluding + the watchdog registers +- interrupt-controller: identifies the node as an interrupt controller +- #interrupt-cells: specifies the number of cells needed to encode an interrupt + source, should be 1. +- interrupt-parent: specifies the phandle to the parent interrupt controller(s) + this one is cascaded from +- interrupts: specifies the interrupt line(s) in the interrupt-parent controller + node for the main timer interrupt, followed by the individual timer + interrupts; valid values depend on the type of parent interrupt controller +- clocks: phandle of timer reference clock (periph) + +Example: + +timer: timer@1040 { + compatible = "brcm,bcm63148-timer", "brcm,bcm6318-timer"; + reg = <0x1040 0x28>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = <31>, <0>, <1>, <2>, <3>; + clock = <&periph_osc>; +}; diff --git a/Documentation/devicetree/bindings/timer/brcm,bcm6345-timer.txt b/Documentation/devicetree/bindings/timer/brcm,bcm6345-timer.txt new file mode 100644 index 000..03250dd --- /dev/null +++ b/Documentation/devicetree/bindings/timer/brcm,bcm6345-timer.txt @@ -0,0 +1,47 @@ +Broadcom BCM6345 Timer + +This block is a timer that is connected to one interrupt on the main interrupt +controller and functions as a programmable interrupt controller for timer +events. + +- 3 independent timers with their own maskable level interrupt bit (but not + per CPU because there is only one parent interrupt and the timers share it) + +- 1 watchdog timer with an unmaskable level interrupt + +- Contains one enable/status word pair + +- No atomic set/clear operations + +The lack of per CPU ability of timers makes them unusable as a set of +clockevent devices, otherwise they could be attached to the remaining +interrupts. + +Required properties: + +- compatible: should be "brcm,bcm-timer", "brcm,bcm6345-timer" +- reg: specifies the base physical address and size of the registers, excluding + the watchdog registers +- interrupt-controller: identifies the node as an interrupt controller +- #interrupt-cells: specifies the number of cells needed to encode an interrupt + source, should be 1. +- interrupt-parent: specifies the phandle to the parent interrupt controller(s) + this one is cascaded from +- interrupts: specifies the interrupt line(s) in the interrupt-parent controller + node for the timer interrupt; valid values depend on the type of parent + interrupt controller +- clocks: phandle of timer reference clock (periph) + +Example: + +timer: timer@1080 { + compatible = "brcm,bcm63168-timer", "brcm,bcm6345-timer"; + reg = <0x1080 0x1c>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&periph_intc>; + interrupts = <0>; + clock·=·<&periph_osc>; +}; -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] reset: bcm63xx: Add support for the BCM63xx soft-reset controller
The BCM63xx contains a soft-reset controller activated by setting a bit (that must previously have cleared). Signed-off-by: Simon Arlott --- MAINTAINERS | 1 + drivers/reset/Kconfig | 9 +++ drivers/reset/Makefile| 1 + drivers/reset/reset-bcm63xx.c | 134 ++ 4 files changed, 145 insertions(+) create mode 100644 drivers/reset/reset-bcm63xx.c diff --git a/MAINTAINERS b/MAINTAINERS index 07613dd..55e493a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2378,6 +2378,7 @@ F:drivers/irqchip/irq-bcm63* F: drivers/irqchip/irq-bcm7* F: drivers/irqchip/irq-brcmstb* F: drivers/regulator/bcm63* +F: drivers/reset/reset-bcm63* F: include/linux/bcm63xx_wdt.h BROADCOM TG3 GIGABIT ETHERNET DRIVER diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 0615f50..064dad2 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -12,4 +12,13 @@ menuconfig RESET_CONTROLLER If unsure, say no. +if RESET_CONTROLLER + +config RESET_BCM63XX + bool "BCM63xx Reset Controller" + help + Support resetting of devices on BCM63xx boards. + +endif + source "drivers/reset/sti/Kconfig" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 85d5904..f6e2171 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o obj-$(CONFIG_ARCH_STI) += sti/ obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o obj-$(CONFIG_ATH79) += reset-ath79.o +obj-$(CONFIG_RESET_BCM63XX) += reset-bcm63xx.o diff --git a/drivers/reset/reset-bcm63xx.c b/drivers/reset/reset-bcm63xx.c new file mode 100644 index 000..46db57f --- /dev/null +++ b/drivers/reset/reset-bcm63xx.c @@ -0,0 +1,134 @@ +/* + * Copyright 2015 Simon Arlott + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * Derived from reset-berlin.c: + * Copyright (C) 2014 Marvell Technology Group Ltd. + * + * Antoine Tenart + * Sebastian Hesselbarth + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define to_bcm63xx_reset_priv(p) \ + container_of((p), struct bcm63xx_reset_priv, rcdev) + +struct bcm63xx_reset_priv { + struct regmap *map; + u32 offset; + u32 mask; /* valid reset bits */ + struct reset_controller_dev rcdev; + struct mutex mutex; +}; + +static int bcm63xx_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct bcm63xx_reset_priv *priv = to_bcm63xx_reset_priv(rcdev); + + mutex_lock(&priv->mutex); + regmap_write_bits(priv->map, priv->offset, BIT(id), 0); + usleep_range(1, 2); + regmap_write_bits(priv->map, priv->offset, BIT(id), BIT(id)); + usleep_range(1, 2); + mutex_unlock(&priv->mutex); + + return 0; +} + +static int bcm63xx_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + struct bcm63xx_reset_priv *priv = to_bcm63xx_reset_priv(rcdev); + + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) + return -EINVAL; + + if (reset_spec->args[0] >= rcdev->nr_resets) + return -EINVAL; + + if (!(BIT(reset_spec->args[0]) & priv->mask)) + return -EINVAL; + + return reset_spec->args[0]; +} + + +static struct reset_control_ops bcm63xx_reset_ops = { + .reset = bcm63xx_reset_reset, +}; + +static int __init bcm63xx_reset_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct bcm63xx_reset_priv *priv; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + mutex_init(&priv->mutex); + + priv->map = syscon_regmap_lookup_by_phandle(np, "regmap"); + if (IS_ERR(priv->map)) + return PTR_ERR(priv->map); + + if (of_property_read_u32(np, "offset", &priv->offset)) + return -EINVAL; + + /* valid reset bits */ + if (of_property_read_u32(np, "mask", &priv->mask)) + priv->mask = 0x; + + priv->rcdev.owner = THIS_MODULE; + priv->rcdev.ops = &bcm63xx_reset_ops; + priv->rcdev.nr_resets = 32; + priv->rcdev.of_node = pdev->dev.of_node; + priv->rcdev.of_reset_n_cells = 1; + priv->rcdev.of_xlate = bcm63xx_reset_xlate; + + ret = reset_controller_register(&priv->rcdev); + if (ret) { + dev_err(&pdev->dev, +
[PATCH 1/2] reset: Add brcm,bcm63xx-reset device tree binding
Add device tree binding for the BCM63xx soft reset controller. The BCM63xx contains a soft-reset controller activated by setting a bit (that must previously have cleared). Signed-off-by: Simon Arlott --- .../bindings/reset/brcm,bcm63xx-reset.txt | 37 ++ 1 file changed, 37 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/brcm,bcm63xx-reset.txt diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm63xx-reset.txt b/Documentation/devicetree/bindings/reset/brcm,bcm63xx-reset.txt new file mode 100644 index 000..48e9daf --- /dev/null +++ b/Documentation/devicetree/bindings/reset/brcm,bcm63xx-reset.txt @@ -0,0 +1,37 @@ +BCM63xx reset controller + +The BCM63xx contains a basic soft reset controller in the perf register +set which resets components using a bit in a register. + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "brcm,bcm-reset", "brcm,bcm63xx-reset" +- regmap: The register map phandle +- offset: Offset in the register map for the reset register (in bytes) +- #reset-cells:Must be set to 1 + +Optional properties: +- mask:Mask of valid reset bits in the reset register (32 bit access) + (Defaults to all bits) + +Example: + +periph_soft_rst: reset-controller { + compatible = "brcm,bcm63168-reset", "brcm,bcm63xx-reset"; + regmap = <&periph_cntl>; + offset = <0x10>; + + #reset-cells = <1>; +}; + +usbh: usbphy@10002700 { + compatible = "brcm,bcm63168-usbh"; + reg = <0x10002700 0x38>; + clocks = <&periph_clk 13>, <&timer_clk 18>; + resets = <&periph_soft_rst 6>; + power-supply = <&power_usbh>; + #phy-cells = <0>; +}; + -- 2.1.4 -- Simon Arlott -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/